diff --git a/backend/IMTest/bin/Debug/net8.0/IMTest.dll b/backend/IMTest/bin/Debug/net8.0/IMTest.dll index 044ea8a..7676d44 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 a3d1b90..39fed94 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 317926a..4b6dd57 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 598449d..4d58f5d 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 3ee5a3b..0d24bfb 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 29b15fd..8145089 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+2ecaa28091b41de707825db3628d380b62fa727f")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+eb8455e141ea496a2134ad7c7d9b759b6029dd75")] [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 d02a3dc..2827c86 100644 --- a/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache +++ b/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache @@ -1 +1 @@ -ed4980dfc7aff253176b260ed9015f9a80b52e92cbf3095eff3ed06865ea6e0d +546570633bb9288fc2957cbb29a807a45f3e48ba127ec13bc3956d28f5e6ed5b 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 2932c7a..56fb82e 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 044ea8a..7676d44 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 a3d1b90..39fed94 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 2793b43..46238b8 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 2793b43..46238b8 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/GroupInviteActionUpdateHandler/RequestDbHandler.cs b/backend/IM_API/Application/EventHandlers/GroupInviteActionUpdateHandler/RequestDbHandler.cs index c5c7620..c7f2321 100644 --- a/backend/IM_API/Application/EventHandlers/GroupInviteActionUpdateHandler/RequestDbHandler.cs +++ b/backend/IM_API/Application/EventHandlers/GroupInviteActionUpdateHandler/RequestDbHandler.cs @@ -15,7 +15,7 @@ namespace IM_API.Application.EventHandlers.GroupInviteActionUpdateHandler public async Task Consume(ConsumeContext context) { var @event = context.Message; - if(@event.Action == Models.GroupInviteState.Passed) + if(@event.Action == Models.GroupRequestState.Passed) { await _groupService.MakeGroupRequestAsync(@event.UserId, @event.InviteUserId,@event.GroupId); } diff --git a/backend/IM_API/Configs/MapperConfig.cs b/backend/IM_API/Configs/MapperConfig.cs index 53f40c0..5fb327a 100644 --- a/backend/IM_API/Configs/MapperConfig.cs +++ b/backend/IM_API/Configs/MapperConfig.cs @@ -29,6 +29,7 @@ namespace IM_API.Configs CreateMap() .ForMember(dest => dest.Username,opt => opt.MapFrom(src => src.Username)) .ForMember(dest => dest.Password,opt => opt.MapFrom(src => src.Password)) + .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email)) .ForMember(dest => dest.Avatar,opt => opt.MapFrom(src => "https://ts1.tc.mm.bing.net/th/id/OIP-C.dl0WpkTP6E2J4FnhDC_jHwAAAA?rs=1&pid=ImgDetMain&o=7&rm=3")) .ForMember(dest => dest.StatusEnum,opt => opt.MapFrom(src => UserStatus.Normal)) .ForMember(dest => dest.OnlineStatusEnum,opt => opt.MapFrom(src => UserOnlineStatus.Offline)) @@ -229,6 +230,20 @@ namespace IM_API.Configs .ForMember(dest => dest.AllMembersBanned, opt => opt.MapFrom(src => src.AllMembersBannedEnum)) .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.StatusEnum)) ; + + //群通知模型转换 + CreateMap() + .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.UserId)) + .ForMember(dest => dest.GroupId, opt => opt.MapFrom(src => src.GroupId)) + .ForMember(dest => dest.InviteUser, opt => opt.MapFrom(src => src.InviteUserId)) + .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.StateEnum)) + .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Description)) + .ForMember(dest => dest.RequestId, opt => opt.MapFrom(src => src.Id)) + //.ForAllMembers(opt => opt.Ignore()) + ; + + + } } } diff --git a/backend/IM_API/Controllers/GroupController.cs b/backend/IM_API/Controllers/GroupController.cs index 35476ed..12bc59e 100644 --- a/backend/IM_API/Controllers/GroupController.cs +++ b/backend/IM_API/Controllers/GroupController.cs @@ -96,5 +96,14 @@ namespace IM_API.Controllers var group = await _groupService.GetGroupInfoAsync(groupId); return Ok(new BaseResponse(group)); } + + [HttpGet] + [ProducesResponseType(typeof(BaseResponse>), StatusCodes.Status200OK)] + public async Task GetGroupNotification([FromQuery]int groupId) + { + string userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier)!; + var data = await _groupService.GetGroupNotificationAsync(int.Parse(userIdStr)); + return Ok(new BaseResponse>(data)); + } } } diff --git a/backend/IM_API/Domain/Events/GroupInviteActionUpdateEvent.cs b/backend/IM_API/Domain/Events/GroupInviteActionUpdateEvent.cs index 3368dfe..2e0de1a 100644 --- a/backend/IM_API/Domain/Events/GroupInviteActionUpdateEvent.cs +++ b/backend/IM_API/Domain/Events/GroupInviteActionUpdateEvent.cs @@ -9,6 +9,6 @@ namespace IM_API.Domain.Events public int InviteUserId { get; set; } public int InviteId { get; set; } public int GroupId { get; set; } - public GroupInviteState Action { get; set; } + public GroupRequestState Action { get; set; } } } diff --git a/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs b/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs index c32dd87..e9d0efa 100644 --- a/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs +++ b/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs @@ -4,6 +4,8 @@ namespace IM_API.Dtos.Auth { public class RegisterRequestDto { + [EmailAddress(ErrorMessage = "邮箱格式错误")] + public string Email { get; set; } [Required(ErrorMessage = "用户名不能为空")] [MaxLength(20, ErrorMessage = "用户名不能超过20字符")] [RegularExpression(@"^[A-Za-z0-9]+$", ErrorMessage = "用户名只能为英文或数字")] diff --git a/backend/IM_API/Dtos/Group/HandleGroupInviteDto.cs b/backend/IM_API/Dtos/Group/HandleGroupInviteDto.cs index 038a4bd..7f26982 100644 --- a/backend/IM_API/Dtos/Group/HandleGroupInviteDto.cs +++ b/backend/IM_API/Dtos/Group/HandleGroupInviteDto.cs @@ -5,6 +5,6 @@ namespace IM_API.Dtos.Group public class HandleGroupInviteDto { public int InviteId { get; set; } - public GroupInviteState Action { get; set; } + public GroupRequestState Action { get; set; } } } diff --git a/backend/IM_API/Interface/Services/IGroupService.cs b/backend/IM_API/Interface/Services/IGroupService.cs index 55ed4b0..67bfc8d 100644 --- a/backend/IM_API/Interface/Services/IGroupService.cs +++ b/backend/IM_API/Interface/Services/IGroupService.cs @@ -56,5 +56,12 @@ namespace IM_API.Interface.Services Task UpdateGroupInfoAsync(int userId, int groupId, GroupUpdateDto updateDto); Task GetGroupInfoAsync(int groupId); + + /// + /// 获取群聊通知 + /// + /// + /// + Task> GetGroupNotificationAsync(int userId); } } diff --git a/backend/IM_API/Migrations/20260309065303_update-group-announcement.Designer.cs b/backend/IM_API/Migrations/20260309065303_update-group-announcement.Designer.cs new file mode 100644 index 0000000..27fcb46 --- /dev/null +++ b/backend/IM_API/Migrations/20260309065303_update-group-announcement.Designer.cs @@ -0,0 +1,1174 @@ +// +using System; +using IM_API.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IM_API.Migrations +{ + [DbContext(typeof(ImContext))] + [Migration("20260309065303_update-group-announcement")] + partial class updategroupannouncement + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("latin1_swedish_ci") + .HasAnnotation("ProductVersion", "8.0.21") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "latin1"); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("状态(0:正常,2:封禁) "); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("更新时间 "); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RoleId" }, "RoleId"); + + b.ToTable("admins", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("int(11)"); + + b.Property("LastMessage") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("最后一条最新消息"); + + b.Property("LastMessageTime") + .HasColumnType("datetime") + .HasComment("最后一条消息发送时间"); + + b.Property("LastReadSequenceId") + .HasColumnType("int(11)") + .HasColumnName("lastReadMessageId") + .HasComment("最后一条未读消息ID "); + + b.Property("MessageId") + .HasColumnType("int(11)"); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.Property("TargetId") + .HasColumnType("int(11)") + .HasComment("对方ID(群聊为群聊ID,单聊为单聊ID) "); + + b.Property("UnreadCount") + .HasColumnType("int(11)") + .HasComment("未读消息数 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("MessageId"); + + b.HasIndex(new[] { "LastReadSequenceId" }, "LastReadSequenceId"); + + b.HasIndex(new[] { "UserId" }, "Userid"); + + b.ToTable("conversations", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(\r\n0:Android,1:Ios,2:PC,3:Pad,4:未知)"); + + b.Property("LastLogin") + .HasColumnType("datetime") + .HasComment("最后一次登录 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("设备所属用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userid") + .HasDatabaseName("Userid1"); + + b.ToTable("devices", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("varchar(10)") + .HasComment("文件类型 "); + + b.Property("MessageId") + .HasColumnType("int(11)") + .HasComment("关联消息ID "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("文件名 "); + + b.Property("Size") + .HasColumnType("int(11)") + .HasComment("文件大小(单位:KB) "); + + b.Property("Url") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("URL") + .HasComment("文件储存URL "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "MessageId" }, "Messageld"); + + b.ToTable("files", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("好友头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("好友关系创建时间"); + + b.Property("FriendId") + .HasColumnType("int(11)") + .HasComment("用户2ID"); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("好友备注名"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("当前好友关系状态\r\n(0:待通过,1:已添加,2:已拒绝,3:已拉黑)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户ID"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID"); + + b.HasIndex(new[] { "UserId", "FriendId" }, "Userld"); + + b.HasIndex(new[] { "FriendId" }, "用户2id"); + + b.ToTable("friends", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("申请时间 "); + + b.Property("Description") + .HasColumnType("text") + .HasComment("申请附言 "); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("备注"); + + b.Property("RequestUser") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.Property("ResponseUser") + .HasColumnType("int(11)") + .HasComment("被申请人 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待通过,1:拒绝,2:同意,3:拉黑) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RequestUser" }, "RequestUser"); + + b.HasIndex(new[] { "ResponseUser" }, "ResponseUser"); + + b.ToTable("friend_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllMembersBanned") + .HasColumnType("tinyint(4)") + .HasComment("全员禁言(0允许发言,2全员禁言)"); + + b.Property("Announcement") + .IsRequired() + .HasColumnType("text") + .HasComment("群公告"); + + b.Property("Auhority") + .HasColumnType("tinyint(4)") + .HasComment("群权限\r\n(0:需管理员同意,1:任意人可加群,2:不允许任何人加入)"); + + b.Property("Avatar") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("群头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("群聊创建时间"); + + b.Property("GroupMaster") + .HasColumnType("int(11)") + .HasComment("群主"); + + b.Property("LastMessage") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastSenderName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastUpdateTime") + .HasColumnType("datetime(6)"); + + b.Property("MaxSequenceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("群聊名称"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("群聊状态\r\n(1:正常,2:封禁)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupMaster" }, "GroupMaster"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID1"); + + b.ToTable("groups", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupInvite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号"); + + b.Property("InviteUser") + .HasColumnType("int(11)") + .HasComment("邀请用户"); + + b.Property("InvitedUser") + .HasColumnType("int(11)") + .HasComment("被邀请用户"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("当前状态(0:待被邀请人同意\r\n1:被邀请人已同意)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupId" }, "GroupId"); + + b.HasIndex(new[] { "InviteUser" }, "InviteUser"); + + b.HasIndex(new[] { "InvitedUser" }, "InvitedUser"); + + b.ToTable("group_invite", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("加入群聊时间"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号"); + + b.Property("Role") + .HasColumnType("tinyint(4)") + .HasComment("成员角色(0:普通成员,1:管理员,2:群主)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户编号"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupId" }, "Groupld"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID2"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld1"); + + b.ToTable("group_member", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("入群附言"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号\r\n"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待管理员同意,1:已拒绝,2:已同意)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("UserId"); + + b.HasIndex(new[] { "GroupId" }, "GroupId") + .HasDatabaseName("GroupId1"); + + b.ToTable("group_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(通Devices/DType) "); + + b.Property("Logined") + .HasColumnType("datetime") + .HasComment("登录时间 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("登录状态(0:登陆成功,1:未验证,2:已被拒绝) "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("登录用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld2"); + + b.ToTable("login_log", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("tinyint(4)") + .HasComment("聊天类型\r\n(0:私聊,1:群聊)"); + + b.Property("ClientMsgId") + .HasColumnType("char(36)"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("消息内容 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("发送时间 "); + + b.Property("MsgType") + .HasColumnType("tinyint(4)") + .HasComment("消息类型\r\n(0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)"); + + b.Property("Recipient") + .HasColumnType("int(11)") + .HasComment("接收者(私聊为用户ID,群聊为群聊ID) "); + + b.Property("Sender") + .HasColumnType("int(11)") + .HasComment("发送者 "); + + b.Property("SequenceId") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("消息状态(0:已发送,1:已撤回) "); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("SequenceId", "StreamKey") + .IsUnique(); + + b.HasIndex(new[] { "Sender" }, "Sender"); + + b.ToTable("messages", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("通知内容"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Ntype") + .HasColumnType("tinyint(4)") + .HasColumnName("NType") + .HasComment("通知类型(0:文本)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasComment("通知标题"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("接收人(为空为全体通知)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld3"); + + b.ToTable("notifications", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Code") + .HasColumnType("int(11)") + .HasComment("权限编码 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("权限名称 "); + + b.Property("Ptype") + .HasColumnType("int(11)") + .HasColumnName("PType") + .HasComment("权限类型(0:增,1:删,2:改,3:查) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("permissions", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.Property("Id") + .HasColumnType("int(11)") + .HasColumnName("ID"); + + b.Property("PermissionId") + .HasColumnType("int(11)") + .HasComment("权限 "); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "PermissionId" }, "Permissionld"); + + b.HasIndex(new[] { "RoleId" }, "Roleld"); + + b.ToTable("permissionarole", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("角色描述 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("角色名称 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("roles", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Upload.UploadTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChunkSize") + .HasColumnType("int"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FileHash") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("ObjectName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProviderUploadId") + .HasColumnType("longtext"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StorageProvider") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TotalChunks") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("upload_tasks", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("用户头像链接"); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("创建时间"); + + b.Property("IsDeleted") + .HasColumnType("tinyint(4)") + .HasComment("软删除标识\r\n0:账号正常\r\n1:账号已删除"); + + b.Property("NickName") + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户昵称"); + + b.Property("OnlineStatus") + .HasColumnType("tinyint(4)") + .HasComment("用户在线状态\r\n0(默认):不在线\r\n1:在线"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(4)") + .HasDefaultValueSql("'1'") + .HasComment("账户状态\r\n(0:未激活,1:正常,2:封禁)"); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("修改时间"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("唯一用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID3"); + + b.HasIndex(new[] { "Username" }, "Username") + .IsUnique(); + + b.ToTable("users", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Admins") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("admins_ibfk_1"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.HasOne("IM_API.Models.Message", null) + .WithMany("Conversations") + .HasForeignKey("MessageId"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("Conversations") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("conversations_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Devices") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("devices_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.HasOne("IM_API.Models.Message", "Message") + .WithMany("Files") + .HasForeignKey("MessageId") + .IsRequired() + .HasConstraintName("files_ibfk_1"); + + b.Navigation("Message"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.HasOne("IM_API.Models.User", "FriendNavigation") + .WithMany("FriendFriendNavigations") + .HasForeignKey("FriendId") + .IsRequired() + .HasConstraintName("用户2id"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("FriendUsers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("用户id"); + + b.Navigation("FriendNavigation"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.HasOne("IM_API.Models.User", "RequestUserNavigation") + .WithMany("FriendRequestRequestUserNavigations") + .HasForeignKey("RequestUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "ResponseUserNavigation") + .WithMany("FriendRequestResponseUserNavigations") + .HasForeignKey("ResponseUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_2"); + + b.Navigation("RequestUserNavigation"); + + b.Navigation("ResponseUserNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.HasOne("IM_API.Models.User", "GroupMasterNavigation") + .WithMany("Groups") + .HasForeignKey("GroupMaster") + .IsRequired() + .HasConstraintName("groups_ibfk_1"); + + b.Navigation("GroupMasterNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.GroupInvite", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupInvites") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_invite_ibfk_2"); + + b.HasOne("IM_API.Models.User", "InviteUserNavigation") + .WithMany("GroupInviteInviteUserNavigations") + .HasForeignKey("InviteUser") + .HasConstraintName("group_invite_ibfk_1"); + + b.HasOne("IM_API.Models.User", "InvitedUserNavigation") + .WithMany("GroupInviteInvitedUserNavigations") + .HasForeignKey("InvitedUser") + .HasConstraintName("group_invite_ibfk_3"); + + b.Navigation("Group"); + + b.Navigation("InviteUserNavigation"); + + b.Navigation("InvitedUserNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupMembers") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_member_ibfk_2"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupMembers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_member_ibfk_1"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupRequests") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupRequests") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_request_ibfk_2"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("LoginLogs") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("login_log_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.HasOne("IM_API.Models.User", "SenderNavigation") + .WithMany("Messages") + .HasForeignKey("Sender") + .IsRequired() + .HasConstraintName("messages_ibfk_1"); + + b.Navigation("SenderNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("notifications_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.HasOne("IM_API.Models.Permission", "Permission") + .WithMany("Permissionaroles") + .HasForeignKey("PermissionId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_2"); + + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Permissionaroles") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_1"); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Navigation("GroupInvites"); + + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Navigation("Conversations"); + + b.Navigation("Files"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Navigation("Admins"); + + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Navigation("Conversations"); + + b.Navigation("Devices"); + + b.Navigation("FriendFriendNavigations"); + + b.Navigation("FriendRequestRequestUserNavigations"); + + b.Navigation("FriendRequestResponseUserNavigations"); + + b.Navigation("FriendUsers"); + + b.Navigation("GroupInviteInviteUserNavigations"); + + b.Navigation("GroupInviteInvitedUserNavigations"); + + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + + b.Navigation("Groups"); + + b.Navigation("LoginLogs"); + + b.Navigation("Messages"); + + b.Navigation("Notifications"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/IM_API/Migrations/20260309065303_update-group-announcement.cs b/backend/IM_API/Migrations/20260309065303_update-group-announcement.cs new file mode 100644 index 0000000..44cea10 --- /dev/null +++ b/backend/IM_API/Migrations/20260309065303_update-group-announcement.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IM_API.Migrations +{ + /// + public partial class updategroupannouncement : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "groups", + keyColumn: "Announcement", + keyValue: null, + column: "Announcement", + value: ""); + + migrationBuilder.AlterColumn( + name: "Announcement", + table: "groups", + type: "text", + nullable: false, + comment: "群公告", + collation: "utf8mb4_general_ci", + oldClrType: typeof(string), + oldType: "text", + oldNullable: true, + oldComment: "群公告") + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("Relational:Collation", "utf8mb4_general_ci"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Announcement", + table: "groups", + type: "text", + nullable: true, + comment: "群公告", + collation: "utf8mb4_general_ci", + oldClrType: typeof(string), + oldType: "text", + oldComment: "群公告") + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("Relational:Collation", "utf8mb4_general_ci"); + } + } +} diff --git a/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.Designer.cs b/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.Designer.cs new file mode 100644 index 0000000..e2229a8 --- /dev/null +++ b/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.Designer.cs @@ -0,0 +1,1101 @@ +// +using System; +using IM_API.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IM_API.Migrations +{ + [DbContext(typeof(ImContext))] + [Migration("20260312094604_group-invite-request-merge")] + partial class groupinviterequestmerge + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("latin1_swedish_ci") + .HasAnnotation("ProductVersion", "8.0.21") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "latin1"); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("状态(0:正常,2:封禁) "); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("更新时间 "); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RoleId" }, "RoleId"); + + b.ToTable("admins", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("int(11)"); + + b.Property("LastMessage") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("最后一条最新消息"); + + b.Property("LastMessageTime") + .HasColumnType("datetime") + .HasComment("最后一条消息发送时间"); + + b.Property("LastReadSequenceId") + .HasColumnType("int(11)") + .HasColumnName("lastReadMessageId") + .HasComment("最后一条未读消息ID "); + + b.Property("MessageId") + .HasColumnType("int(11)"); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.Property("TargetId") + .HasColumnType("int(11)") + .HasComment("对方ID(群聊为群聊ID,单聊为单聊ID) "); + + b.Property("UnreadCount") + .HasColumnType("int(11)") + .HasComment("未读消息数 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("MessageId"); + + b.HasIndex(new[] { "LastReadSequenceId" }, "LastReadSequenceId"); + + b.HasIndex(new[] { "UserId" }, "Userid"); + + b.ToTable("conversations", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(\r\n0:Android,1:Ios,2:PC,3:Pad,4:未知)"); + + b.Property("LastLogin") + .HasColumnType("datetime") + .HasComment("最后一次登录 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("设备所属用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userid") + .HasDatabaseName("Userid1"); + + b.ToTable("devices", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("varchar(10)") + .HasComment("文件类型 "); + + b.Property("MessageId") + .HasColumnType("int(11)") + .HasComment("关联消息ID "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("文件名 "); + + b.Property("Size") + .HasColumnType("int(11)") + .HasComment("文件大小(单位:KB) "); + + b.Property("Url") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("URL") + .HasComment("文件储存URL "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "MessageId" }, "Messageld"); + + b.ToTable("files", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("好友头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("好友关系创建时间"); + + b.Property("FriendId") + .HasColumnType("int(11)") + .HasComment("用户2ID"); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("好友备注名"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("当前好友关系状态\r\n(0:待通过,1:已添加,2:已拒绝,3:已拉黑)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户ID"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID"); + + b.HasIndex(new[] { "UserId", "FriendId" }, "Userld"); + + b.HasIndex(new[] { "FriendId" }, "用户2id"); + + b.ToTable("friends", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("申请时间 "); + + b.Property("Description") + .HasColumnType("text") + .HasComment("申请附言 "); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("备注"); + + b.Property("RequestUser") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.Property("ResponseUser") + .HasColumnType("int(11)") + .HasComment("被申请人 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待通过,1:拒绝,2:同意,3:拉黑) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RequestUser" }, "RequestUser"); + + b.HasIndex(new[] { "ResponseUser" }, "ResponseUser"); + + b.ToTable("friend_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllMembersBanned") + .HasColumnType("tinyint(4)") + .HasComment("全员禁言(0允许发言,2全员禁言)"); + + b.Property("Announcement") + .IsRequired() + .HasColumnType("text") + .HasComment("群公告"); + + b.Property("Auhority") + .HasColumnType("tinyint(4)") + .HasComment("群权限\r\n(0:需管理员同意,1:任意人可加群,2:不允许任何人加入)"); + + b.Property("Avatar") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("群头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("群聊创建时间"); + + b.Property("GroupMaster") + .HasColumnType("int(11)") + .HasComment("群主"); + + b.Property("LastMessage") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastSenderName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastUpdateTime") + .HasColumnType("datetime(6)"); + + b.Property("MaxSequenceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("群聊名称"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("群聊状态\r\n(1:正常,2:封禁)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupMaster" }, "GroupMaster"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID1"); + + b.ToTable("groups", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("加入群聊时间"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号"); + + b.Property("Role") + .HasColumnType("tinyint(4)") + .HasComment("成员角色(0:普通成员,1:管理员,2:群主)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户编号"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupId" }, "Groupld"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID2"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld1"); + + b.ToTable("group_member", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("入群附言"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号\r\n"); + + b.Property("InviteUserId") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待管理员同意,1:已拒绝,2:已同意)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("UserId"); + + b.HasIndex(new[] { "GroupId" }, "GroupId"); + + b.ToTable("group_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(通Devices/DType) "); + + b.Property("Logined") + .HasColumnType("datetime") + .HasComment("登录时间 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("登录状态(0:登陆成功,1:未验证,2:已被拒绝) "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("登录用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld2"); + + b.ToTable("login_log", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("tinyint(4)") + .HasComment("聊天类型\r\n(0:私聊,1:群聊)"); + + b.Property("ClientMsgId") + .HasColumnType("char(36)"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("消息内容 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("发送时间 "); + + b.Property("MsgType") + .HasColumnType("tinyint(4)") + .HasComment("消息类型\r\n(0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)"); + + b.Property("Recipient") + .HasColumnType("int(11)") + .HasComment("接收者(私聊为用户ID,群聊为群聊ID) "); + + b.Property("Sender") + .HasColumnType("int(11)") + .HasComment("发送者 "); + + b.Property("SequenceId") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("消息状态(0:已发送,1:已撤回) "); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("SequenceId", "StreamKey") + .IsUnique(); + + b.HasIndex(new[] { "Sender" }, "Sender"); + + b.ToTable("messages", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("通知内容"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Ntype") + .HasColumnType("tinyint(4)") + .HasColumnName("NType") + .HasComment("通知类型(0:文本)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasComment("通知标题"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("接收人(为空为全体通知)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld3"); + + b.ToTable("notifications", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Code") + .HasColumnType("int(11)") + .HasComment("权限编码 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("权限名称 "); + + b.Property("Ptype") + .HasColumnType("int(11)") + .HasColumnName("PType") + .HasComment("权限类型(0:增,1:删,2:改,3:查) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("permissions", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.Property("Id") + .HasColumnType("int(11)") + .HasColumnName("ID"); + + b.Property("PermissionId") + .HasColumnType("int(11)") + .HasComment("权限 "); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "PermissionId" }, "Permissionld"); + + b.HasIndex(new[] { "RoleId" }, "Roleld"); + + b.ToTable("permissionarole", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("角色描述 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("角色名称 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("roles", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Upload.UploadTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChunkSize") + .HasColumnType("int"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FileHash") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("ObjectName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProviderUploadId") + .HasColumnType("longtext"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StorageProvider") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TotalChunks") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("upload_tasks", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("用户头像链接"); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("创建时间"); + + b.Property("IsDeleted") + .HasColumnType("tinyint(4)") + .HasComment("软删除标识\r\n0:账号正常\r\n1:账号已删除"); + + b.Property("NickName") + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户昵称"); + + b.Property("OnlineStatus") + .HasColumnType("tinyint(4)") + .HasComment("用户在线状态\r\n0(默认):不在线\r\n1:在线"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(4)") + .HasDefaultValueSql("'1'") + .HasComment("账户状态\r\n(0:未激活,1:正常,2:封禁)"); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("修改时间"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("唯一用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID3"); + + b.HasIndex(new[] { "Username" }, "Username") + .IsUnique(); + + b.ToTable("users", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Admins") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("admins_ibfk_1"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.HasOne("IM_API.Models.Message", null) + .WithMany("Conversations") + .HasForeignKey("MessageId"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("Conversations") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("conversations_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Devices") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("devices_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.HasOne("IM_API.Models.Message", "Message") + .WithMany("Files") + .HasForeignKey("MessageId") + .IsRequired() + .HasConstraintName("files_ibfk_1"); + + b.Navigation("Message"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.HasOne("IM_API.Models.User", "FriendNavigation") + .WithMany("FriendFriendNavigations") + .HasForeignKey("FriendId") + .IsRequired() + .HasConstraintName("用户2id"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("FriendUsers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("用户id"); + + b.Navigation("FriendNavigation"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.HasOne("IM_API.Models.User", "RequestUserNavigation") + .WithMany("FriendRequestRequestUserNavigations") + .HasForeignKey("RequestUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "ResponseUserNavigation") + .WithMany("FriendRequestResponseUserNavigations") + .HasForeignKey("ResponseUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_2"); + + b.Navigation("RequestUserNavigation"); + + b.Navigation("ResponseUserNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.HasOne("IM_API.Models.User", "GroupMasterNavigation") + .WithMany("Groups") + .HasForeignKey("GroupMaster") + .IsRequired() + .HasConstraintName("groups_ibfk_1"); + + b.Navigation("GroupMasterNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupMembers") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_member_ibfk_2"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupMembers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_member_ibfk_1"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupRequests") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupRequests") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_request_ibfk_2"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("LoginLogs") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("login_log_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.HasOne("IM_API.Models.User", "SenderNavigation") + .WithMany("Messages") + .HasForeignKey("Sender") + .IsRequired() + .HasConstraintName("messages_ibfk_1"); + + b.Navigation("SenderNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("notifications_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.HasOne("IM_API.Models.Permission", "Permission") + .WithMany("Permissionaroles") + .HasForeignKey("PermissionId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_2"); + + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Permissionaroles") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_1"); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Navigation("Conversations"); + + b.Navigation("Files"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Navigation("Admins"); + + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Navigation("Conversations"); + + b.Navigation("Devices"); + + b.Navigation("FriendFriendNavigations"); + + b.Navigation("FriendRequestRequestUserNavigations"); + + b.Navigation("FriendRequestResponseUserNavigations"); + + b.Navigation("FriendUsers"); + + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + + b.Navigation("Groups"); + + b.Navigation("LoginLogs"); + + b.Navigation("Messages"); + + b.Navigation("Notifications"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.cs b/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.cs new file mode 100644 index 0000000..1fe1ed6 --- /dev/null +++ b/backend/IM_API/Migrations/20260312094604_group-invite-request-merge.cs @@ -0,0 +1,87 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IM_API.Migrations +{ + /// + public partial class groupinviterequestmerge : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "group_invite"); + + migrationBuilder.AddColumn( + name: "InviteUserId", + table: "group_request", + type: "int", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "InviteUserId", + table: "group_request"); + + migrationBuilder.RenameIndex( + name: "GroupId", + table: "group_request", + newName: "GroupId1"); + + migrationBuilder.CreateTable( + name: "group_invite", + columns: table => new + { + ID = table.Column(type: "int(11)", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + GroupId = table.Column(type: "int(11)", nullable: false, comment: "群聊编号"), + InvitedUser = table.Column(type: "int(11)", nullable: true, comment: "被邀请用户"), + InviteUser = table.Column(type: "int(11)", nullable: true, comment: "邀请用户"), + Created = table.Column(type: "datetime", nullable: true, comment: "创建时间"), + State = table.Column(type: "tinyint(4)", nullable: true, comment: "当前状态(0:待被邀请人同意\r\n1:被邀请人已同意)") + }, + constraints: table => + { + table.PrimaryKey("PRIMARY", x => x.ID); + table.ForeignKey( + name: "group_invite_ibfk_1", + column: x => x.InviteUser, + principalTable: "users", + principalColumn: "ID"); + table.ForeignKey( + name: "group_invite_ibfk_2", + column: x => x.GroupId, + principalTable: "groups", + principalColumn: "ID"); + table.ForeignKey( + name: "group_invite_ibfk_3", + column: x => x.InvitedUser, + principalTable: "users", + principalColumn: "ID"); + }) + .Annotation("MySql:CharSet", "utf8mb4") + .Annotation("Relational:Collation", "utf8mb4_general_ci"); + + migrationBuilder.CreateIndex( + name: "GroupId", + table: "group_invite", + column: "GroupId"); + + migrationBuilder.CreateIndex( + name: "InvitedUser", + table: "group_invite", + column: "InvitedUser"); + + migrationBuilder.CreateIndex( + name: "InviteUser", + table: "group_invite", + column: "InviteUser"); + } + } +} diff --git a/backend/IM_API/Migrations/20260315134653_update-user.Designer.cs b/backend/IM_API/Migrations/20260315134653_update-user.Designer.cs new file mode 100644 index 0000000..d45c70f --- /dev/null +++ b/backend/IM_API/Migrations/20260315134653_update-user.Designer.cs @@ -0,0 +1,1110 @@ +// +using System; +using IM_API.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IM_API.Migrations +{ + [DbContext(typeof(ImContext))] + [Migration("20260315134653_update-user")] + partial class updateuser + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("latin1_swedish_ci") + .HasAnnotation("ProductVersion", "8.0.21") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "latin1"); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("状态(0:正常,2:封禁) "); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("更新时间 "); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RoleId" }, "RoleId"); + + b.ToTable("admins", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("int(11)"); + + b.Property("LastMessage") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("最后一条最新消息"); + + b.Property("LastMessageTime") + .HasColumnType("datetime") + .HasComment("最后一条消息发送时间"); + + b.Property("LastReadSequenceId") + .HasColumnType("int(11)") + .HasColumnName("lastReadMessageId") + .HasComment("最后一条未读消息ID "); + + b.Property("MessageId") + .HasColumnType("int(11)"); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.Property("TargetId") + .HasColumnType("int(11)") + .HasComment("对方ID(群聊为群聊ID,单聊为单聊ID) "); + + b.Property("UnreadCount") + .HasColumnType("int(11)") + .HasComment("未读消息数 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("MessageId"); + + b.HasIndex(new[] { "LastReadSequenceId" }, "LastReadSequenceId"); + + b.HasIndex(new[] { "UserId" }, "Userid"); + + b.ToTable("conversations", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(\r\n0:Android,1:Ios,2:PC,3:Pad,4:未知)"); + + b.Property("LastLogin") + .HasColumnType("datetime") + .HasComment("最后一次登录 "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("设备所属用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userid") + .HasDatabaseName("Userid1"); + + b.ToTable("devices", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("varchar(10)") + .HasComment("文件类型 "); + + b.Property("MessageId") + .HasColumnType("int(11)") + .HasComment("关联消息ID "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("文件名 "); + + b.Property("Size") + .HasColumnType("int(11)") + .HasComment("文件大小(单位:KB) "); + + b.Property("Url") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("URL") + .HasComment("文件储存URL "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "MessageId" }, "Messageld"); + + b.ToTable("files", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("好友头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("好友关系创建时间"); + + b.Property("FriendId") + .HasColumnType("int(11)") + .HasComment("用户2ID"); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("好友备注名"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("当前好友关系状态\r\n(0:待通过,1:已添加,2:已拒绝,3:已拉黑)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户ID"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID"); + + b.HasIndex(new[] { "UserId", "FriendId" }, "Userld"); + + b.HasIndex(new[] { "FriendId" }, "用户2id"); + + b.ToTable("friends", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("申请时间 "); + + b.Property("Description") + .HasColumnType("text") + .HasComment("申请附言 "); + + b.Property("RemarkName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("备注"); + + b.Property("RequestUser") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.Property("ResponseUser") + .HasColumnType("int(11)") + .HasComment("被申请人 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待通过,1:拒绝,2:同意,3:拉黑) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "RequestUser" }, "RequestUser"); + + b.HasIndex(new[] { "ResponseUser" }, "ResponseUser"); + + b.ToTable("friend_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllMembersBanned") + .HasColumnType("tinyint(4)") + .HasComment("全员禁言(0允许发言,2全员禁言)"); + + b.Property("Announcement") + .IsRequired() + .HasColumnType("text") + .HasComment("群公告"); + + b.Property("Auhority") + .HasColumnType("tinyint(4)") + .HasComment("群权限\r\n(0:需管理员同意,1:任意人可加群,2:不允许任何人加入)"); + + b.Property("Avatar") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("群头像"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("群聊创建时间"); + + b.Property("GroupMaster") + .HasColumnType("int(11)") + .HasComment("群主"); + + b.Property("LastMessage") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastSenderName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LastUpdateTime") + .HasColumnType("datetime(6)"); + + b.Property("MaxSequenceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("群聊名称"); + + b.Property("Status") + .HasColumnType("tinyint(4)") + .HasComment("群聊状态\r\n(1:正常,2:封禁)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupMaster" }, "GroupMaster"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID1"); + + b.ToTable("groups", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("加入群聊时间"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号"); + + b.Property("Role") + .HasColumnType("tinyint(4)") + .HasComment("成员角色(0:普通成员,1:管理员,2:群主)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("用户编号"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "GroupId" }, "Groupld"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID2"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld1"); + + b.ToTable("group_member", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("入群附言"); + + b.Property("GroupId") + .HasColumnType("int(11)") + .HasComment("群聊编号\r\n"); + + b.Property("InviteUserId") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("申请状态(0:待管理员同意,1:已拒绝,2:已同意)"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("申请人 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("UserId"); + + b.HasIndex(new[] { "GroupId" }, "GroupId"); + + b.ToTable("group_request", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Dtype") + .HasColumnType("tinyint(4)") + .HasColumnName("DType") + .HasComment("设备类型(通Devices/DType) "); + + b.Property("Logined") + .HasColumnType("datetime") + .HasComment("登录时间 "); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("登录状态(0:登陆成功,1:未验证,2:已被拒绝) "); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("登录用户 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld2"); + + b.ToTable("login_log", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatType") + .HasColumnType("tinyint(4)") + .HasComment("聊天类型\r\n(0:私聊,1:群聊)"); + + b.Property("ClientMsgId") + .HasColumnType("char(36)"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("消息内容 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("发送时间 "); + + b.Property("MsgType") + .HasColumnType("tinyint(4)") + .HasComment("消息类型\r\n(0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)"); + + b.Property("Recipient") + .HasColumnType("int(11)") + .HasComment("接收者(私聊为用户ID,群聊为群聊ID) "); + + b.Property("Sender") + .HasColumnType("int(11)") + .HasComment("发送者 "); + + b.Property("SequenceId") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("tinyint(4)") + .HasComment("消息状态(0:已发送,1:已撤回) "); + + b.Property("StreamKey") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("消息推送唯一标识符"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex("SequenceId", "StreamKey") + .IsUnique(); + + b.HasIndex(new[] { "Sender" }, "Sender"); + + b.ToTable("messages", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("通知内容"); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间"); + + b.Property("Ntype") + .HasColumnType("tinyint(4)") + .HasColumnName("NType") + .HasComment("通知类型(0:文本)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasComment("通知标题"); + + b.Property("UserId") + .HasColumnType("int(11)") + .HasComment("接收人(为空为全体通知)"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "UserId" }, "Userld") + .HasDatabaseName("Userld3"); + + b.ToTable("notifications", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Code") + .HasColumnType("int(11)") + .HasComment("权限编码 "); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("权限名称 "); + + b.Property("Ptype") + .HasColumnType("int(11)") + .HasColumnName("PType") + .HasComment("权限类型(0:增,1:删,2:改,3:查) "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("permissions", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.Property("Id") + .HasColumnType("int(11)") + .HasColumnName("ID"); + + b.Property("PermissionId") + .HasColumnType("int(11)") + .HasComment("权限 "); + + b.Property("RoleId") + .HasColumnType("int(11)") + .HasComment("角色 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "PermissionId" }, "Permissionld"); + + b.HasIndex(new[] { "RoleId" }, "Roleld"); + + b.ToTable("permissionarole", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime") + .HasComment("创建时间 "); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasComment("角色描述 "); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasComment("角色名称 "); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("roles", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Upload.UploadTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChunkSize") + .HasColumnType("int"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FileHash") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("ObjectName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProviderUploadId") + .HasColumnType("longtext"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StorageProvider") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TotalChunks") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.ToTable("upload_tasks", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int(11)") + .HasColumnName("ID"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Avatar") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasComment("用户头像链接"); + + b.Property("Created") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValueSql("'1970-01-01 00:00:00'") + .HasComment("创建时间"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("tinyint(4)") + .HasComment("软删除标识\r\n0:账号正常\r\n1:账号已删除"); + + b.Property("NickName") + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("用户昵称"); + + b.Property("OnlineStatus") + .HasColumnType("tinyint(4)") + .HasComment("用户在线状态\r\n0(默认):不在线\r\n1:在线"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("密码"); + + b.Property("Region") + .HasColumnType("longtext"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(4)") + .HasDefaultValueSql("'1'") + .HasComment("账户状态\r\n(0:未激活,1:正常,2:封禁)"); + + b.Property("Updated") + .HasColumnType("datetime") + .HasComment("修改时间"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasComment("唯一用户名"); + + b.HasKey("Id") + .HasName("PRIMARY"); + + b.HasIndex(new[] { "Id" }, "ID") + .HasDatabaseName("ID3"); + + b.HasIndex(new[] { "Username" }, "Username") + .IsUnique(); + + b.ToTable("users", (string)null); + + MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); + MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); + }); + + modelBuilder.Entity("IM_API.Models.Admin", b => + { + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Admins") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("admins_ibfk_1"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Conversation", b => + { + b.HasOne("IM_API.Models.Message", null) + .WithMany("Conversations") + .HasForeignKey("MessageId"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("Conversations") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("conversations_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Device", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Devices") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("devices_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.File", b => + { + b.HasOne("IM_API.Models.Message", "Message") + .WithMany("Files") + .HasForeignKey("MessageId") + .IsRequired() + .HasConstraintName("files_ibfk_1"); + + b.Navigation("Message"); + }); + + modelBuilder.Entity("IM_API.Models.Friend", b => + { + b.HasOne("IM_API.Models.User", "FriendNavigation") + .WithMany("FriendFriendNavigations") + .HasForeignKey("FriendId") + .IsRequired() + .HasConstraintName("用户2id"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("FriendUsers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("用户id"); + + b.Navigation("FriendNavigation"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.FriendRequest", b => + { + b.HasOne("IM_API.Models.User", "RequestUserNavigation") + .WithMany("FriendRequestRequestUserNavigations") + .HasForeignKey("RequestUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "ResponseUserNavigation") + .WithMany("FriendRequestResponseUserNavigations") + .HasForeignKey("ResponseUser") + .IsRequired() + .HasConstraintName("friend_request_ibfk_2"); + + b.Navigation("RequestUserNavigation"); + + b.Navigation("ResponseUserNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.HasOne("IM_API.Models.User", "GroupMasterNavigation") + .WithMany("Groups") + .HasForeignKey("GroupMaster") + .IsRequired() + .HasConstraintName("groups_ibfk_1"); + + b.Navigation("GroupMasterNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.GroupMember", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupMembers") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_member_ibfk_2"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupMembers") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_member_ibfk_1"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.GroupRequest", b => + { + b.HasOne("IM_API.Models.Group", "Group") + .WithMany("GroupRequests") + .HasForeignKey("GroupId") + .IsRequired() + .HasConstraintName("group_request_ibfk_1"); + + b.HasOne("IM_API.Models.User", "User") + .WithMany("GroupRequests") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("group_request_ibfk_2"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.LoginLog", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("LoginLogs") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("login_log_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.HasOne("IM_API.Models.User", "SenderNavigation") + .WithMany("Messages") + .HasForeignKey("Sender") + .IsRequired() + .HasConstraintName("messages_ibfk_1"); + + b.Navigation("SenderNavigation"); + }); + + modelBuilder.Entity("IM_API.Models.Notification", b => + { + b.HasOne("IM_API.Models.User", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .IsRequired() + .HasConstraintName("notifications_ibfk_1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IM_API.Models.Permissionarole", b => + { + b.HasOne("IM_API.Models.Permission", "Permission") + .WithMany("Permissionaroles") + .HasForeignKey("PermissionId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_2"); + + b.HasOne("IM_API.Models.Role", "Role") + .WithMany("Permissionaroles") + .HasForeignKey("RoleId") + .IsRequired() + .HasConstraintName("permissionarole_ibfk_1"); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("IM_API.Models.Group", b => + { + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + }); + + modelBuilder.Entity("IM_API.Models.Message", b => + { + b.Navigation("Conversations"); + + b.Navigation("Files"); + }); + + modelBuilder.Entity("IM_API.Models.Permission", b => + { + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.Role", b => + { + b.Navigation("Admins"); + + b.Navigation("Permissionaroles"); + }); + + modelBuilder.Entity("IM_API.Models.User", b => + { + b.Navigation("Conversations"); + + b.Navigation("Devices"); + + b.Navigation("FriendFriendNavigations"); + + b.Navigation("FriendRequestRequestUserNavigations"); + + b.Navigation("FriendRequestResponseUserNavigations"); + + b.Navigation("FriendUsers"); + + b.Navigation("GroupMembers"); + + b.Navigation("GroupRequests"); + + b.Navigation("Groups"); + + b.Navigation("LoginLogs"); + + b.Navigation("Messages"); + + b.Navigation("Notifications"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/IM_API/Migrations/20260315134653_update-user.cs b/backend/IM_API/Migrations/20260315134653_update-user.cs new file mode 100644 index 0000000..38752f2 --- /dev/null +++ b/backend/IM_API/Migrations/20260315134653_update-user.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IM_API.Migrations +{ + /// + public partial class updateuser : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Description", + table: "users", + type: "longtext", + nullable: true, + collation: "utf8mb4_general_ci") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Email", + table: "users", + type: "longtext", + nullable: true, + collation: "utf8mb4_general_ci") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Region", + table: "users", + type: "longtext", + nullable: true, + collation: "utf8mb4_general_ci") + .Annotation("MySql:CharSet", "utf8mb4"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Description", + table: "users"); + + migrationBuilder.DropColumn( + name: "Email", + table: "users"); + + migrationBuilder.DropColumn( + name: "Region", + table: "users"); + } + } +} diff --git a/backend/IM_API/Migrations/ImContextModelSnapshot.cs b/backend/IM_API/Migrations/ImContextModelSnapshot.cs index 53e6917..f195355 100644 --- a/backend/IM_API/Migrations/ImContextModelSnapshot.cs +++ b/backend/IM_API/Migrations/ImContextModelSnapshot.cs @@ -333,6 +333,7 @@ namespace IM_API.Migrations .HasComment("全员禁言(0允许发言,2全员禁言)"); b.Property("Announcement") + .IsRequired() .HasColumnType("text") .HasComment("群公告"); @@ -392,50 +393,6 @@ namespace IM_API.Migrations MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); }); - modelBuilder.Entity("IM_API.Models.GroupInvite", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int(11)") - .HasColumnName("ID"); - - MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("datetime") - .HasComment("创建时间"); - - b.Property("GroupId") - .HasColumnType("int(11)") - .HasComment("群聊编号"); - - b.Property("InviteUser") - .HasColumnType("int(11)") - .HasComment("邀请用户"); - - b.Property("InvitedUser") - .HasColumnType("int(11)") - .HasComment("被邀请用户"); - - b.Property("State") - .HasColumnType("tinyint(4)") - .HasComment("当前状态(0:待被邀请人同意\r\n1:被邀请人已同意)"); - - b.HasKey("Id") - .HasName("PRIMARY"); - - b.HasIndex(new[] { "GroupId" }, "GroupId"); - - b.HasIndex(new[] { "InviteUser" }, "InviteUser"); - - b.HasIndex(new[] { "InvitedUser" }, "InvitedUser"); - - b.ToTable("group_invite", (string)null); - - MySqlEntityTypeBuilderExtensions.HasCharSet(b, "utf8mb4"); - MySqlEntityTypeBuilderExtensions.UseCollation(b, "utf8mb4_general_ci"); - }); - modelBuilder.Entity("IM_API.Models.GroupMember", b => { b.Property("Id") @@ -502,6 +459,9 @@ namespace IM_API.Migrations .HasColumnType("int(11)") .HasComment("群聊编号\r\n"); + b.Property("InviteUserId") + .HasColumnType("int"); + b.Property("State") .HasColumnType("tinyint(4)") .HasComment("申请状态(0:待管理员同意,1:已拒绝,2:已同意)"); @@ -515,8 +475,7 @@ namespace IM_API.Migrations b.HasIndex("UserId"); - b.HasIndex(new[] { "GroupId" }, "GroupId") - .HasDatabaseName("GroupId1"); + b.HasIndex(new[] { "GroupId" }, "GroupId"); b.ToTable("group_request", (string)null); @@ -844,6 +803,12 @@ namespace IM_API.Migrations .HasDefaultValueSql("'1970-01-01 00:00:00'") .HasComment("创建时间"); + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + b.Property("IsDeleted") .HasColumnType("tinyint(4)") .HasComment("软删除标识\r\n0:账号正常\r\n1:账号已删除"); @@ -863,6 +828,9 @@ namespace IM_API.Migrations .HasColumnType("varchar(50)") .HasComment("密码"); + b.Property("Region") + .HasColumnType("longtext"); + b.Property("Status") .ValueGeneratedOnAdd() .HasColumnType("tinyint(4)") @@ -991,31 +959,6 @@ namespace IM_API.Migrations b.Navigation("GroupMasterNavigation"); }); - modelBuilder.Entity("IM_API.Models.GroupInvite", b => - { - b.HasOne("IM_API.Models.Group", "Group") - .WithMany("GroupInvites") - .HasForeignKey("GroupId") - .IsRequired() - .HasConstraintName("group_invite_ibfk_2"); - - b.HasOne("IM_API.Models.User", "InviteUserNavigation") - .WithMany("GroupInviteInviteUserNavigations") - .HasForeignKey("InviteUser") - .HasConstraintName("group_invite_ibfk_1"); - - b.HasOne("IM_API.Models.User", "InvitedUserNavigation") - .WithMany("GroupInviteInvitedUserNavigations") - .HasForeignKey("InvitedUser") - .HasConstraintName("group_invite_ibfk_3"); - - b.Navigation("Group"); - - b.Navigation("InviteUserNavigation"); - - b.Navigation("InvitedUserNavigation"); - }); - modelBuilder.Entity("IM_API.Models.GroupMember", b => { b.HasOne("IM_API.Models.Group", "Group") @@ -1108,8 +1051,6 @@ namespace IM_API.Migrations modelBuilder.Entity("IM_API.Models.Group", b => { - b.Navigation("GroupInvites"); - b.Navigation("GroupMembers"); b.Navigation("GroupRequests"); @@ -1148,10 +1089,6 @@ namespace IM_API.Migrations b.Navigation("FriendUsers"); - b.Navigation("GroupInviteInviteUserNavigations"); - - b.Navigation("GroupInviteInvitedUserNavigations"); - b.Navigation("GroupMembers"); b.Navigation("GroupRequests"); diff --git a/backend/IM_API/Models/Group.cs b/backend/IM_API/Models/Group.cs index 8d06fee..5449b21 100644 --- a/backend/IM_API/Models/Group.cs +++ b/backend/IM_API/Models/Group.cs @@ -38,7 +38,7 @@ public partial class Group /// /// 群公告 /// - public string? Announcement { get; set; } + public string Announcement { get; set; } = "暂无群公告,点击编辑添加。"; /// /// 群聊创建时间 @@ -56,7 +56,6 @@ public partial class Group public DateTimeOffset LastUpdateTime { get; set; } = DateTime.UtcNow; - public virtual ICollection GroupInvites { get; set; } = new List(); public virtual User GroupMasterNavigation { get; set; } = null!; diff --git a/backend/IM_API/Models/GroupInviteExt.cs b/backend/IM_API/Models/GroupInviteExt.cs deleted file mode 100644 index 1202368..0000000 --- a/backend/IM_API/Models/GroupInviteExt.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace IM_API.Models -{ - public partial class GroupInvite - { - public GroupInviteState StateEnum - { - get => (GroupInviteState)State; - set => State = (sbyte)value; - } - } -} diff --git a/backend/IM_API/Models/GroupInviteState.cs b/backend/IM_API/Models/GroupInviteState.cs deleted file mode 100644 index 0a69d35..0000000 --- a/backend/IM_API/Models/GroupInviteState.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace IM_API.Models -{ - /// - /// 群邀请状态 - /// - public enum GroupInviteState - { - /// - /// 待处理 - /// - Pending = 0, - /// - /// 已同意 - /// - Passed = 1 - } -} diff --git a/backend/IM_API/Models/GroupRequestState.cs b/backend/IM_API/Models/GroupRequestState.cs index ccc0d94..31a389d 100644 --- a/backend/IM_API/Models/GroupRequestState.cs +++ b/backend/IM_API/Models/GroupRequestState.cs @@ -7,12 +7,20 @@ /// Pending = 0, /// - /// 已拒绝 + /// 管理员已拒绝 /// Declined = 1, /// - /// 已同意 + /// 管理员已同意 /// - Passed = 2 + Passed = 2, + /// + /// 待对方同意 + /// + TargetPending = 3, + /// + /// 对方拒绝 + /// + TargetDeclined = 4 } } diff --git a/backend/IM_API/Models/Groupinvite.cs b/backend/IM_API/Models/Groupinvite.cs deleted file mode 100644 index cca0ad9..0000000 --- a/backend/IM_API/Models/Groupinvite.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace IM_API.Models; - -public partial class GroupInvite -{ - public int Id { get; set; } - - /// - /// 群聊编号 - /// - public int GroupId { get; set; } - - /// - /// 被邀请用户 - /// - public int? InvitedUser { get; set; } - - /// - /// 邀请用户 - /// - public int? InviteUser { get; set; } - - /// - /// 当前状态(0:待被邀请人同意 - /// 1:被邀请人已同意) - /// - public sbyte? State { get; set; } - - /// - /// 创建时间 - /// - public DateTimeOffset? Created { get; set; } - - public virtual Group Group { get; set; } = null!; - - public virtual User? InviteUserNavigation { get; set; } - - public virtual User? InvitedUserNavigation { get; set; } -} diff --git a/backend/IM_API/Models/Grouprequest.cs b/backend/IM_API/Models/Grouprequest.cs index a372610..9b20fa5 100644 --- a/backend/IM_API/Models/Grouprequest.cs +++ b/backend/IM_API/Models/Grouprequest.cs @@ -19,8 +19,10 @@ public partial class GroupRequest /// public int UserId { get; set; } + public int? InviteUserId { get; set; } + /// - /// 申请状态(0:待管理员同意,1:已拒绝,2:已同意) + /// 申请状态(0:待管理员同意,1:管理员已拒绝,2:管理员已同意,3:待对方同意,4:对方拒绝) /// public sbyte State { get; set; } diff --git a/backend/IM_API/Models/ImContext.Custom.cs b/backend/IM_API/Models/ImContext.Custom.cs index d02529d..ea2bb95 100644 --- a/backend/IM_API/Models/ImContext.Custom.cs +++ b/backend/IM_API/Models/ImContext.Custom.cs @@ -49,11 +49,6 @@ namespace IM_API.Models entity.Ignore(e => e.AuhorityEnum); }); - modelBuilder.Entity(entity => - { - entity.Ignore(e => e.StateEnum); - }); - modelBuilder.Entity(entity => { entity.Ignore(e => e.RoleEnum); diff --git a/backend/IM_API/Models/ImContext.cs b/backend/IM_API/Models/ImContext.cs index 59599b4..6b263d5 100644 --- a/backend/IM_API/Models/ImContext.cs +++ b/backend/IM_API/Models/ImContext.cs @@ -27,7 +27,6 @@ public partial class ImContext : DbContext public virtual DbSet Groups { get; set; } - public virtual DbSet GroupInvites { get; set; } public virtual DbSet GroupMembers { get; set; } @@ -362,53 +361,6 @@ public partial class ImContext : DbContext .HasConstraintName("groups_ibfk_1"); }); - modelBuilder.Entity(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(entity => { diff --git a/backend/IM_API/Models/User.cs b/backend/IM_API/Models/User.cs index ece733f..2e7ee5d 100644 --- a/backend/IM_API/Models/User.cs +++ b/backend/IM_API/Models/User.cs @@ -23,6 +23,18 @@ public partial class User /// 用户昵称 /// public string? NickName { get; set; } + /// + /// 用户邮箱 + /// + public string? Email { get; set; } + /// + /// 用户签名 + /// + public string? Description { get; set; } = ""; + /// + /// 地区 + /// + public string? Region { get; set; } = "未知地区"; /// /// 用户在线状态 @@ -73,10 +85,6 @@ public partial class User [JsonIgnore] public virtual ICollection FriendUsers { get; set; } = new List(); [JsonIgnore] - public virtual ICollection GroupInviteInviteUserNavigations { get; set; } = new List(); - [JsonIgnore] - public virtual ICollection GroupInviteInvitedUserNavigations { get; set; } = new List(); - [JsonIgnore] public virtual ICollection GroupMembers { get; set; } = new List(); [JsonIgnore] public virtual ICollection GroupRequests { get; set; } = new List(); diff --git a/backend/IM_API/Services/GroupService.cs b/backend/IM_API/Services/GroupService.cs index b784623..d83665a 100644 --- a/backend/IM_API/Services/GroupService.cs +++ b/backend/IM_API/Services/GroupService.cs @@ -79,6 +79,7 @@ namespace IM_API.Services } } + public Task DeleteGroupAsync(int userId, int groupId) { throw new NotImplementedException(); @@ -90,15 +91,15 @@ namespace IM_API.Services x => x.Id == groupId) ?? throw new BaseException(CodeDefine.GROUP_NOT_FOUND); //过滤非好友 var groupInviteIds = await validFriendshipAsync(userId, userIds); - var inviteList = groupInviteIds.Select(id => new GroupInvite + var inviteList = groupInviteIds.Select(id => new GroupRequest { Created = DateTime.UtcNow, GroupId = group.Id, - InviteUser = userId, - InvitedUser = id, - StateEnum = GroupInviteState.Pending + UserId = id, + InviteUserId = userId, + StateEnum = GroupRequestState.TargetPending }).ToList(); - _context.GroupInvites.AddRange(inviteList); + _context.GroupRequests.AddRange(inviteList); await _context.SaveChangesAsync(); await _endPoint.Publish(new GroupInviteEvent { @@ -132,7 +133,7 @@ namespace IM_API.Services throw new NotImplementedException(); } - public async Task> GetGroupListAsync(int userId, int page, int limit, bool desc) + public async Task> GetGroupListAsync(int userId, int page = 1, int limit = 50, bool desc = false) { var query = _context.GroupMembers .Where(x => x.UserId == userId) @@ -159,14 +160,18 @@ namespace IM_API.Services _context.Groups.Update(group); await _context.SaveChangesAsync(); } + public async Task HandleGroupInviteAsync(int userid, HandleGroupInviteDto dto) { var user = _userService.GetUserInfoAsync(userid); - var inviteInfo = await _context.GroupInvites.FirstOrDefaultAsync(x => x.Id == dto.InviteId) + var inviteInfo = await _context.GroupRequests + .FirstOrDefaultAsync(x => x.UserId == userid && x.StateEnum == GroupRequestState.TargetPending) ?? throw new BaseException(CodeDefine.INVALID_ACTION); - if (inviteInfo.InvitedUser != userid) throw new BaseException(CodeDefine.AUTH_FAILED); + if (!(dto.Action == GroupRequestState.TargetPending || + dto.Action == GroupRequestState.TargetDeclined)) + return; inviteInfo.StateEnum = dto.Action; - _context.GroupInvites.Update(inviteInfo); + _context.GroupRequests.Update(inviteInfo); await _context.SaveChangesAsync(); await _endPoint.Publish(new GroupInviteActionUpdateEvent { @@ -176,12 +181,13 @@ namespace IM_API.Services EventId = Guid.NewGuid(), GroupId = inviteInfo.GroupId, InviteId = inviteInfo.Id, - InviteUserId = inviteInfo.InviteUser.Value, + InviteUserId = inviteInfo.InviteUserId!.Value, OperatorId = userid, UserId = userid }); } + public async Task HandleGroupRequestAsync(int userid, HandleGroupRequestDto dto) { var user = _userService.GetUserInfoAsync(userid); @@ -302,5 +308,68 @@ namespace IM_API.Services return _mapper.Map(groupInfo); } + + public async Task> GetGroupNotificationAsync(int userId) + { + // 1. 查询群请求记录 + var groupList = await _context.GroupMembers + .Where(x => x.UserId == userId && + (x.Role == (sbyte)GroupMemberRole.Master || x.Role == (sbyte)GroupMemberRole.Administrator)) + .Select(s => s.GroupId) + .ToListAsync(); + + var groupRequest = await _context.GroupRequests + .Where(x => groupList.Contains(x.GroupId) || x.UserId == userId || x.InviteUserId == userId) + .OrderByDescending(o => o.Id) + .ToListAsync(); + + if (!groupRequest.Any()) return new List(); + + // 2. 收集所有需要的 ID 并去重 + var userIds = groupRequest.Select(s => s.UserId).Distinct().ToList(); + var inviteUserIds = groupRequest.Where(x => x.InviteUserId != null).Select(s => s.InviteUserId.Value).Distinct().ToList(); + var groupIds = groupRequest.Select(s => s.GroupId).Distinct().ToList(); + + var userList = await _userService.GetUserInfoListAsync(userIds); + var inviteUserList = await _userService.GetUserInfoListAsync(inviteUserIds); + var groupInfoList = await _context.Groups + .Where(x => groupIds.Contains(x.Id)) + .ToListAsync(); + + // 2. 转换为字典 + var userDict = userList.ToDictionary(u => u.Id); + var inviteUserDict = inviteUserList.ToDictionary(u => u.Id); + var groupDict = groupInfoList.ToDictionary(g => g.Id); + + // 3. 组装数据 (Select 逻辑不变) + return groupRequest.Select(g => + { + var gnv = _mapper.Map(g); + + // 匹配用户信息 + if (userDict.TryGetValue(g.UserId, out var u)) + { + gnv.UserAvatar = u.Avatar; + gnv.NickName = u.NickName; + } + + // 匹配邀请人信息 + if (g.InviteUserId.HasValue && inviteUserDict.TryGetValue(g.InviteUserId.Value, out var i)) + { + gnv.InviteUserAvatar = i.Avatar; + gnv.InviteUserNickname = i.NickName; + } + + // 匹配群信息 + if (groupDict.TryGetValue(g.GroupId, out var gi)) + { + gnv.GroupAvatar = gi.Avatar; + gnv.GroupName = gi.Name; + } + + return gnv; + }).ToList(); + + } } } diff --git a/backend/IM_API/VOs/Group/GroupInviteActionUpdateVo.cs b/backend/IM_API/VOs/Group/GroupInviteActionUpdateVo.cs index 23fdd23..65640e2 100644 --- a/backend/IM_API/VOs/Group/GroupInviteActionUpdateVo.cs +++ b/backend/IM_API/VOs/Group/GroupInviteActionUpdateVo.cs @@ -8,6 +8,6 @@ namespace IM_API.VOs.Group public int InviteUserId { get; set; } public int InvitedUserId { get; set; } public int InviteId { get; set; } - public GroupInviteState Action { get; set; } + public GroupRequestState Action { get; set; } } } diff --git a/backend/IM_API/VOs/Group/GroupNotificationVo.cs b/backend/IM_API/VOs/Group/GroupNotificationVo.cs new file mode 100644 index 0000000..4152191 --- /dev/null +++ b/backend/IM_API/VOs/Group/GroupNotificationVo.cs @@ -0,0 +1,21 @@ +using IM_API.Models; + +namespace IM_API.VOs.Group +{ + public class GroupNotificationVo + { + public int RequestId { get; set; } + public int? UserId { get; set; } + public string? NickName { get; set; } + public string? UserAvatar { get; set; } + public int GroupId { get; set; } + public string? GroupAvatar { get; set; } + public string? GroupName { get; set; } + + public GroupRequestState Status { get; set; } + public string Description { get; set; } + public int? InviteUser { get; set; } + public string? InviteUserNickname { get; set; } + public string? InviteUserAvatar { get; set; } + } +} diff --git a/frontend/pc/IM/package-lock.json b/frontend/pc/IM/package-lock.json index 9f3a51c..e7ebfb3 100644 --- a/frontend/pc/IM/package-lock.json +++ b/frontend/pc/IM/package-lock.json @@ -16,6 +16,7 @@ "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "axios": "^1.13.2", + "crypto": "^1.0.1", "electron-updater": "^6.3.9", "feather-icons": "^4.29.2", "hevue-img-preview": "^7.1.3", @@ -3993,6 +3994,13 @@ "node": ">= 8" } }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", + "license": "ISC" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", diff --git a/frontend/pc/IM/package.json b/frontend/pc/IM/package.json index 7da87b0..1c62636 100644 --- a/frontend/pc/IM/package.json +++ b/frontend/pc/IM/package.json @@ -25,6 +25,7 @@ "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "axios": "^1.13.2", + "crypto": "^1.0.1", "electron-updater": "^6.3.9", "feather-icons": "^4.29.2", "hevue-img-preview": "^7.1.3", diff --git a/frontend/pc/IM/src/cache/cacheDir.js b/frontend/pc/IM/src/cache/cacheDir.js new file mode 100644 index 0000000..285532b --- /dev/null +++ b/frontend/pc/IM/src/cache/cacheDir.js @@ -0,0 +1,13 @@ +import { app } from "electron"; +import path from 'path'; + +export const CACHE_ROOT = path.join(app.getPath('userData'), 'resource_cache') + +export const PROTOCOL_HEAD = 'ql-im://' + +export const DIRS = { + Image: 'images', + Video: 'videos', + Voice: 'voices', + File: 'files', +} diff --git a/frontend/pc/IM/src/cache/cacheHandler.js b/frontend/pc/IM/src/cache/cacheHandler.js new file mode 100644 index 0000000..28d71c3 --- /dev/null +++ b/frontend/pc/IM/src/cache/cacheHandler.js @@ -0,0 +1,35 @@ +import path from "path"; +import { FILE_TYPE } from "../renderer/src/constants/fileTypeDefine"; +import { DIRS, CACHE_ROOT, PROTOCOL_HEAD } from "./cacheDir"; +import crypto from 'crypto' +import fs from 'fs-extra' +import axios from "axios"; + +export const getCacheResorce = async (url, type = FILE_TYPE.Image) => { + const hash = crypto.createHash('md5').update(url).digest('hex') + const subDir = hash.substring(0,2); + const targetPath = path.join(DIRS[type], subDir) + + const filePath = path.join(targetPath, hash) + + if(await fs.pathExists(path.join(CACHE_ROOT, filePath))){ + return PROTOCOL_HEAD + filePath.replaceAll('\\', '/') + } + + await fs.ensureDir(path.join(CACHE_ROOT, targetPath)) + + const writer = fs.createWriteStream(path.join(CACHE_ROOT, filePath)) + + const response = await axios({ + url, + method: 'GET', + responseType: 'stream' + }) + + response.data.pipe(writer) + + return new Promise((resolve, reject) => { + writer.on('finish', () => resolve(PROTOCOL_HEAD + filePath.replaceAll('\\', '/'))); + writer.on('error', reject); + }); +} diff --git a/frontend/pc/IM/src/cache/protocolReg.js b/frontend/pc/IM/src/cache/protocolReg.js new file mode 100644 index 0000000..72c8d76 --- /dev/null +++ b/frontend/pc/IM/src/cache/protocolReg.js @@ -0,0 +1,13 @@ +import { net, protocol } from 'electron' +import { CACHE_ROOT } from './cacheDir' +import path from 'path' + +export const addProtocolHandler = () => { + protocol.handle('ql-im', (request) => { + const url = request.url.replace('ql-im://', '') + + const filePath = path.join(CACHE_ROOT, url.replaceAll('/', '\\')) + + return net.fetch(`file://${filePath}`) + }) +} diff --git a/frontend/pc/IM/src/main/index.js b/frontend/pc/IM/src/main/index.js index f0878fd..8bb5f3f 100644 --- a/frontend/pc/IM/src/main/index.js +++ b/frontend/pc/IM/src/main/index.js @@ -4,6 +4,8 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/icon.png?asset' import { registerWindowHandler } from './ipcHandlers/window' import { createTry } from './trayHandler' +import { registerCacheHandler } from './ipcHandlers/cache' +import { addProtocolHandler } from '../cache/protocolReg' function createWindow() { // Create the browser window. @@ -49,6 +51,8 @@ app.whenReady().then(() => { // Set app user model id for windows electronApp.setAppUserModelId('com.electron') + addProtocolHandler() + // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils @@ -59,7 +63,8 @@ app.whenReady().then(() => { // IPC test ipcMain.on('ping', () => console.log('pong')) - registerWindowHandler() + registerWindowHandler() + registerCacheHandler() createWindow() diff --git a/frontend/pc/IM/src/main/ipcHandlers/cache.js b/frontend/pc/IM/src/main/ipcHandlers/cache.js new file mode 100644 index 0000000..6955b9c --- /dev/null +++ b/frontend/pc/IM/src/main/ipcHandlers/cache.js @@ -0,0 +1,8 @@ +import { ipcMain } from "electron"; +import { getCacheResorce } from "../../cache/cacheHandler"; + +export function registerCacheHandler(){ + ipcMain.handle('cache-get', (event, url, type) => { + return getCacheResorce(url, type) + }) +} diff --git a/frontend/pc/IM/src/main/ipcHandlers/window.js b/frontend/pc/IM/src/main/ipcHandlers/window.js index 2b71798..b462962 100644 --- a/frontend/pc/IM/src/main/ipcHandlers/window.js +++ b/frontend/pc/IM/src/main/ipcHandlers/window.js @@ -6,7 +6,8 @@ import { is } from '@electron-toolkit/utils' export function registerWindowHandler() { const windowMapData = new Map() - ipcMain.on('window-action', (event, action) => { + //**窗口控件操作 */ + ipcMain.on('window-action', (event, action, data) => { const win = BrowserWindow.fromWebContents(event.sender) if (!win) return const actions = { @@ -20,14 +21,19 @@ export function registerWindowHandler() { win.destroy() } }, - isMaximized: () => win.isMaximized() + isMaximized: () => win.isMaximized(), + changeSize: () => { + win.setSize(data.width, data.height, true) + win.setResizable(data.resizable) + } } actions[action]?.() }) - ipcMain.on('window-new', (event, { route, data }) => { + /**新开窗口 */ + ipcMain.on('window-new', (event, { route, data, width = 900, height=670 }) => { const win = new BrowserWindow({ - width: 900, - height: 670, + width: width, + height: height, show: true, autoHideMenuBar: true, frame: false, diff --git a/frontend/pc/IM/src/preload/index.js b/frontend/pc/IM/src/preload/index.js index 923143a..2f4d62e 100644 --- a/frontend/pc/IM/src/preload/index.js +++ b/frontend/pc/IM/src/preload/index.js @@ -9,8 +9,13 @@ const api = { close: () => ipcRenderer.send('window-action', 'close'), closeThis: () => ipcRenderer.send('window-action', 'closeThis'), isMaximized: () => ipcRenderer.send('window-action', 'isMaximized'), - newWindow: (route, data) => ipcRenderer.send('window-new', { route, data }), - getWindowData: (winId) => ipcRenderer.invoke('get-window-data', winId) + newWindow: (route, data, width, height) => ipcRenderer.send('window-new', { route, data, width, height }), + getWindowData: (winId) => ipcRenderer.invoke('get-window-data', winId), + setMainSize: (width, height, resizable = true) => + ipcRenderer.send('window-action', 'changeSize', { width, height, resizable }) + }, + cache: { + getCache: (url, type) => ipcRenderer.invoke('cache-get', url, type) } } diff --git a/frontend/pc/IM/src/renderer/index.html b/frontend/pc/IM/src/renderer/index.html index 6d8cfaa..35f7a5c 100644 --- a/frontend/pc/IM/src/renderer/index.html +++ b/frontend/pc/IM/src/renderer/index.html @@ -5,13 +5,13 @@ Electron + media-src 'self' blob: http://192.168.5.116:7070; ql-im:"> diff --git a/frontend/pc/IM/src/renderer/src/assets/loading_img.png b/frontend/pc/IM/src/renderer/src/assets/loading_img.png new file mode 100644 index 0000000..2097d21 Binary files /dev/null and b/frontend/pc/IM/src/renderer/src/assets/loading_img.png differ diff --git a/frontend/pc/IM/src/renderer/src/components/AsyncImage.vue b/frontend/pc/IM/src/renderer/src/components/AsyncImage.vue new file mode 100644 index 0000000..8d046af --- /dev/null +++ b/frontend/pc/IM/src/renderer/src/components/AsyncImage.vue @@ -0,0 +1,40 @@ + + + diff --git a/frontend/pc/IM/src/renderer/src/components/WindowControls.vue b/frontend/pc/IM/src/renderer/src/components/WindowControls.vue index a7e3398..6b9a3dc 100644 --- a/frontend/pc/IM/src/renderer/src/components/WindowControls.vue +++ b/frontend/pc/IM/src/renderer/src/components/WindowControls.vue @@ -5,7 +5,7 @@ - -
- - + +
@@ -60,8 +70,8 @@ onMounted(async () =>{
-
@@ -80,8 +90,8 @@ onMounted(async () =>{ box-shadow: 0 4px 12px rgba(0,0,0,0.15); } -header { - padding: 12px 16px; display: flex; justify-content: space-between; +header { + padding: 12px 16px; display: flex; justify-content: space-between; background: #f9f9f9; font-weight: bold; font-size: 14px; } @@ -110,4 +120,4 @@ footer { padding: 12px; } border: none; border-radius: 6px; font-weight: bold; cursor: pointer; } .btn:disabled { background: #e1e1e1; color: #999; cursor: not-allowed; } - \ No newline at end of file + diff --git a/frontend/pc/IM/src/renderer/src/components/messages/InfoSidebar.vue b/frontend/pc/IM/src/renderer/src/components/messages/InfoSidebar.vue index 4b4ac26..82b7dc6 100644 --- a/frontend/pc/IM/src/renderer/src/components/messages/InfoSidebar.vue +++ b/frontend/pc/IM/src/renderer/src/components/messages/InfoSidebar.vue @@ -19,26 +19,26 @@
- {{ groupData.announcement || '暂无群公告,点击编辑添加。' }} + {{ groupInfo ? groupInfo.announcement : '暂无群公告,点击编辑添加。' }}
- +
-
+
+
邀请
@@ -69,12 +69,13 @@
+ diff --git a/frontend/pc/IM/src/renderer/src/views/auth/Login.vue b/frontend/pc/IM/src/renderer/src/views/auth/Login.vue index 402c14b..d535411 100644 --- a/frontend/pc/IM/src/renderer/src/views/auth/Login.vue +++ b/frontend/pc/IM/src/renderer/src/views/auth/Login.vue @@ -1,48 +1,58 @@ @@ -52,12 +62,11 @@ import { useMessage } from '@/components/messages/useAlert' import { authService } from '@/services/auth' import { useRouter } from 'vue-router' import feather from 'feather-icons' -import IconInput from '@/components/IconInput.vue' -import MyButton from '@/components/MyButton.vue' import { required, maxLength, helpers } from '@vuelidate/validators' import useVuelidate from '@vuelidate/core' import { useAuthStore } from '@/stores/auth' import { useSignalRStore } from '@/stores/signalr' +import WindowControls from '../../components/WindowControls.vue' const message = useMessage(); const router = useRouter(); @@ -111,219 +120,190 @@ const handleLogin = async () => { } onMounted(() => { + window.api.window.setMainSize(360, 532, false) feather.replace() }) - - \ No newline at end of file diff --git a/frontend/pc/IM/src/renderer/src/views/auth/Register.vue b/frontend/pc/IM/src/renderer/src/views/auth/Register.vue index 0fd3f73..df05b93 100644 --- a/frontend/pc/IM/src/renderer/src/views/auth/Register.vue +++ b/frontend/pc/IM/src/renderer/src/views/auth/Register.vue @@ -1,49 +1,76 @@ diff --git a/frontend/pc/IM/src/renderer/src/views/contact/ContactList.vue b/frontend/pc/IM/src/renderer/src/views/contact/ContactList.vue index 13cb7ad..34ca1a5 100644 --- a/frontend/pc/IM/src/renderer/src/views/contact/ContactList.vue +++ b/frontend/pc/IM/src/renderer/src/views/contact/ContactList.vue @@ -7,17 +7,17 @@
- +
新的朋友
-
+
-
群聊
-
+
群聊通知
+
标签
@@ -27,7 +27,7 @@
- +
@@ -35,8 +35,8 @@
- @@ -104,9 +104,8 @@ const filteredContacts = computed(() => { // 发送事件给父组件(用于切换回聊天Tab并打开会话) const emit = defineEmits(['start-chat']) -const showGroupList = () => { - groupModal.value = true; -} +// const showGroupList = () => { +// } @@ -206,8 +205,8 @@ onMounted(async () => { } /* 去除 hover、active 等状态的效果 */ -a:hover, -a:active, +a:hover, +a:active, a:focus { text-decoration: none; color: inherit; /* 保持颜色不变 */ @@ -237,4 +236,4 @@ a:focus { .icon-box.orange { background: #faad14; } .icon-box.green { background: #52c41a; } .icon-box.blue { background: #1890ff; } - \ No newline at end of file + diff --git a/frontend/pc/IM/src/renderer/src/views/contact/FriendRequestList.vue b/frontend/pc/IM/src/renderer/src/views/contact/FriendRequestList.vue index 560641a..18fd192 100644 --- a/frontend/pc/IM/src/renderer/src/views/contact/FriendRequestList.vue +++ b/frontend/pc/IM/src/renderer/src/views/contact/FriendRequestList.vue @@ -1,6 +1,10 @@ @@ -61,6 +68,7 @@ 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'; +import WindowControls from '../../components/WindowControls.vue'; const message = useMessage(); const authStore = useAuthStore(); @@ -104,7 +112,7 @@ 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: + case FRIEND_ACTIONS.Accept: message.show('添加好友成功'); break; case FRIEND_ACTIONS.Reject: @@ -132,6 +140,11 @@ onMounted(async () => { width: 100%; height: 100%; background-color: #f5f5f5; /* 极致白 */ +} +.request-container { + width: 100%; + height: 100%; + background-color: #f5f5f5; /* 极致白 */ display: flex; justify-content: center; overflow-y: auto; @@ -320,4 +333,4 @@ onMounted(async () => { border-radius: 10px; cursor: pointer; } - \ No newline at end of file + diff --git a/frontend/pc/IM/src/renderer/src/views/contact/GroupRequest.vue b/frontend/pc/IM/src/renderer/src/views/contact/GroupRequest.vue new file mode 100644 index 0000000..436906c --- /dev/null +++ b/frontend/pc/IM/src/renderer/src/views/contact/GroupRequest.vue @@ -0,0 +1,393 @@ + + + + + diff --git a/frontend/pc/IM/src/renderer/src/views/messages/MessageList.vue b/frontend/pc/IM/src/renderer/src/views/messages/MessageList.vue index 8a34167..cd812d0 100644 --- a/frontend/pc/IM/src/renderer/src/views/messages/MessageList.vue +++ b/frontend/pc/IM/src/renderer/src/views/messages/MessageList.vue @@ -19,7 +19,8 @@
- + + {{ s.unreadCount ?? 0 }}
@@ -35,7 +36,7 @@ - +
@@ -51,10 +52,17 @@ import SearchUser from '@/components/user/SearchUser.vue' import CreateGroup from '@/components/groups/CreateGroup.vue' import { useBrowserNotification } from '@/services/useBrowserNotification' import { useChatStore } from '@/stores/chat' +import { groupService } from '../../services/group' +import { SYSTEM_BASE_STATUS } from '../../constants/systemBaseStatus' +import { useMessage } from '../../components/messages/useAlert' +import { useCacheStore } from '../../stores/cache' +import AsyncImage from '../../components/AsyncImage.vue' const conversationStore = useConversationStore(); const router = useRouter(); const browserNotification = useBrowserNotification(); +const message = useMessage() +const cacheStore = useCacheStore() const searchQuery = ref('') const activeId = ref(0) @@ -82,6 +90,25 @@ const addMenuList = [ } ]; + +const createGroupSubmitHandler = async (selectedUsers, groupName) => { + const res = await groupService.createGroup({ + name: groupName, + avatar: "http://192.168.5.116:7070/uploads/files/IM/2026/03/2/bf1a0f691220.jpg", + userIDs: [...selectedUsers] +}) + +if(res.code == SYSTEM_BASE_STATUS.SUCCESS){ + message.success('群聊创建成功') +}else{ + message.error(res.message) +} +} + +const urlHandler = async () => { + +} + const filteredSessions = computed(() => conversationStore.sortedConversations.filter(s => s.targetName.includes(searchQuery.value))) function selectSession(s) { @@ -272,7 +299,7 @@ onMounted(async () => { } /* 头像样式统一 */ -.avatar-std { width: 40px; height: 40px; border-radius: 4px; object-fit: cover; } +:deep(.avatar-std) { width: 40px; height: 40px; border-radius: 4px; object-fit: cover; } .avatar-chat { width: 38px; height: 38px; border-radius: 4px; object-fit: cover; flex-shrink: 0; } /* 未读气泡 */ diff --git a/frontend/pc/IM/src/renderer/src/views/messages/messageContent/MessageContent.vue b/frontend/pc/IM/src/renderer/src/views/messages/messageContent/MessageContent.vue index 7e5c158..b02a7e5 100644 --- a/frontend/pc/IM/src/renderer/src/views/messages/messageContent/MessageContent.vue +++ b/frontend/pc/IM/src/renderer/src/views/messages/messageContent/MessageContent.vue @@ -18,29 +18,19 @@ @retry="loadHistoryMsg" /> - - -
-
-
- 正在播放视频 - -
- -
- -
-
- -
-
-
+
- + +
{{ @@ -50,8 +40,11 @@
{{ m.content }}
{{ m.content }}
- 图片消息 + +
@@ -89,7 +82,8 @@
-
- +
+

账号管理

+
+
+ 退出账号 +
+ +
+

存储与缓存

@@ -80,9 +90,13 @@