Browse Source

完善IM项目;修改一些不合理的代码

pull/1/head
cKey 6 years ago
parent
commit
8a49331b43
  1. 14
      README.en.md
  2. 14
      README.md
  3. 494
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200602134027_Add-Chat-Message-Entites.Designer.cs
  4. 281
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200602134027_Add-Chat-Message-Entites.cs
  5. 368
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
  6. 10
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs
  7. 72
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs
  8. 2
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN.Abp.IM.csproj
  9. 26
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/Group.cs
  10. 8
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupChat.cs
  11. 4
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs
  12. 2
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/UserGroup.cs
  13. 18
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs
  14. 5
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs
  15. 4
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendState.cs
  16. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs
  17. 3
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json
  18. 3
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json
  19. 9
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs
  20. 30
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/MessageServiceErrorCodes.cs
  21. 15
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Messages/ChatGroupConsts.cs
  22. 10
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Messages/MessageConsts.cs
  23. 0
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs
  24. 0
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs
  25. 11
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN.Abp.MessageService.Domain.csproj
  26. 48
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/UserCreateEventHandler.cs
  27. 11
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json
  28. 11
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json
  29. 26
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs
  30. 76
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatGroup.cs
  31. 69
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatGroupAdmin.cs
  32. 30
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatMessage.cs
  33. 32
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/GroupChatBlack.cs
  34. 24
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/GroupMessage.cs
  35. 22
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IGroupRepository.cs
  36. 24
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IMessageRepository.cs
  37. 25
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IUserChatGroupRepository.cs
  38. 20
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IUserChatSettingRepository.cs
  39. 50
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/Message.cs
  40. 132
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/MessageStore.cs
  41. 32
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatBlack.cs
  42. 27
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatGroup.cs
  43. 54
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatSetting.cs
  44. 86
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserGroupStore.cs
  45. 25
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserMessage.cs
  46. 32
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserSpecialFocus.cs
  47. 7
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs
  48. 102
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
  49. 43
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs
  50. 114
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs
  51. 86
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs
  52. 39
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatSettingRepository.cs
  53. 6
      aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs
  54. BIN
      vueJs/images/aggregate.png
  55. BIN
      vueJs/images/client.png
  56. BIN
      vueJs/images/im-notifications.png
  57. BIN
      vueJs/images/tenant.png
  58. 3
      vueJs/src/components/TenantBox/index.vue

14
README.en.md

@ -41,7 +41,19 @@ If you want to get started with a minimal template code instead of integration s
## Screenshots ## Screenshots
![dashboard](./demo/dashboard.png) ![Login](./vueJs/images/userLogin.png)
![Tenants](./vueJs/images/tenant.png)
![Roles](./vueJs/images/userRoles.png)
![Permissions](./vueJs/images/userPermissions.png)
![IM](./vueJs/images/im-notifications.png)
![Clients](./vueJs/images/client.png)
![Aggregate route](./vueJs/images/aggregate.png)
## Related Projects ## Related Projects

14
README.md

@ -19,11 +19,19 @@
## 截图 ## 截图
![登录页](./images/userLogin.png) ![登录页](./vueJs/images/userLogin.png)
![角色页](./images/userRoles.png) ![租户管理](./vueJs/images/tenant.png)
![权限页](./images/userPermissions.png) ![角色页](./vueJs/images/userRoles.png)
![权限页](./vueJs/images/userPermissions.png)
![即时通讯](./vueJs/images/im-notifications.png)
![客户端管理](./vueJs/images/client.png)
![聚合路由](./vueJs/images/aggregate.png)
## 相关项目 ## 相关项目

494
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200602134027_Add-Chat-Message-Entites.Designer.cs

@ -0,0 +1,494 @@
// <auto-generated />
using System;
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace LINGYUN.Abp.MessageService.Migrations
{
[DbContext(typeof(MessageServiceHostMigrationsDbContext))]
[Migration("20200602134027_Add-Chat-Message-Entites")]
partial class AddChatMessageEntites
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.3")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasColumnType("varchar(256) CHARACTER SET utf8mb4")
.HasMaxLength(256);
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<string>("Description")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(20) CHARACTER SET utf8mb4")
.HasMaxLength(20);
b.Property<string>("Notice")
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<string>("Tag")
.HasColumnType("varchar(512) CHARACTER SET utf8mb4")
.HasMaxLength(512);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroupAdmin", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowDissolveGroup")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowKickPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendNotice")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSilence")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<bool>("IsSuperAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppChatGroupAdmins");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("FocusUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserSpecialFocuss");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("NotificationData")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasColumnType("varchar(512) CHARACTER SET utf8mb4")
.HasMaxLength(512);
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationId")
.HasName("IX_Tenant_User_Notification_Id");
b.ToTable("AppUserNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<string>("NotificationName")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
.IsUnique()
.HasName("IX_Tenant_User_Notification_Name");
b.ToTable("AppUserSubscribes");
});
#pragma warning restore 612, 618
}
}
}

281
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200602134027_Add-Chat-Message-Entites.cs

@ -0,0 +1,281 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Abp.MessageService.Migrations
{
public partial class AddChatMessageEntites : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "ReadStatus",
table: "AppUserNotifications",
nullable: false,
oldClrType: typeof(sbyte),
oldType: "tinyint");
migrationBuilder.CreateTable(
name: "AppChatGroupAdmins",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
GroupId = table.Column<long>(nullable: false),
UserId = table.Column<Guid>(nullable: false),
IsSuperAdmin = table.Column<bool>(nullable: false),
AllowSilence = table.Column<bool>(nullable: false),
AllowKickPeople = table.Column<bool>(nullable: false),
AllowAddPeople = table.Column<bool>(nullable: false),
AllowSendNotice = table.Column<bool>(nullable: false),
AllowDissolveGroup = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppChatGroupAdmins", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppChatGroups",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
GroupId = table.Column<long>(nullable: false),
Name = table.Column<string>(maxLength: 20, nullable: false),
Tag = table.Column<string>(maxLength: 512, nullable: true),
Address = table.Column<string>(maxLength: 256, nullable: true),
Notice = table.Column<string>(maxLength: 64, nullable: true),
MaxUserCount = table.Column<int>(nullable: false),
AllowAnonymous = table.Column<bool>(nullable: false),
AllowSendMessage = table.Column<bool>(nullable: false),
Description = table.Column<string>(maxLength: 128, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AppChatGroups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppGroupChatBlacks",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
GroupId = table.Column<long>(nullable: false),
ShieldUserId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppGroupChatBlacks", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppGroupMessages",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
MessageId = table.Column<long>(nullable: false),
SendUserName = table.Column<string>(maxLength: 64, nullable: false),
Content = table.Column<string>(maxLength: 1048576, nullable: false),
Type = table.Column<int>(nullable: false),
SendState = table.Column<sbyte>(nullable: false),
GroupId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppGroupMessages", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUserChatBlacks",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
ShieldUserId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUserChatBlacks", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUserChatGroups",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
GroupId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUserChatGroups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUserChatSettings",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
AllowAnonymous = table.Column<bool>(nullable: false),
AllowAddFriend = table.Column<bool>(nullable: false),
RequireAddFriendValition = table.Column<bool>(nullable: false),
AllowReceiveMessage = table.Column<bool>(nullable: false),
AllowSendMessage = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUserChatSettings", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUserMessages",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
MessageId = table.Column<long>(nullable: false),
SendUserName = table.Column<string>(maxLength: 64, nullable: false),
Content = table.Column<string>(maxLength: 1048576, nullable: false),
Type = table.Column<int>(nullable: false),
SendState = table.Column<sbyte>(nullable: false),
ReceiveUserId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUserMessages", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUserSpecialFocuss",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
FocusUserId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUserSpecialFocuss", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_AppChatGroupAdmins_TenantId_GroupId",
table: "AppChatGroupAdmins",
columns: new[] { "TenantId", "GroupId" });
migrationBuilder.CreateIndex(
name: "IX_AppChatGroups_TenantId_Name",
table: "AppChatGroups",
columns: new[] { "TenantId", "Name" });
migrationBuilder.CreateIndex(
name: "IX_AppGroupChatBlacks_TenantId_GroupId",
table: "AppGroupChatBlacks",
columns: new[] { "TenantId", "GroupId" });
migrationBuilder.CreateIndex(
name: "IX_AppGroupMessages_TenantId_GroupId",
table: "AppGroupMessages",
columns: new[] { "TenantId", "GroupId" });
migrationBuilder.CreateIndex(
name: "IX_AppUserChatBlacks_TenantId_UserId",
table: "AppUserChatBlacks",
columns: new[] { "TenantId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AppUserChatGroups_TenantId_GroupId_UserId",
table: "AppUserChatGroups",
columns: new[] { "TenantId", "GroupId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AppUserChatSettings_TenantId_UserId",
table: "AppUserChatSettings",
columns: new[] { "TenantId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AppUserMessages_TenantId_ReceiveUserId",
table: "AppUserMessages",
columns: new[] { "TenantId", "ReceiveUserId" });
migrationBuilder.CreateIndex(
name: "IX_AppUserSpecialFocuss_TenantId_UserId",
table: "AppUserSpecialFocuss",
columns: new[] { "TenantId", "UserId" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppChatGroupAdmins");
migrationBuilder.DropTable(
name: "AppChatGroups");
migrationBuilder.DropTable(
name: "AppGroupChatBlacks");
migrationBuilder.DropTable(
name: "AppGroupMessages");
migrationBuilder.DropTable(
name: "AppUserChatBlacks");
migrationBuilder.DropTable(
name: "AppUserChatGroups");
migrationBuilder.DropTable(
name: "AppUserChatSettings");
migrationBuilder.DropTable(
name: "AppUserMessages");
migrationBuilder.DropTable(
name: "AppUserSpecialFocuss");
migrationBuilder.AlterColumn<sbyte>(
name: "ReadStatus",
table: "AppUserNotifications",
type: "tinyint",
nullable: false,
oldClrType: typeof(int));
}
}
}

368
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs

@ -17,6 +17,370 @@ namespace LINGYUN.Abp.MessageService.Migrations
.HasAnnotation("ProductVersion", "3.1.3") .HasAnnotation("ProductVersion", "3.1.3")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasColumnType("varchar(256) CHARACTER SET utf8mb4")
.HasMaxLength(256);
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<string>("Description")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("char(36)");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(20) CHARACTER SET utf8mb4")
.HasMaxLength(20);
b.Property<string>("Notice")
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<string>("Tag")
.HasColumnType("varchar(512) CHARACTER SET utf8mb4")
.HasMaxLength(512);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroupAdmin", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowDissolveGroup")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowKickPeople")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendNotice")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSilence")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<bool>("IsSuperAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppChatGroupAdmins");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(1048576);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasColumnType("varchar(64) CHARACTER SET utf8mb4")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)");
b.Property<Guid>("FocusUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserSpecialFocuss");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b => modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{ {
b.Property<long>("Id") b.Property<long>("Id")
@ -74,8 +438,8 @@ namespace LINGYUN.Abp.MessageService.Migrations
b.Property<long>("NotificationId") b.Property<long>("NotificationId")
.HasColumnType("bigint"); .HasColumnType("bigint");
b.Property<sbyte>("ReadStatus") b.Property<int>("ReadStatus")
.HasColumnType("tinyint"); .HasColumnType("int");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnName("TenantId") .HasColumnName("TenantId")

10
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs

@ -30,14 +30,14 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
// 持久化 // 持久化
await _messageStore.StoreMessageAsync(chatMessage); await _messageStore.StoreMessageAsync(chatMessage);
if (!chatMessage.GroupName.IsNullOrWhiteSpace()) if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{ {
try try
{ {
var signalRClient = Clients.Group(chatMessage.GroupName); var signalRClient = Clients.Group(chatMessage.GroupId);
if (signalRClient == null) if (signalRClient == null)
{ {
Logger.LogDebug("Can not get group " + chatMessage.GroupName + " from SignalR hub!"); Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!");
return; return;
} }
@ -45,13 +45,13 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogWarning("Could not send message to group: {0}", chatMessage.GroupName); Logger.LogWarning("Could not send message to group: {0}", chatMessage.GroupId);
Logger.LogWarning("Send group message error: {0}", ex.Message); Logger.LogWarning("Send group message error: {0}", ex.Message);
} }
} }
else else
{ {
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId); var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.GetValueOrDefault());
var onlineClients = OnlineClientManager.GetAllByContext(onlineClientContext); var onlineClients = OnlineClientManager.GetAllByContext(onlineClientContext);
foreach (var onlineClient in onlineClients) foreach (var onlineClient in onlineClients)
{ {

72
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs

@ -41,47 +41,59 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
// 持久化 // 持久化
await _messageStore.StoreMessageAsync(chatMessage); await _messageStore.StoreMessageAsync(chatMessage);
if (!chatMessage.GroupName.IsNullOrWhiteSpace()) try
{
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(chatMessage);
}
else
{
await SendMessageToUserAsync(chatMessage);
}
}
catch (Exception ex)
{
Logger.LogWarning("Could not send message, group: {0}, formUser: {1}, toUser: {2}",
chatMessage.GroupId, chatMessage.FormUserName,
chatMessage.ToUserId.HasValue ? chatMessage.ToUserId.ToString() : "None");
Logger.LogWarning("Send group message error: {0}", ex.Message);
}
}
protected virtual async Task SendMessageToGroupAsync(ChatMessage chatMessage)
{
var signalRClient = _hubContext.Clients.Group(chatMessage.GroupId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!");
return;
}
await signalRClient.SendAsync("getChatMessage", chatMessage);
}
protected virtual async Task SendMessageToUserAsync(ChatMessage chatMessage)
{
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.Value);
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
foreach (var onlineClient in onlineClients)
{ {
try try
{ {
var signalRClient = _hubContext.Clients.Group(chatMessage.GroupName); var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
if (signalRClient == null) if (signalRClient == null)
{ {
Logger.LogDebug("Can not get group " + chatMessage.GroupName + " from SignalR hub!"); Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
return; continue;
} }
await signalRClient.SendAsync("getChatMessage", chatMessage); await signalRClient.SendAsync("getChatMessage", chatMessage);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogWarning("Could not send message to group: {0}", chatMessage.GroupName); Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId);
Logger.LogWarning("Send group message error: {0}", ex.Message); Logger.LogWarning("Send to user message error: {0}", ex.Message);
}
}
else
{
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId);
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
foreach (var onlineClient in onlineClients)
{
try
{
var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue;
}
await signalRClient.SendAsync("getChatMessage", chatMessage);
}
catch (Exception ex)
{
Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId);
Logger.LogWarning("Send to user message error: {0}", ex.Message);
}
} }
} }
} }

2
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN.Abp.IM.csproj

@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="2.8.0" /> <PackageReference Include="Volo.Abp.Auditing" Version="2.8.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

26
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/Group.cs

@ -0,0 +1,26 @@
namespace LINGYUN.Abp.IM.Group
{
public class Group
{
/// <summary>
/// 群组名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 允许匿名聊天
/// </summary>
public bool AllowAnonymous { get; set; }
/// <summary>
/// 允许发送消息
/// </summary>
public bool AllowSendMessage { get; set; }
/// <summary>
/// 最大用户数
/// </summary>
public int MaxUserLength { get; set; }
/// <summary>
/// 群组用户数
/// </summary>
public int GroupUserCount { get; set; }
}
}

8
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupChat.cs

@ -1,8 +0,0 @@
namespace LINGYUN.Abp.IM.Group
{
public class GroupChat
{
public string Name { get; set; }
public int MaxUserLength { get; set; }
}
}

4
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs

@ -12,7 +12,7 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<GroupChat>> GetUserGroupsAsync(Guid? tenantId, Guid userId); Task<IEnumerable<Group>> GetUserGroupsAsync(Guid? tenantId, Guid userId);
/// <summary> /// <summary>
/// 获取通讯组所有用户 /// 获取通讯组所有用户
/// </summary> /// </summary>
@ -27,7 +27,7 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
Task AddUserToGroupAsync(Guid? tenantId, Guid userId, long groupId); Task AddUserToGroupAsync(Guid? tenantId, Guid userId, long groupId, Guid acceptUserId);
/// <summary> /// <summary>
/// 用户退出通讯组 /// 用户退出通讯组
/// </summary> /// </summary>

2
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/UserGroup.cs

@ -7,5 +7,7 @@ namespace LINGYUN.Abp.IM.Group
public Guid? TenantId { get; set; } public Guid? TenantId { get; set; }
public Guid UserId { get; set; } public Guid UserId { get; set; }
public long GroupId { get; set; } public long GroupId { get; set; }
public bool IsAdmin { get; set; }
public bool IsSuperAdmin { get; set; }
} }
} }

18
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs

@ -1,15 +1,29 @@
using System; using System;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.IM.Messages namespace LINGYUN.Abp.IM.Messages
{ {
public class ChatMessage public class ChatMessage
{ {
public Guid? TenantId { get; set; } public Guid? TenantId { get; set; }
public string GroupName { get; set; }
public string GroupId { get; set; }
public string MessageId { get; set; }
public Guid FormUserId { get; set; } public Guid FormUserId { get; set; }
public Guid ToUserId { get; set; }
public string FormUserName { get; set; }
public Guid? ToUserId { get; set; }
[DisableAuditing]
public string Content { get; set; } public string Content { get; set; }
public DateTime SendTime { get; set; } public DateTime SendTime { get; set; }
public bool IsAnonymous { get; set; } = false;
public MessageType MessageType { get; set; } = MessageType.Text; public MessageType MessageType { get; set; } = MessageType.Text;
} }
} }

5
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs

@ -21,7 +21,7 @@ namespace LINGYUN.Abp.IM.Messages
/// <param name="groupName"></param> /// <param name="groupName"></param>
/// <param name="maxResultCount"></param> /// <param name="maxResultCount"></param>
/// <returns></returns> /// <returns></returns>
Task<List<ChatMessage>> GetGroupMessageAsync(Guid tenantId, string groupName, int maxResultCount = 10); Task<List<ChatMessage>> GetGroupMessageAsync(Guid? tenantId, long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10);
/// <summary> /// <summary>
/// 获取与某个用户的聊天记录 /// 获取与某个用户的聊天记录
/// </summary> /// </summary>
@ -29,6 +29,7 @@ namespace LINGYUN.Abp.IM.Messages
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="maxResultCount"></param> /// <param name="maxResultCount"></param>
/// <returns></returns> /// <returns></returns>
Task<List<ChatMessage>> GetChatMessageAsync(Guid tenantId, Guid userId, int maxResultCount = 10); Task<List<ChatMessage>> GetChatMessageAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10);
} }
} }

4
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/SendStatus.cs → aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendState.cs

@ -1,9 +1,9 @@
namespace LINGYUN.Abp.MessageService namespace LINGYUN.Abp.IM.Messages
{ {
/// <summary> /// <summary>
/// 消息状态 /// 消息状态
/// </summary> /// </summary>
public enum SendStatus : sbyte public enum MessageSendState : sbyte
{ {
/// <summary> /// <summary>
/// 已发送 /// 已发送

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs

@ -18,6 +18,8 @@ namespace LINGYUN.Abp.Notifications
Data = new NotificationData(); Data = new NotificationData();
NotificationType = NotificationType.Application; NotificationType = NotificationType.Application;
NotificationSeverity = NotificationSeverity.Info; NotificationSeverity = NotificationSeverity.Info;
CreationTime = DateTime.Now;
} }
} }
} }

3
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json

@ -25,6 +25,7 @@
"ClientClaimNotFound": "Client claim: {0} not found!", "ClientClaimNotFound": "Client claim: {0} not found!",
"ClientSecretNotFound": "Client secret: {0} not found!", "ClientSecretNotFound": "Client secret: {0} not found!",
"ClientPropertyNotFound": "Client property: {0} not found!", "ClientPropertyNotFound": "Client property: {0} not found!",
"IdentityResourcePropertyNotFound": "Identity resource property: {0} not found!" "IdentityResourcePropertyNotFound": "Identity resource property: {0} not found!",
"EncryptionNotImplemented": "Encryption type: {0} not implemented!"
} }
} }

3
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json

@ -25,6 +25,7 @@
"ClientClaimNotFound": "客户端声明: {0} 不存在!", "ClientClaimNotFound": "客户端声明: {0} 不存在!",
"ClientSecretNotFound": "客户端密钥: {0} 不存在!", "ClientSecretNotFound": "客户端密钥: {0} 不存在!",
"ClientPropertyNotFound": "客户端属性: {0} 不存在!", "ClientPropertyNotFound": "客户端属性: {0} 不存在!",
"IdentityResourcePropertyNotFound": "身份资源属性: {0} 不存在!" "IdentityResourcePropertyNotFound": "身份资源属性: {0} 不存在!",
"EncryptionNotImplemented": "加密类型: {0} 未实现!"
} }
} }

9
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.IdentityServer.Clients; using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.Security.Encryption;
using Client = Volo.Abp.IdentityServer.Clients.Client; using Client = Volo.Abp.IdentityServer.Clients.Client;
namespace LINGYUN.Abp.IdentityServer.Clients namespace LINGYUN.Abp.IdentityServer.Clients
@ -15,9 +14,6 @@ namespace LINGYUN.Abp.IdentityServer.Clients
[Authorize(AbpIdentityServerPermissions.Clients.Default)] [Authorize(AbpIdentityServerPermissions.Clients.Default)]
public class ClientAppService : AbpIdentityServerAppServiceBase, IClientAppService public class ClientAppService : AbpIdentityServerAppServiceBase, IClientAppService
{ {
private IStringEncryptionService _encryptionService;
protected IStringEncryptionService EncryptionService => LazyGetRequiredService(ref _encryptionService);
protected IClientRepository ClientRepository { get; } protected IClientRepository ClientRepository { get; }
public ClientAppService(IClientRepository clientRepository) public ClientAppService(IClientRepository clientRepository)
@ -69,7 +65,8 @@ namespace LINGYUN.Abp.IdentityServer.Clients
} }
else else
{ {
clientSecretValue = EncryptionService.Encrypt(clientSecretCreate.Value); // 其他类型的服务器加密方式暂时不提供
throw new UserFriendlyException(L["EncryptionNotImplemented", clientSecretCreate.Type]);
} }
client.AddSecret(clientSecretValue, clientSecretCreate.Expiration, client.AddSecret(clientSecretValue, clientSecretCreate.Expiration,
clientSecretCreate.Type, clientSecretCreate.Description); clientSecretCreate.Type, clientSecretCreate.Description);
@ -461,7 +458,7 @@ namespace LINGYUN.Abp.IdentityServer.Clients
} }
else else
{ {
clientSecretValue = EncryptionService.Encrypt(clientSecretUpdate.Value); throw new UserFriendlyException(L["EncryptionNotImplemented", clientSecretUpdate.Type]);
} }
clientSecret.Value = clientSecretValue; clientSecret.Value = clientSecretValue;

30
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/MessageServiceErrorCodes.cs

@ -0,0 +1,30 @@
namespace LINGYUN.Abp.MessageService
{
public class MessageServiceErrorCodes
{
/// <summary>
/// 管理员已开启全员禁言
/// </summary>
public const string GroupNotAllowedToSpeak = "Messages:Group:1001";
/// <summary>
/// 管理员不允许匿名发言
/// </summary>
public const string GroupNotAllowedToSpeakAnonymously = "Messages:Group:1002";
/// <summary>
/// 管理员已禁止用户发言
/// </summary>
public const string GroupUserHasBlack = "Messages:Group:1003";
/// <summary>
/// 用户已将发信人拉黑
/// </summary>
public const string UserHasBlack = "Messages:User:1003";
/// <summary>
/// 用户已拒接所有消息
/// </summary>
public const string UserHasRejectAllMessage = "Messages:User:1001";
/// <summary>
/// 用户不允许匿名发言
/// </summary>
public const string UserNotAllowedToSpeakAnonymously = "Messages:User:1002";
}
}

15
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Messages/ChatGroupConsts.cs

@ -0,0 +1,15 @@
namespace LINGYUN.Abp.MessageService.Messages
{
public class ChatGroupConsts
{
public const int MaxNameLength = 20;
public const int MaxTagLength = 512;
public const int MaxAddressLength = 256;
public const int MaxNoticeLength = 64;
public const int MaxDescriptionLength = 128;
}
}

10
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Messages/MessageConsts.cs

@ -0,0 +1,10 @@
namespace LINGYUN.Abp.MessageService.Messages
{
public class MessageConsts
{
public const int MaxSendUserNameLength = 64;
// 1 MB
public const int MaxContentLength = 1024 * 1024;
}
}

0
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs → aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Notifications/NotificationConsts.cs

0
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs → aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs

11
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN.Abp.MessageService.Domain.csproj

@ -5,10 +5,21 @@
<RootNamespace /> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\MessageService\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="2.8.0" /> <PackageReference Include="Volo.Abp.Ddd.Domain" Version="2.8.0" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="2.8.0" /> <PackageReference Include="Volo.Abp.AutoMapper" Version="2.8.0" />
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.8.0" /> <PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.8.0" />
<PackageReference Include="Volo.Abp.Users.Abstractions" Version="2.8.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

48
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/UserCreateEventHandler.cs

@ -0,0 +1,48 @@
using LINGYUN.Abp.MessageService.Messages;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus
{
public class UserCreateEventHandler : IDistributedEventHandler<EntityCreatedEto<UserEto>>
{
private readonly ICurrentTenant _currentTenant;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IUserChatSettingRepository _userChatSettingRepository;
public UserCreateEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IUserChatSettingRepository userChatSettingRepository)
{
_currentTenant = currentTenant;
_unitOfWorkManager = unitOfWorkManager;
_userChatSettingRepository = userChatSettingRepository;
}
/// <summary>
/// 接收添加用户事件,启用IM模块时增加用户配置
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
public async Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
using (var unitOfWork = _unitOfWorkManager.Begin())
{
using (_currentTenant.Change(eventData.Entity.TenantId))
{
var userHasOpendIm = await _userChatSettingRepository.UserHasOpendImAsync(eventData.Entity.Id);
if (!userHasOpendIm)
{
var userChatSetting = new UserChatSetting(eventData.Entity.Id, eventData.Entity.TenantId);
await _userChatSettingRepository.InsertAsync(userChatSetting);
await unitOfWork.SaveChangesAsync();
}
}
}
}
}
}

11
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json

@ -0,0 +1,11 @@
{
"culture": "en",
"texts": {
"Messages:Group:1001": "The current group is not allowed to speak",
"Messages:Group:1002": "The current group is not allowed to speak anonymously",
"Messages:Group:1003": "The administrator has banned you from speaking!",
"Messages:User:1001": "Users do not receive anonymous comments!",
"Messages:User:1002": "The user has rejected all messages!",
"Messages:User:1003": "The user rejects the message you sent!"
}
}

11
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json

@ -0,0 +1,11 @@
{
"culture": "zh-Hans",
"texts": {
"Messages:Group:1001": "管理员已开启全员禁言!",
"Messages:Group:1002": "管理员不允许匿名发言!",
"Messages:Group:1003": "管理员已禁止您发言!",
"Messages:User:1001": "用户不接收匿名发言!",
"Messages:User:1002": "用户已拒接所有消息!",
"Messages:User:1003": "用户拒绝您发送的消息!"
}
}

26
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs

@ -1,11 +1,11 @@
using AutoMapper; using AutoMapper;
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.MessageService.Messages;
using LINGYUN.Abp.MessageService.Notifications; using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.MessageService.Subscriptions; using LINGYUN.Abp.MessageService.Subscriptions;
using LINGYUN.Abp.Notifications; using LINGYUN.Abp.Notifications;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.MessageService.Mapper namespace LINGYUN.Abp.MessageService.Mapper
{ {
@ -30,6 +30,28 @@ namespace LINGYUN.Abp.MessageService.Mapper
})); }));
CreateMap<UserSubscribe, NotificationSubscriptionInfo>(); CreateMap<UserSubscribe, NotificationSubscriptionInfo>();
CreateMap<GroupMessage, ChatMessage>()
.ForMember(dto => dto.Content, map => map.MapFrom(src => src.Content))
.ForMember(dto => dto.GroupId, map => map.MapFrom(src => src.GroupId.ToString()))
.ForMember(dto => dto.MessageId, map => map.MapFrom(src => src.MessageId.ToString()))
.ForMember(dto => dto.FormUserId, map => map.MapFrom(src => src.CreatorId))
.ForMember(dto => dto.FormUserName, map => map.MapFrom(src => src.SendUserName))
.ForMember(dto => dto.SendTime, map => map.MapFrom(src => src.CreationTime))
.ForMember(dto => dto.MessageType, map => map.MapFrom(src => src.Type))
.ForMember(dto => dto.IsAnonymous, map => map.Ignore())
.ForMember(dto => dto.ToUserId, map => map.Ignore());
CreateMap<UserMessage, ChatMessage>()
.ForMember(dto => dto.Content, map => map.MapFrom(src => src.Content))
.ForMember(dto => dto.ToUserId, map => map.MapFrom(src => src.ReceiveUserId))
.ForMember(dto => dto.MessageId, map => map.MapFrom(src => src.MessageId.ToString()))
.ForMember(dto => dto.FormUserId, map => map.MapFrom(src => src.CreatorId))
.ForMember(dto => dto.FormUserName, map => map.MapFrom(src => src.SendUserName))
.ForMember(dto => dto.SendTime, map => map.MapFrom(src => src.CreationTime))
.ForMember(dto => dto.MessageType, map => map.MapFrom(src => src.Type))
.ForMember(dto => dto.IsAnonymous, map => map.Ignore())
.ForMember(dto => dto.GroupId, map => map.Ignore());
} }
} }
} }

76
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatGroup.cs

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 聊天群组
/// </summary>
public class ChatGroup : AuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 群组标识
/// </summary>
public virtual long GroupId { get; protected set; }
/// <summary>
/// 群组名称
/// </summary>
public virtual string Name { get; protected set; }
/// <summary>
/// 群组标记
/// </summary>
public virtual string Tag { get; protected set; }
/// <summary>
/// 群组地址
/// </summary>
public virtual string Address { get; protected set; }
/// <summary>
/// 群组公告
/// </summary>
public virtual string Notice { get; protected set; }
/// <summary>
/// 最大用户数量
/// </summary>
public virtual int MaxUserCount { get; protected set; }
/// <summary>
/// 允许匿名聊天
/// </summary>
public virtual bool AllowAnonymous { get; set; }
/// <summary>
/// 允许发送消息
/// </summary>
public virtual bool AllowSendMessage { get; set; }
/// <summary>
/// 群组说明
/// </summary>
public virtual string Description { get; set; }
protected ChatGroup()
{
}
public ChatGroup(long id, string name, string tag = "", string address = "", int maxUserCount = 200)
{
GroupId = id;
Name = name;
Tag = tag;
Address = address;
MaxUserCount = maxUserCount;
}
public void ChangeAddress(string address)
{
Address = address;
}
public void SetNotice(string notice)
{
Notice = notice;
}
}
}

69
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatGroupAdmin.cs

@ -0,0 +1,69 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 群管理员
/// </summary>
public class ChatGroupAdmin : AuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 群组标识
/// </summary>
public virtual long GroupId { get; protected set; }
/// <summary>
/// 管理员用户
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 是否群主
/// </summary>
public virtual bool IsSuperAdmin { get; protected set; }
/// <summary>
/// 允许禁言
/// </summary>
public virtual bool AllowSilence { get; set; }
/// <summary>
/// 允许踢人
/// </summary>
public virtual bool AllowKickPeople { get; set; }
/// <summary>
/// 允许加人
/// </summary>
public virtual bool AllowAddPeople { get; set; }
/// <summary>
/// 允许发送群公告
/// </summary>
public virtual bool AllowSendNotice { get; set; }
/// <summary>
/// 允许解散群组
/// </summary>
public virtual bool AllowDissolveGroup { get; set; }
protected ChatGroupAdmin() { }
public ChatGroupAdmin(long groupId, Guid userId, bool isSuperAdmin = false)
{
GroupId = groupId;
UserId = userId;
AllowSilence = true;
AllowKickPeople = true;
AllowAddPeople = true;
AllowSendNotice = true;
SetSuperAdmin(isSuperAdmin);
}
public void SetSuperAdmin(bool isSuperAdmin = false)
{
IsSuperAdmin = isSuperAdmin;
if (isSuperAdmin)
{
AllowDissolveGroup = true;
}
}
}
}

30
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/ChatMessage.cs

@ -1,30 +0,0 @@
using System;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
public abstract class ChatMessage : Entity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 发送用户标识
/// </summary>
public virtual Guid SendUserId { get; protected set; }
/// <summary>
/// 接收用户标识
/// </summary>
public virtual Guid ReceiveUserId { get; set; }
/// <summary>
/// 内容
/// </summary>
public virtual string Content { get; protected set; }
/// <summary>
/// 发送状态
/// </summary>
public virtual SendStatus SendStatus { get; protected set; }
}
}

32
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/GroupChatBlack.cs

@ -0,0 +1,32 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 用户黑名单
/// </summary>
public class GroupChatBlack : CreationAuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 群组标识
/// </summary>
public virtual long GroupId { get; protected set; }
/// <summary>
/// 拉黑的用户
/// </summary>
public virtual Guid ShieldUserId { get; protected set; }
protected GroupChatBlack() { }
public GroupChatBlack(long groupId, Guid shieldUserId, Guid? tenantId)
{
GroupId = groupId;
ShieldUserId = shieldUserId;
TenantId = tenantId;
}
}
}

24
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/GroupMessage.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.IM.Messages;
using System;
namespace LINGYUN.Abp.MessageService.Messages
{
public class GroupMessage : Message
{
/// <summary>
/// 群组标识
/// </summary>
public virtual long GroupId { get; protected set; }
protected GroupMessage() { }
public GroupMessage(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
: base(id, sendUserId, sendUserName, content, type)
{
}
public void SendToGroup(long groupId)
{
GroupId = groupId;
}
}
}

22
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IGroupRepository.cs

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Abp.MessageService.Messages
{
public interface IGroupRepository : IBasicRepository<ChatGroup, long>
{
/// <summary>
/// 用户是否已被拉黑
/// </summary>
/// <param name="id"></param>
/// <param name="formUserId"></param>
/// <returns></returns>
Task<bool> UserHasBlackedAsync(long id, Guid formUserId);
Task<ChatGroup> GetByIdAsync(long id);
Task<List<ChatGroupAdmin>> GetGroupAdminAsync(long id);
}
}

24
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IMessageRepository.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.IM.Messages;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.MessageService.Messages
{
public interface IMessageRepository
{
Task<UserMessage> InsertUserMessageAsync(UserMessage userMessage, bool saveChangs = false);
Task<GroupMessage> InsertGroupMessageAsync(GroupMessage groupMessage, bool saveChangs = false);
Task<UserMessage> GetUserMessageAsync(long id);
Task<GroupMessage> GetGroupMessageAsync(long id);
Task<List<UserMessage>> GetUserMessagesAsync(Guid sendUserId, Guid receiveUserId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10);
Task<List<GroupMessage>> GetGroupMessagesAsync(long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10);
Task<List<GroupMessage>> GetUserGroupMessagesAsync(Guid sendUserId, long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10);
}
}

25
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IUserChatGroupRepository.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.IM.Group;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Abp.MessageService.Messages
{
public interface IUserChatGroupRepository : IBasicRepository<UserChatGroup, long>
{
/// <summary>
/// 用户是否在组里
/// </summary>
/// <param name="id"></param>
/// <param name="userId"></param>
/// <returns></returns>
Task<bool> UserHasInGroupAsync(long groupId, Guid userId);
Task<UserChatGroup> GetUserGroupAsync(long groupId, Guid userId);
Task<List<UserGroup>> GetGroupUsersAsync(long groupId);
Task<List<Group>> GetUserGroupsAsync(Guid userId);
}
}

20
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/IUserChatSettingRepository.cs

@ -0,0 +1,20 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Abp.MessageService.Messages
{
public interface IUserChatSettingRepository : IBasicRepository<UserChatSetting, long>
{
Task<bool> UserHasOpendImAsync(Guid userId);
/// <summary>
/// 用户是否已被拉黑
/// </summary>
/// <param name="formUserId"></param>
/// <param name="toUserId"></param>
/// <returns></returns>
Task<bool> UserHasBlackedAsync(Guid formUserId, Guid toUserId);
Task<UserChatSetting> GetByUserIdAsync(Guid userId);
}
}

50
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/Message.cs

@ -0,0 +1,50 @@
using LINGYUN.Abp.IM.Messages;
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
public abstract class Message : CreationAuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 消息标识
/// </summary>
public virtual long MessageId { get; protected set; }
/// <summary>
/// 发送用户名称
/// </summary>
public virtual string SendUserName { get; protected set; }
/// <summary>
/// 内容
/// </summary>
public virtual string Content { get; protected set; }
/// <summary>
/// 消息类型
/// </summary>
public virtual MessageType Type { get; protected set; }
/// <summary>
/// 发送状态
/// </summary>
public virtual MessageSendState SendState { get; protected set; }
protected Message() { }
public Message(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
{
MessageId = id;
CreatorId = sendUserId;
SendUserName = sendUserName;
Content = content;
Type = type;
CreationTime = DateTime.Now;
}
public void ChangeSendState(MessageSendState state = MessageSendState.Send)
{
SendState = state;
}
}
}

132
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/MessageStore.cs

@ -0,0 +1,132 @@
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.MessageService.Utils;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MessageService.Messages
{
public class MessageStore : DomainService, IMessageStore
{
private IObjectMapper _objectMapper;
protected IObjectMapper ObjectMapper => LazyGetRequiredService(ref _objectMapper);
private IUnitOfWorkManager _unitOfWorkManager;
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager);
protected IUserChatSettingRepository UserChatSettingRepository { get; }
protected IMessageRepository MessageRepository { get; }
protected IGroupRepository GroupRepository { get; }
protected ISnowflakeIdGenerator SnowflakeIdGenerator { get; }
public MessageStore(
IGroupRepository groupRepository,
IMessageRepository messageRepository,
ISnowflakeIdGenerator snowflakeIdGenerator,
IUserChatSettingRepository userChatSettingRepository)
{
GroupRepository = groupRepository;
MessageRepository = messageRepository;
SnowflakeIdGenerator = snowflakeIdGenerator;
UserChatSettingRepository = userChatSettingRepository;
}
[UnitOfWork]
public async Task StoreMessageAsync(ChatMessage chatMessage)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
using (CurrentTenant.Change(chatMessage.TenantId))
{
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
long groupId = long.Parse(chatMessage.GroupId);
await StoreGroupMessageAsync(chatMessage, groupId);
}
else
{
await StoreUserMessageAsync(chatMessage);
}
await unitOfWork.SaveChangesAsync();
}
}
}
public async Task<List<ChatMessage>> GetGroupMessageAsync(Guid? tenantId, long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10)
{
using (CurrentTenant.Change(tenantId))
{
var groupMessages = await MessageRepository.GetGroupMessagesAsync(groupId, filter, type, skipCount, maxResultCount);
var chatMessages = ObjectMapper.Map<List<GroupMessage>, List<ChatMessage>>(groupMessages);
return chatMessages;
}
}
public async Task<List<ChatMessage>> GetChatMessageAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10)
{
using (CurrentTenant.Change(tenantId))
{
var userMessages = await MessageRepository.GetUserMessagesAsync(sendUserId, receiveUserId, filter, type, skipCount, maxResultCount);
var chatMessages = ObjectMapper.Map<List<UserMessage>, List<ChatMessage>>(userMessages);
return chatMessages;
}
}
protected virtual async Task StoreUserMessageAsync(ChatMessage chatMessage)
{
var userHasBlacked = await UserChatSettingRepository
.UserHasBlackedAsync(chatMessage.ToUserId.Value, chatMessage.FormUserId);
if (userHasBlacked)
{
// 当前发送的用户已被拉黑
throw new BusinessException(MessageServiceErrorCodes.UserHasBlack);
}
var userChatSetting = await UserChatSettingRepository.GetByUserIdAsync(chatMessage.ToUserId.Value);
if (!userChatSetting.AllowReceiveMessage)
{
// 当前发送的用户不接收消息
throw new BusinessException(MessageServiceErrorCodes.UserHasRejectAllMessage);
}
if (chatMessage.IsAnonymous && !userChatSetting.AllowAnonymous)
{
// 当前用户不允许匿名发言
throw new BusinessException(MessageServiceErrorCodes.UserNotAllowedToSpeakAnonymously);
}
var messageId = SnowflakeIdGenerator.Create();
var message = new UserMessage(messageId, chatMessage.FormUserId, chatMessage.FormUserName, chatMessage.Content, chatMessage.MessageType);
message.SendToUser(chatMessage.ToUserId.Value);
await MessageRepository.InsertUserMessageAsync(message);
}
protected virtual async Task StoreGroupMessageAsync(ChatMessage chatMessage, long groupId)
{
var userHasBlacked = await GroupRepository
.UserHasBlackedAsync(groupId, chatMessage.FormUserId);
if (userHasBlacked)
{
// 当前发送的用户已被拉黑
throw new BusinessException(MessageServiceErrorCodes.GroupUserHasBlack);
}
var group = await GroupRepository.GetByIdAsync(groupId);
if (!group.AllowSendMessage)
{
// 当前群组不允许发言
throw new BusinessException(MessageServiceErrorCodes.GroupNotAllowedToSpeak);
}
if (chatMessage.IsAnonymous && !group.AllowAnonymous)
{
// 当前群组不允许匿名发言
throw new BusinessException(MessageServiceErrorCodes.GroupNotAllowedToSpeakAnonymously);
}
var messageId = SnowflakeIdGenerator.Create();
var message = new GroupMessage(messageId, chatMessage.FormUserId, chatMessage.FormUserName, chatMessage.Content, chatMessage.MessageType);
// TODO: 需要压测 高并发场景下的装箱性能影响
message.SendToGroup(groupId);
await MessageRepository.InsertGroupMessageAsync(message);
}
}
}

32
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatBlack.cs

@ -0,0 +1,32 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 用户黑名单
/// </summary>
public class UserChatBlack : CreationAuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 用户标识
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 拉黑的用户
/// </summary>
public virtual Guid ShieldUserId { get; protected set; }
protected UserChatBlack() { }
public UserChatBlack(Guid userId, Guid shieldUserId, Guid? tenantId)
{
UserId = userId;
ShieldUserId = shieldUserId;
TenantId = tenantId;
}
}
}

27
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatGroup.cs

@ -0,0 +1,27 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 用户群组
/// </summary>
public class UserChatGroup : CreationAuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
public virtual Guid UserId { get; protected set; }
public virtual long GroupId { get; protected set; }
protected UserChatGroup() { }
public UserChatGroup(long groupId, Guid userId, Guid acceptUserId, Guid? tenantId = null)
{
UserId = userId;
GroupId = groupId;
CreatorId = acceptUserId;
TenantId = tenantId;
}
}
}

54
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserChatSetting.cs

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
public class UserChatSetting : Entity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 用户标识
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 允许匿名聊天
/// </summary>
public virtual bool AllowAnonymous { get; set; }
/// <summary>
/// 允许添加好友
/// </summary>
public virtual bool AllowAddFriend { get; set; }
/// <summary>
/// 添加好友需要验证
/// </summary>
public virtual bool RequireAddFriendValition { get; set; }
/// <summary>
/// 允许接收消息
/// </summary>
public virtual bool AllowReceiveMessage { get; set; }
/// <summary>
/// 允许发送消息
/// </summary>
public virtual bool AllowSendMessage { get; set; }
protected UserChatSetting()
{
}
public UserChatSetting(Guid userId, Guid? tenantId)
: this()
{
UserId = userId;
TenantId = tenantId;
AllowAnonymous = false;
AllowAddFriend = true;
AllowReceiveMessage = true;
AllowSendMessage = true;
RequireAddFriendValition = true;
}
}
}

86
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserGroupStore.cs

@ -0,0 +1,86 @@
using LINGYUN.Abp.IM.Group;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MessageService.Messages
{
public class UserGroupStore : DomainService, IUserGroupStore
{
private IObjectMapper _objectMapper;
protected IObjectMapper ObjectMapper => LazyGetRequiredService(ref _objectMapper);
private IUnitOfWorkManager _unitOfWorkManager;
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager);
protected IUserChatGroupRepository UserChatGroupRepository { get; }
public UserGroupStore(
IUserChatGroupRepository userChatGroupRepository)
{
UserChatGroupRepository = userChatGroupRepository;
}
[UnitOfWork]
public async Task AddUserToGroupAsync(Guid? tenantId, Guid userId, long groupId, Guid acceptUserId)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
using (CurrentTenant.Change(tenantId))
{
var userHasInGroup = await UserChatGroupRepository.UserHasInGroupAsync(groupId, userId);
if (!userHasInGroup)
{
var userGroup = new UserChatGroup(groupId, userId, acceptUserId, tenantId);
await UserChatGroupRepository.InsertAsync(userGroup);
await unitOfWork.SaveChangesAsync();
}
}
}
}
public async Task<IEnumerable<UserGroup>> GetGroupUsersAsync(Guid? tenantId, long groupId)
{
using (CurrentTenant.Change(tenantId))
{
var userGroups = await UserChatGroupRepository.GetGroupUsersAsync(groupId);
return userGroups;
}
}
public async Task<IEnumerable<Group>> GetUserGroupsAsync(Guid? tenantId, Guid userId)
{
using (CurrentTenant.Change(tenantId))
{
var groups = await UserChatGroupRepository.GetUserGroupsAsync(userId);
return groups;
}
}
[UnitOfWork]
public async Task RemoveUserFormGroupAsync(Guid? tenantId, Guid userId, long groupId)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
using (CurrentTenant.Change(tenantId))
{
var userGroup = await UserChatGroupRepository.GetUserGroupAsync(groupId, userId);
if(userGroup != null)
{
await UserChatGroupRepository.DeleteAsync(userGroup);
await unitOfWork.SaveChangesAsync();
}
}
}
}
}
}

25
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserMessage.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.IM.Messages;
using System;
namespace LINGYUN.Abp.MessageService.Messages
{
public class UserMessage : Message
{
/// <summary>
/// 接收用户标识
/// </summary>
public virtual Guid ReceiveUserId { get; set; }
protected UserMessage() { }
public UserMessage(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
: base(id, sendUserId, sendUserName, content, type)
{
}
public void SendToUser(Guid receiveUserId)
{
ReceiveUserId = receiveUserId;
}
}
}

32
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Messages/UserSpecialFocus.cs

@ -0,0 +1,32 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Messages
{
/// <summary>
/// 用户特别关注
/// </summary>
public class UserSpecialFocus : CreationAuditedEntity<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 用户标识
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 关注的用户
/// </summary>
public virtual Guid FocusUserId { get; protected set; }
protected UserSpecialFocus() { }
public UserSpecialFocus(Guid userId, Guid focusUserId, Guid? tenantId)
{
UserId = userId;
FocusUserId = focusUserId;
TenantId = tenantId;
}
}
}

7
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.MessageService.Notifications; using LINGYUN.Abp.MessageService.Messages;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.MessageService.Subscriptions; using LINGYUN.Abp.MessageService.Subscriptions;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
@ -19,6 +20,10 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore
options.AddRepository<UserNotification, IUserNotificationRepository>(); options.AddRepository<UserNotification, IUserNotificationRepository>();
options.AddRepository<UserSubscribe, IUserSubscribeRepository>(); options.AddRepository<UserSubscribe, IUserSubscribeRepository>();
options.AddRepository<ChatGroup, IGroupRepository>();
options.AddRepository<UserChatGroup, IUserChatGroupRepository>();
options.AddRepository<UserChatSetting, IUserChatSettingRepository>();
options.AddDefaultRepositories(includeAllEntities: true); options.AddDefaultRepositories(includeAllEntities: true);
}); });
} }

102
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.MessageService.Notifications; using LINGYUN.Abp.MessageService.Messages;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.MessageService.Subscriptions; using LINGYUN.Abp.MessageService.Subscriptions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
@ -52,11 +53,108 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore
b.ConfigureCreationTime(); b.ConfigureCreationTime();
b.ConfigureMultiTenant(); b.ConfigureMultiTenant();
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.UserId, p.NotificationName }) b.HasIndex(p => new { p.TenantId, p.UserId, p.NotificationName })
.HasName("IX_Tenant_User_Notification_Name") .HasName("IX_Tenant_User_Notification_Name")
.IsUnique(); .IsUnique();
}); });
builder.Entity<UserMessage>(b =>
{
b.ToTable(options.TablePrefix + "UserMessages", options.Schema);
b.Property(p => p.SendUserName).HasMaxLength(MessageConsts.MaxSendUserNameLength).IsRequired();
b.Property(p => p.Content).HasMaxLength(MessageConsts.MaxContentLength).IsRequired();
b.ConfigureCreationTime();
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.ReceiveUserId });
});
builder.Entity<GroupMessage>(b =>
{
b.ToTable(options.TablePrefix + "GroupMessages", options.Schema);
b.Property(p => p.SendUserName).HasMaxLength(MessageConsts.MaxSendUserNameLength).IsRequired();
b.Property(p => p.Content).HasMaxLength(MessageConsts.MaxContentLength).IsRequired();
b.ConfigureCreationTime();
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.GroupId });
});
builder.Entity<UserChatSetting>(b =>
{
b.ToTable(options.TablePrefix + "UserChatSettings", options.Schema);
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.UserId });
});
builder.Entity<UserSpecialFocus>(b =>
{
b.ToTable(options.TablePrefix + "UserSpecialFocuss", options.Schema);
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.UserId });
});
builder.Entity<UserChatBlack>(b =>
{
b.ToTable(options.TablePrefix + "UserChatBlacks", options.Schema);
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.UserId });
});
builder.Entity<GroupChatBlack>(b =>
{
b.ToTable(options.TablePrefix + "GroupChatBlacks", options.Schema);
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.GroupId });
});
builder.Entity<ChatGroupAdmin>(b =>
{
b.ToTable(options.TablePrefix + "ChatGroupAdmins", options.Schema);
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.GroupId });
});
builder.Entity<ChatGroup>(b =>
{
b.ToTable(options.TablePrefix + "ChatGroups", options.Schema);
b.Property(p => p.Name).HasMaxLength(ChatGroupConsts.MaxNameLength).IsRequired();
b.Property(p => p.Tag).HasMaxLength(ChatGroupConsts.MaxTagLength);
b.Property(p => p.Notice).HasMaxLength(ChatGroupConsts.MaxNoticeLength);
b.Property(p => p.Address).HasMaxLength(ChatGroupConsts.MaxAddressLength);
b.Property(p => p.Description).HasMaxLength(ChatGroupConsts.MaxDescriptionLength);
b.ConfigureAudited();
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.Name });
});
builder.Entity<UserChatGroup>(b =>
{
b.ToTable(options.TablePrefix + "UserChatGroups", options.Schema);
b.ConfigureCreationAudited();
b.ConfigureMultiTenant();
b.HasIndex(p => new { p.TenantId, p.GroupId, p.UserId });
});
} }
} }
} }

43
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs

@ -0,0 +1,43 @@
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.MessageService.Messages
{
public class EfCoreGroupRepository : EfCoreRepository<MessageServiceDbContext, ChatGroup, long>,
IGroupRepository, ITransientDependency
{
public EfCoreGroupRepository(
IDbContextProvider<MessageServiceDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<ChatGroup> GetByIdAsync(long id)
{
return await DbSet.Where(x => x.GroupId.Equals(id)).FirstOrDefaultAsync();
}
public async Task<List<ChatGroupAdmin>> GetGroupAdminAsync(long id)
{
var groupAdmins = await (from gp in DbContext.Set<ChatGroup>()
join gpa in DbContext.Set<ChatGroupAdmin>()
on gp.GroupId equals gpa.GroupId
select gpa).ToListAsync();
return groupAdmins;
}
public async Task<bool> UserHasBlackedAsync(long id, Guid formUserId)
{
var userHasBlack = await DbContext.Set<GroupChatBlack>()
.AnyAsync(x => x.GroupId.Equals(id) && x.ShieldUserId.Equals(formUserId));
return userHasBlack;
}
}
}

114
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs

@ -0,0 +1,114 @@
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.MessageService.Messages
{
public class EfCoreMessageRepository : EfCoreRepository<MessageServiceDbContext, Message, long>,
IMessageRepository, ITransientDependency
{
public EfCoreMessageRepository(
IDbContextProvider<MessageServiceDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<GroupMessage> GetGroupMessageAsync(long id)
{
return await DbContext.Set<GroupMessage>()
.Where(x => x.MessageId.Equals(id))
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<List<GroupMessage>> GetGroupMessagesAsync(long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10)
{
if(skipCount > 0)
{
skipCount -= 1;
}
var groupMessages = await DbContext.Set<GroupMessage>()
.Where(x => x.GroupId.Equals(groupId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
.Skip(skipCount * maxResultCount)
.Take(maxResultCount)
.ToListAsync();
return groupMessages;
}
public async Task<List<GroupMessage>> GetUserGroupMessagesAsync(Guid sendUserId, long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10)
{
if (skipCount > 0)
{
skipCount -= 1;
}
var groupMessages = await DbContext.Set<GroupMessage>()
.Where(x => x.GroupId.Equals(groupId) && x.CreatorId.Equals(sendUserId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
.Skip(skipCount * maxResultCount)
.Take(maxResultCount)
.ToListAsync();
return groupMessages;
}
public async Task<UserMessage> GetUserMessageAsync(long id)
{
return await DbContext.Set<UserMessage>()
.Where(x => x.MessageId.Equals(id))
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<List<UserMessage>> GetUserMessagesAsync(Guid sendUserId, Guid receiveUserId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10)
{
if (skipCount > 0)
{
skipCount -= 1;
}
var userMessages = await DbContext.Set<UserMessage>()
.Where(x => x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
.Skip(skipCount * maxResultCount)
.Take(maxResultCount)
.ToListAsync();
return userMessages;
}
public async Task<GroupMessage> InsertGroupMessageAsync(GroupMessage groupMessage, bool saveChangs = false)
{
groupMessage = (await DbContext.Set<GroupMessage>().AddAsync(groupMessage, GetCancellationToken())).Entity;
if(saveChangs)
{
await DbContext.SaveChangesAsync();
}
return groupMessage;
}
public async Task<UserMessage> InsertUserMessageAsync(UserMessage userMessage, bool saveChangs = false)
{
userMessage = (await DbContext.Set<UserMessage>().AddAsync(userMessage, GetCancellationToken())).Entity;
if (saveChangs)
{
await DbContext.SaveChangesAsync();
}
return userMessage;
}
}
}

86
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs

@ -0,0 +1,86 @@
using LINGYUN.Abp.IM.Group;
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.MessageService.Messages
{
public class EfCoreUserChatGroupRepository : EfCoreRepository<MessageServiceDbContext, UserChatGroup, long>,
IUserChatGroupRepository, ITransientDependency
{
public EfCoreUserChatGroupRepository(
IDbContextProvider<MessageServiceDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<List<UserGroup>> GetGroupUsersAsync(long groupId)
{
// TODO: 急需单元测试,对这段代码不是太自信...
var groupUsers = await (from ug in DbSet
join x in (
from gaj in DbContext.Set<ChatGroupAdmin>()
where gaj.GroupId.Equals(groupId)
select gaj
) on ug.UserId equals x.UserId
into y from ga in y.DefaultIfEmpty()
where ug.GroupId.Equals(groupId)
select new UserGroup
{
GroupId = ug.GroupId,
IsSuperAdmin = ga != null && ga.IsSuperAdmin,
IsAdmin = ga != null,
TenantId = ug.TenantId,
UserId = ug.UserId
})
.AsNoTracking()
.ToListAsync();
return groupUsers;
}
public async Task<UserChatGroup> GetUserGroupAsync(long groupId, Guid userId)
{
return await DbSet.Where(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId))
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<List<Group>> GetUserGroupsAsync(Guid userId)
{
// TODO: 急需单元测试,对这段代码不是太自信...
var userGroups = await (from ucg in DbSet
join cg in DbContext.Set<ChatGroup>()
on ucg.GroupId equals cg.GroupId
group cg by new
{
cg.GroupId,
cg.Name,
cg.AllowAnonymous,
cg.AllowSendMessage,
cg.MaxUserCount
}
into ug
orderby ug.Key.GroupId descending
select new Group
{
AllowAnonymous = ug.Key.AllowAnonymous,
AllowSendMessage = ug.Key.AllowSendMessage,
GroupUserCount = ug.Count(),
MaxUserLength = ug.Key.MaxUserCount,
Name = ug.Key.Name
}).ToListAsync();
return userGroups;
}
public async Task<bool> UserHasInGroupAsync(long groupId, Guid userId)
{
return await DbSet.AnyAsync(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId));
}
}
}

39
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatSettingRepository.cs

@ -0,0 +1,39 @@
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.MessageService.Messages
{
public class EfCoreUserChatSettingRepository : EfCoreRepository<MessageServiceDbContext, UserChatSetting, long>,
IUserChatSettingRepository, ITransientDependency
{
public EfCoreUserChatSettingRepository(
IDbContextProvider<MessageServiceDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<UserChatSetting> GetByUserIdAsync(Guid userId)
{
return await DbSet.Where(x => x.UserId.Equals(userId))
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<bool> UserHasBlackedAsync(Guid formUserId, Guid toUserId)
{
return await DbContext.Set<UserChatBlack>()
.AnyAsync(x => x.UserId.Equals(toUserId) && x.ShieldUserId.Equals(formUserId));
}
public async Task<bool> UserHasOpendImAsync(Guid userId)
{
return await DbSet.AnyAsync(x => x.UserId.Equals(userId));
}
}
}

6
aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs

@ -41,6 +41,12 @@ namespace LINGYUN.Abp.SettingManagement
continue; continue;
} }
// TODO: 是否遵循框架的限制?
//if (!setting.IsVisibleToClients)
//{
// continue;
//}
var settingValue = await SettingManager.GetOrNullAsync(setting.Name, providerName, providerKey); var settingValue = await SettingManager.GetOrNullAsync(setting.Name, providerName, providerKey);
var settingInfo = new SettingDto var settingInfo = new SettingDto
{ {

BIN
vueJs/images/aggregate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
vueJs/images/client.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
vueJs/images/im-notifications.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
vueJs/images/tenant.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

3
vueJs/src/components/TenantBox/index.vue

@ -9,10 +9,9 @@
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-link <el-link
type="info"
@click="handleSwitchTenant" @click="handleSwitchTenant"
> >
{{ $t('AbpUiMultiTenancy.SwitchTenant') }} ({{ $t('AbpUiMultiTenancy.SwitchTenant') }})
</el-link> </el-link>
</el-col> </el-col>
</el-row> </el-row>

Loading…
Cancel
Save