committed by
GitHub
146 changed files with 5088 additions and 402 deletions
@ -0,0 +1,62 @@ |
|||
using LINGYUN.Abp.Notifications; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Controllers |
|||
{ |
|||
[Route("api/app/notifications")] |
|||
public class NotificationController : AbpController |
|||
{ |
|||
private readonly INotificationDispatcher _notificationDispatcher; |
|||
public NotificationController( |
|||
INotificationDispatcher notificationDispatcher) |
|||
{ |
|||
_notificationDispatcher = notificationDispatcher; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Send")] |
|||
public async Task SendNofitication([FromForm] SendNotification notification) |
|||
{ |
|||
var notificationInfo = new NotificationInfo |
|||
{ |
|||
TenantId = null, |
|||
NotificationSeverity = notification.Severity, |
|||
NotificationType = NotificationType.Application, |
|||
Id = new Random().Next(int.MinValue, int.MaxValue), |
|||
Name = "TestApplicationNotofication", |
|||
CreationTime = Clock.Now |
|||
}; |
|||
notificationInfo.Data.Properties["id"] = notificationInfo.Id.ToString(); |
|||
notificationInfo.Data.Properties["title"] = notification.Title; |
|||
notificationInfo.Data.Properties["message"] = notification.Message; |
|||
notificationInfo.Data.Properties["datetime"] = Clock.Now; |
|||
notificationInfo.Data.Properties["severity"] = notification.Severity; |
|||
|
|||
await _notificationDispatcher.DispatcheAsync(notificationInfo); |
|||
} |
|||
} |
|||
|
|||
public class SendNotification |
|||
{ |
|||
public Guid UserId { get; set; } |
|||
public string Title { get; set; } |
|||
public string Message { get; set; } |
|||
public NotificationSeverity Severity { get; set; } = NotificationSeverity.Success; |
|||
} |
|||
|
|||
public class TestApplicationNotificationData : NotificationData |
|||
{ |
|||
public object Message |
|||
{ |
|||
get { return this[nameof(Message)]; } |
|||
set |
|||
{ |
|||
Properties[nameof(Message)] = value; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.EntityFrameworkCore |
|||
{ |
|||
public class MessageServiceHostMigrationsDbContext : AbpDbContext<MessageServiceHostMigrationsDbContext> |
|||
{ |
|||
public MessageServiceHostMigrationsDbContext(DbContextOptions<MessageServiceHostMigrationsDbContext> options) |
|||
: base(options) |
|||
{ |
|||
|
|||
} |
|||
|
|||
protected override void OnModelCreating(ModelBuilder modelBuilder) |
|||
{ |
|||
base.OnModelCreating(modelBuilder); |
|||
|
|||
modelBuilder.ConfigureMessageService(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System.IO; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Design; |
|||
using Microsoft.Extensions.Configuration; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.EntityFrameworkCore |
|||
{ |
|||
public class MessageServiceHostMigrationsDbContextFactory : IDesignTimeDbContextFactory<MessageServiceHostMigrationsDbContext> |
|||
{ |
|||
public MessageServiceHostMigrationsDbContext CreateDbContext(string[] args) |
|||
{ |
|||
var configuration = BuildConfiguration(); |
|||
|
|||
var builder = new DbContextOptionsBuilder<MessageServiceHostMigrationsDbContext>() |
|||
.UseMySql(configuration.GetConnectionString("Default")); |
|||
|
|||
return new MessageServiceHostMigrationsDbContext(builder.Options); |
|||
} |
|||
|
|||
private static IConfigurationRoot BuildConfiguration() |
|||
{ |
|||
var builder = new ConfigurationBuilder() |
|||
.SetBasePath(Directory.GetCurrentDirectory()) |
|||
.AddJsonFile("appsettings.Development.json", optional: false); |
|||
|
|||
return builder.Build(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace>LINGYUN.Abp.MessageService</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3"> |
|||
<PrivateAssets>all</PrivateAssets> |
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
|||
</PackageReference> |
|||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.3" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.3" /> |
|||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> |
|||
<PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" /> |
|||
<PackageReference Include="Serilog.Enrichers.Process" Version="2.0.1" /> |
|||
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" /> |
|||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> |
|||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> |
|||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="2.8.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> |
|||
<ProjectReference Include="..\modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj" /> |
|||
<ProjectReference Include="..\modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj" /> |
|||
<ProjectReference Include="..\modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,152 @@ |
|||
using IdentityModel; |
|||
using LINGYUN.Abp.IM.SignalR; |
|||
using LINGYUN.Abp.MessageService.EntityFrameworkCore; |
|||
using LINGYUN.Abp.MessageService.MultiTenancy; |
|||
using LINGYUN.Abp.Notifications.SignalR; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.OpenApi.Models; |
|||
using StackExchange.Redis; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Authentication.JwtBearer; |
|||
using Volo.Abp.AspNetCore.MultiTenancy; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
|||
using Volo.Abp.Security.Claims; |
|||
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
|||
using Volo.Abp.TenantManagement.EntityFrameworkCore; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpMessageServiceHttpApiModule), |
|||
typeof(AbpAspNetCoreMultiTenancyModule), |
|||
typeof(AbpMessageServiceEntityFrameworkCoreModule), |
|||
typeof(AbpTenantManagementEntityFrameworkCoreModule), |
|||
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
|||
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
|||
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), |
|||
typeof(AbpIMSignalRModule), |
|||
typeof(AbpNotificationsSignalRModule), |
|||
typeof(AbpAutofacModule) |
|||
)] |
|||
public class AbpMessageServiceHttpApiHostModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = hostingEnvironment.BuildConfiguration(); |
|||
// 配置Ef
|
|||
Configure<AbpDbContextOptions>(options => |
|||
{ |
|||
options.UseMySQL(); |
|||
}); |
|||
|
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpMessageServiceHttpApiHostModule>("LINGYUN.Abp.MessageService"); |
|||
}); |
|||
|
|||
// 多租户
|
|||
Configure<AbpMultiTenancyOptions>(options => |
|||
{ |
|||
options.IsEnabled = true; |
|||
}); |
|||
|
|||
Configure<AbpTenantResolveOptions>(options => |
|||
{ |
|||
options.TenantResolvers.Insert(0, new AuthorizationTenantResolveContributor()); |
|||
}); |
|||
|
|||
// Swagger
|
|||
context.Services.AddSwaggerGen( |
|||
options => |
|||
{ |
|||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "MessageService API", Version = "v1" }); |
|||
options.DocInclusionPredicate((docName, description) => true); |
|||
options.CustomSchemaIds(type => type.FullName); |
|||
}); |
|||
|
|||
// 支持本地化语言类型
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
|||
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
|||
}); |
|||
|
|||
context.Services.AddAuthentication("Bearer") |
|||
.AddIdentityServerAuthentication(options => |
|||
{ |
|||
options.Authority = configuration["AuthServer:Authority"]; |
|||
options.RequireHttpsMetadata = false; |
|||
options.ApiName = configuration["AuthServer:ApiName"]; |
|||
AbpClaimTypes.UserId = JwtClaimTypes.Subject; |
|||
AbpClaimTypes.UserName = JwtClaimTypes.Name; |
|||
AbpClaimTypes.Role = JwtClaimTypes.Role; |
|||
AbpClaimTypes.Email = JwtClaimTypes.Email; |
|||
}); |
|||
|
|||
context.Services.AddStackExchangeRedisCache(options => |
|||
{ |
|||
options.Configuration = configuration["RedisCache:ConnectString"]; |
|||
var instanceName = configuration["RedisCache:RedisPrefix"]; |
|||
options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName; |
|||
}); |
|||
|
|||
if (!hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); |
|||
context.Services |
|||
.AddDataProtection() |
|||
.PersistKeysToStackExchangeRedis(redis, "MessageService-Protection-Keys"); |
|||
} |
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var app = context.GetApplicationBuilder(); |
|||
// http调用链
|
|||
app.UseCorrelationId(); |
|||
// 虚拟文件系统
|
|||
app.UseVirtualFiles(); |
|||
// 本地化
|
|||
app.UseAbpRequestLocalization(); |
|||
//路由
|
|||
app.UseRouting(); |
|||
// 加入自定义中间件
|
|||
app.UseMiddleware<SignalRJwtTokenMiddleware>(); |
|||
// 认证
|
|||
app.UseAuthentication(); |
|||
// jwt
|
|||
app.UseJwtTokenMiddleware(); |
|||
// 授权
|
|||
app.UseAuthorization(); |
|||
// 多租户
|
|||
app.UseMultiTenancy(); |
|||
// Swagger
|
|||
app.UseSwagger(); |
|||
// Swagger可视化界面
|
|||
app.UseSwaggerUI(options => |
|||
{ |
|||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support MessageService API"); |
|||
}); |
|||
// 审计日志
|
|||
app.UseAuditing(); |
|||
// 路由
|
|||
app.UseConfiguredEndpoints(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using DotNetCore.CAP.Internal; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Utils |
|||
{ |
|||
[Dependency(ServiceLifetime.Singleton, TryRegister = true)] |
|||
[ExposeServices(typeof(ISnowflakeIdGenerator))] |
|||
public class SnowflakeIdGenerator : ISnowflakeIdGenerator |
|||
{ |
|||
public long Create() |
|||
{ |
|||
return SnowflakeId.Default().NextId(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
// <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("20200601060701_Add-Abp-Message-Service-Module")] |
|||
partial class AddAbpMessageServiceModule |
|||
{ |
|||
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.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<sbyte>("ReadStatus") |
|||
.HasColumnType("tinyint"); |
|||
|
|||
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
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Metadata; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Migrations |
|||
{ |
|||
public partial class AddAbpMessageServiceModule : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "AppNotifications", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<long>(nullable: false) |
|||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), |
|||
TenantId = table.Column<Guid>(nullable: true), |
|||
Severity = table.Column<sbyte>(nullable: false), |
|||
Type = table.Column<int>(nullable: false), |
|||
NotificationId = table.Column<long>(nullable: false), |
|||
NotificationName = table.Column<string>(maxLength: 100, nullable: false), |
|||
NotificationData = table.Column<string>(maxLength: 1048576, nullable: false), |
|||
NotificationTypeName = table.Column<string>(maxLength: 512, nullable: false), |
|||
ExpirationTime = table.Column<DateTime>(nullable: true), |
|||
CreationTime = table.Column<DateTime>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppNotifications", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AppUserNotifications", |
|||
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), |
|||
NotificationId = table.Column<long>(nullable: false), |
|||
ReadStatus = table.Column<sbyte>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppUserNotifications", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "AppUserSubscribes", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<long>(nullable: false) |
|||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), |
|||
TenantId = table.Column<Guid>(nullable: true), |
|||
CreationTime = table.Column<DateTime>(nullable: false), |
|||
NotificationName = table.Column<string>(maxLength: 100, nullable: false), |
|||
UserId = table.Column<Guid>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppUserSubscribes", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppNotifications_NotificationName", |
|||
table: "AppNotifications", |
|||
column: "NotificationName"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Tenant_User_Notification_Id", |
|||
table: "AppUserNotifications", |
|||
columns: new[] { "TenantId", "UserId", "NotificationId" }); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Tenant_User_Notification_Name", |
|||
table: "AppUserSubscribes", |
|||
columns: new[] { "TenantId", "UserId", "NotificationName" }, |
|||
unique: true); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "AppNotifications"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "AppUserNotifications"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "AppUserSubscribes"); |
|||
} |
|||
} |
|||
} |
|||
@ -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
|
|||
} |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,492 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using LINGYUN.Abp.MessageService.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Migrations |
|||
{ |
|||
[DbContext(typeof(MessageServiceHostMigrationsDbContext))] |
|||
partial class MessageServiceHostMigrationsDbContextModelSnapshot : ModelSnapshot |
|||
{ |
|||
protected override void BuildModel(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
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using Microsoft.AspNetCore.Http; |
|||
using System.Linq; |
|||
using Volo.Abp.AspNetCore.MultiTenancy; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Security.Claims; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.MultiTenancy |
|||
{ |
|||
public class AuthorizationTenantResolveContributor : HttpTenantResolveContributorBase |
|||
{ |
|||
public override string Name => "Authorization"; |
|||
|
|||
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) |
|||
{ |
|||
if (httpContext.User?.Identity == null) |
|||
{ |
|||
return null; |
|||
} |
|||
if (!httpContext.User.Identity.IsAuthenticated) |
|||
{ |
|||
return null; |
|||
} |
|||
var tenantIdKey = context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey; |
|||
|
|||
var tenantClaim = httpContext.User.Claims.FirstOrDefault(x => x.Type.Equals(AbpClaimTypes.TenantId)); |
|||
|
|||
if (tenantClaim == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return tenantClaim.Value; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Serilog; |
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static int Main(string[] args) |
|||
{ |
|||
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; |
|||
var configuration = new ConfigurationBuilder() |
|||
.SetBasePath(Directory.GetCurrentDirectory()) |
|||
.AddJsonFile($"appsettings.{env}.json", optional: false, reloadOnChange: true) |
|||
.AddEnvironmentVariables() |
|||
.Build(); |
|||
Log.Logger = new LoggerConfiguration() |
|||
.ReadFrom.Configuration(configuration) |
|||
.CreateLogger(); |
|||
try |
|||
{ |
|||
Log.Information("Starting web host."); |
|||
CreateHostBuilder(args).Build().Run(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
|
|||
internal static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}) |
|||
.UseSerilog() |
|||
.UseAutofac(); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:63963", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"LINGYUN.Abp.MessageService.HttpApi.Host": { |
|||
"commandName": "Project", |
|||
"launchBrowser": false, |
|||
"applicationUrl": "http://localhost:30020", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddApplication<AbpMessageServiceHttpApiHostModule>(); |
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app) |
|||
{ |
|||
app.InitializeApplication(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
using LINGYUN.Abp.IM.Messages; |
|||
using LINGYUN.Abp.RealTime.Client; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.SignalR; |
|||
|
|||
namespace LINGYUN.Abp.IM.SignalR.Hubs |
|||
{ |
|||
[Authorize] |
|||
public class MessageHub : OnlineClientHubBase |
|||
{ |
|||
private readonly IMessageStore _messageStore; |
|||
|
|||
public MessageHub( |
|||
IMessageStore messageStore) |
|||
{ |
|||
_messageStore = messageStore; |
|||
} |
|||
/// <summary>
|
|||
/// 客户端调用发送消息方法
|
|||
/// </summary>
|
|||
/// <param name="chatMessage"></param>
|
|||
/// <returns></returns>
|
|||
[HubMethodName("SendMessage")] |
|||
public virtual async Task SendMessageAsync(ChatMessage chatMessage) |
|||
{ |
|||
// 持久化
|
|||
await _messageStore.StoreMessageAsync(chatMessage); |
|||
|
|||
if (!chatMessage.GroupId.IsNullOrWhiteSpace()) |
|||
{ |
|||
try |
|||
{ |
|||
var signalRClient = Clients.Group(chatMessage.GroupId); |
|||
if (signalRClient == null) |
|||
{ |
|||
Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!"); |
|||
return; |
|||
} |
|||
|
|||
await signalRClient.SendAsync("getChatMessage", chatMessage); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Logger.LogWarning("Could not send message to group: {0}", chatMessage.GroupId); |
|||
Logger.LogWarning("Send group message error: {0}", ex.Message); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.GetValueOrDefault()); |
|||
var onlineClients = OnlineClientManager.GetAllByContext(onlineClientContext); |
|||
foreach (var onlineClient in onlineClients) |
|||
{ |
|||
try |
|||
{ |
|||
var signalRClient = 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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
using LINGYUN.Abp.IM.Messages; |
|||
using LINGYUN.Abp.IM.SignalR.Hubs; |
|||
using LINGYUN.Abp.RealTime.Client; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.IM.SignalR.Messages |
|||
{ |
|||
public class SignalRMessageSender : IMessageSender, ITransientDependency |
|||
{ |
|||
public ILogger<SignalRMessageSender> Logger { protected get; set; } |
|||
|
|||
private readonly IOnlineClientManager _onlineClientManager; |
|||
|
|||
private readonly IHubContext<MessageHub> _hubContext; |
|||
|
|||
private readonly IMessageStore _messageStore; |
|||
|
|||
public SignalRMessageSender( |
|||
IOnlineClientManager onlineClientManager, |
|||
IHubContext<MessageHub> hubContext, |
|||
IMessageStore messageStore) |
|||
{ |
|||
_hubContext = hubContext; |
|||
_messageStore = messageStore; |
|||
_onlineClientManager = onlineClientManager; |
|||
|
|||
Logger = NullLogger<SignalRMessageSender>.Instance; |
|||
} |
|||
/// <summary>
|
|||
/// 服务端调用发送消息方法
|
|||
/// </summary>
|
|||
/// <param name="chatMessage"></param>
|
|||
/// <returns></returns>
|
|||
public async Task SendMessageAsync(ChatMessage chatMessage) |
|||
{ |
|||
// 持久化
|
|||
await _messageStore.StoreMessageAsync(chatMessage); |
|||
|
|||
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 |
|||
{ |
|||
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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IM.Group |
|||
{ |
|||
public interface IUserGroupStore |
|||
{ |
|||
/// <summary>
|
|||
/// 获取用户所在通讯组列表
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="userId"></param>
|
|||
/// <returns></returns>
|
|||
Task<IEnumerable<Group>> GetUserGroupsAsync(Guid? tenantId, Guid userId); |
|||
/// <summary>
|
|||
/// 获取通讯组所有用户
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="groupId"></param>
|
|||
/// <returns></returns>
|
|||
Task<IEnumerable<UserGroup>> GetGroupUsersAsync(Guid? tenantId, long groupId); |
|||
/// <summary>
|
|||
/// 用户加入通讯组
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="userId"></param>
|
|||
/// <param name="groupId"></param>
|
|||
/// <returns></returns>
|
|||
Task AddUserToGroupAsync(Guid? tenantId, Guid userId, long groupId, Guid acceptUserId); |
|||
/// <summary>
|
|||
/// 用户退出通讯组
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="userId"></param>
|
|||
/// <param name="groupId"></param>
|
|||
/// <returns></returns>
|
|||
Task RemoveUserFormGroupAsync(Guid? tenantId, Guid userId, long groupId); |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.IM.Group |
|||
{ |
|||
public class UserGroup |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
public Guid UserId { get; set; } |
|||
public long GroupId { get; set; } |
|||
public bool IsAdmin { get; set; } |
|||
public bool IsSuperAdmin { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using Volo.Abp.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.IM.Messages |
|||
{ |
|||
public class ChatMessage |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public string GroupId { get; set; } |
|||
|
|||
public string MessageId { get; set; } |
|||
|
|||
public Guid FormUserId { get; set; } |
|||
|
|||
public string FormUserName { get; set; } |
|||
|
|||
public Guid? ToUserId { get; set; } |
|||
|
|||
[DisableAuditing] |
|||
public string Content { get; set; } |
|||
|
|||
public DateTime SendTime { get; set; } |
|||
|
|||
public bool IsAnonymous { get; set; } = false; |
|||
|
|||
public MessageType MessageType { get; set; } = MessageType.Text; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IM.Messages |
|||
{ |
|||
public interface IMessageSender |
|||
{ |
|||
Task SendMessageAsync(ChatMessage chatMessage); |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IM.Messages |
|||
{ |
|||
public interface IMessageStore |
|||
{ |
|||
/// <summary>
|
|||
/// 存储聊天记录
|
|||
/// </summary>
|
|||
/// <param name="chatMessage"></param>
|
|||
/// <param name="formUserId"></param>
|
|||
/// <param name="toUserId"></param>
|
|||
/// <returns></returns>
|
|||
Task StoreMessageAsync(ChatMessage chatMessage); |
|||
/// <summary>
|
|||
/// 获取群组聊天记录
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="groupName"></param>
|
|||
/// <param name="maxResultCount"></param>
|
|||
/// <returns></returns>
|
|||
Task<List<ChatMessage>> GetGroupMessageAsync(Guid? tenantId, long groupId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10); |
|||
/// <summary>
|
|||
/// 获取与某个用户的聊天记录
|
|||
/// </summary>
|
|||
/// <param name="tenantId"></param>
|
|||
/// <param name="userId"></param>
|
|||
/// <param name="maxResultCount"></param>
|
|||
/// <returns></returns>
|
|||
Task<List<ChatMessage>> GetChatMessageAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", MessageType type = MessageType.Text, int skipCount = 1, int maxResultCount = 10); |
|||
|
|||
} |
|||
} |
|||
@ -1,9 +1,9 @@ |
|||
namespace LINGYUN.Abp.MessageService |
|||
namespace LINGYUN.Abp.IM.Messages |
|||
{ |
|||
/// <summary>
|
|||
/// 消息状态
|
|||
/// </summary>
|
|||
public enum SendStatus : sbyte |
|||
public enum MessageSendState : sbyte |
|||
{ |
|||
/// <summary>
|
|||
/// 已发送
|
|||
@ -0,0 +1,10 @@ |
|||
namespace LINGYUN.Abp.IM.Messages |
|||
{ |
|||
public enum MessageType |
|||
{ |
|||
Text = 0, |
|||
Image = 10, |
|||
Link = 20, |
|||
Video = 30 |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.SignalR" Version="2.8.0" /> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="2.8.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.RealTime\LINGYUN.Abp.RealTime.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,15 @@ |
|||
using LINGYUN.Abp.RealTime; |
|||
using Volo.Abp.AspNetCore.SignalR; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.SignalR |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpRealTimeModule), |
|||
typeof(AbpNotificationModule), |
|||
typeof(AbpAspNetCoreSignalRModule))] |
|||
public class AbpNotificationsSignalRModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.SignalR.Hubs |
|||
{ |
|||
[Authorize] |
|||
public class NotificationsHub : OnlineClientHubBase |
|||
{ |
|||
private INotificationStore _notificationStore; |
|||
protected INotificationStore NotificationStore => LazyGetRequiredService(ref _notificationStore); |
|||
|
|||
[HubMethodName("GetNotification")] |
|||
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync( |
|||
NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10) |
|||
{ |
|||
var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState, maxResultCount); |
|||
|
|||
return new ListResultDto<NotificationInfo>(userNotifications); |
|||
} |
|||
|
|||
[HubMethodName("ChangeState")] |
|||
public virtual async Task ChangeStateAsync(long id, NotificationReadState readState = NotificationReadState.Read) |
|||
{ |
|||
await NotificationStore.ChangeUserNotificationReadStateAsync(CurrentTenant.Id, CurrentUser.GetId(), id, readState); |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
using LINGYUN.Abp.RealTime.Client; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.SignalR; |
|||
using Volo.Abp.Security.Claims; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.SignalR |
|||
{ |
|||
public abstract class OnlineClientHubBase : AbpHub |
|||
{ |
|||
private ICurrentPrincipalAccessor _currentPrincipalAccessor; |
|||
protected ICurrentPrincipalAccessor CurrentPrincipalAccessor => LazyGetRequiredService(ref _currentPrincipalAccessor); |
|||
|
|||
private IOnlineClientManager _onlineClientManager; |
|||
protected IOnlineClientManager OnlineClientManager => LazyGetRequiredService(ref _onlineClientManager); |
|||
|
|||
private IHttpContextAccessor _httpContextAccessor; |
|||
protected IHttpContextAccessor HttpContextAccessor => LazyGetRequiredService(ref _httpContextAccessor); |
|||
|
|||
public override async Task OnConnectedAsync() |
|||
{ |
|||
await base.OnConnectedAsync(); |
|||
IOnlineClient onlineClient = CreateClientForCurrentConnection(); |
|||
Logger.LogDebug("A client is connected: " + onlineClient.ToString()); |
|||
OnlineClientManager.Add(onlineClient); |
|||
} |
|||
|
|||
public override async Task OnDisconnectedAsync(Exception exception) |
|||
{ |
|||
await base.OnDisconnectedAsync(exception); |
|||
Logger.LogDebug("A client is disconnected: " + Context.ConnectionId); |
|||
try |
|||
{ |
|||
// 从通讯组移除
|
|||
var onlineClient = OnlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId); |
|||
if(onlineClient != null) |
|||
{ |
|||
// 移除在线客户端
|
|||
OnlineClientManager.Remove(Context.ConnectionId); |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Logger.LogWarning(ex.ToString(), ex); |
|||
} |
|||
} |
|||
|
|||
protected virtual IOnlineClient CreateClientForCurrentConnection() |
|||
{ |
|||
// abp框架没有处理,需要切换一下用户身份令牌.否则无法获取用户信息
|
|||
using (CurrentPrincipalAccessor.Change(Context.User)) |
|||
{ |
|||
return new OnlineClient(Context.ConnectionId, GetClientIpAddress(), |
|||
CurrentTenant.Id, CurrentUser.Id) |
|||
{ |
|||
ConnectTime = Clock.Now, |
|||
UserName = CurrentUser.UserName |
|||
}; |
|||
} |
|||
} |
|||
|
|||
protected virtual string GetClientIpAddress() |
|||
{ |
|||
try |
|||
{ |
|||
return HttpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString(); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Logger.LogException(ex, LogLevel.Warning); |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using Microsoft.AspNetCore.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Microsoft.AspNetCore.Builder |
|||
{ |
|||
public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency |
|||
{ |
|||
public async Task InvokeAsync(HttpContext context, RequestDelegate next) |
|||
{ |
|||
// 仅针对自定义的SignalR hub
|
|||
if (context.Request.Path.StartsWithSegments("/signalr-hubs/notifications")) |
|||
{ |
|||
if (context.User.Identity?.IsAuthenticated != true) |
|||
{ |
|||
if (context.Request.Query.TryGetValue("access_token", out var accessToken)) |
|||
{ |
|||
context.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); |
|||
} |
|||
|
|||
} |
|||
} |
|||
await next(context); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using LINGYUN.Abp.Notifications.Internal; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Notifications |
|||
{ |
|||
public class AbpNotificationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddTransient<INotificationDispatcher, DefaultNotificationDispatcher>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Notifications |
|||
{ |
|||
public interface INotificationSender |
|||
{ |
|||
Task SendAsync(NotificationData data, Guid userId, Guid? tenantId); |
|||
Task SendAsync(NotificationData data, IEnumerable<Guid> userIds, Guid? tenantId); |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Notifications.Internal |
|||
{ |
|||
internal class DefaultNotificationDispatcher : INotificationDispatcher |
|||
{ |
|||
private readonly INotificationStore _notificationStore; |
|||
private readonly INotificationPublisher _notificationPublisher; |
|||
public DefaultNotificationDispatcher( |
|||
INotificationStore notificationStore, |
|||
INotificationPublisher notificationPublisher) |
|||
{ |
|||
_notificationStore = notificationStore; |
|||
_notificationPublisher = notificationPublisher; |
|||
} |
|||
|
|||
public async Task DispatcheAsync(NotificationInfo notification) |
|||
{ |
|||
// 持久化通知
|
|||
await _notificationStore.InsertNotificationAsync(notification); |
|||
|
|||
// 获取用户订阅列表
|
|||
var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notification.TenantId, notification.Name); |
|||
|
|||
// 持久化用户通知
|
|||
var subscriptionUserIds = userSubscriptions.Select(us => us.UserId); |
|||
await _notificationStore.InsertUserNotificationsAsync(notification, subscriptionUserIds); |
|||
|
|||
// 发布用户通知
|
|||
await _notificationPublisher.PublishAsync(notification, subscriptionUserIds); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
|
|||
namespace Newtonsoft.Json |
|||
{ |
|||
public class HexLongConverter : JsonConverter |
|||
{ |
|||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
|||
{ |
|||
long v = value is ulong ? (long)(ulong)value : (long)value; |
|||
writer.WriteValue(v.ToString()); |
|||
} |
|||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
|||
{ |
|||
string value = reader.Value as string; |
|||
long lValue = long.Parse(value); |
|||
return typeof(ulong) == objectType ? (object)(ulong)lValue : lValue; |
|||
} |
|||
public override bool CanConvert(Type objectType) |
|||
{ |
|||
switch (objectType.FullName) |
|||
{ |
|||
case "System.Int64": |
|||
case "System.UInt64": |
|||
return true; |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Core" Version="2.8.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.RealTime |
|||
{ |
|||
public class AbpRealTimeModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.IM |
|||
namespace LINGYUN.Abp.RealTime.Client |
|||
{ |
|||
public interface IOnlineClientStore |
|||
{ |
|||
@ -1,6 +1,6 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.IM |
|||
namespace LINGYUN.Abp.RealTime.Client |
|||
{ |
|||
public class OnlineClientEventArgs : EventArgs |
|||
{ |
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.IM |
|||
namespace LINGYUN.Abp.RealTime.Client |
|||
{ |
|||
public class OnlineUserEventArgs : OnlineClientEventArgs |
|||
{ |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Localization |
|||
{ |
|||
[LocalizationResourceName("MessageService")] |
|||
public class MessageServiceResource |
|||
{ |
|||
} |
|||
} |
|||
@ -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"; |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
public class MessageServiceSettingNames |
|||
{ |
|||
public const string GroupName = "Abp.MessageService"; |
|||
|
|||
public class Notifications |
|||
{ |
|||
public const string Default = GroupName + ".Notifications"; |
|||
/// <summary>
|
|||
/// 清理过期消息批次
|
|||
/// </summary>
|
|||
public const string CleanupExpirationBatchCount = Default + ".CleanupExpirationBatchCount"; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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,0 +1,16 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications |
|||
{ |
|||
public class CleanupNotificationJobArgs |
|||
{ |
|||
/// <summary>
|
|||
/// 清理大小
|
|||
/// </summary>
|
|||
public int Count { get; set; } |
|||
/// <summary>
|
|||
/// 清理租户
|
|||
/// </summary>
|
|||
public Guid? TenantId { get; set; } |
|||
} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
/// <summary>
|
|||
/// 读取状态
|
|||
/// </summary>
|
|||
public enum ReadStatus : sbyte |
|||
{ |
|||
/// <summary>
|
|||
/// 已读
|
|||
/// </summary>
|
|||
Read = 0, |
|||
/// <summary>
|
|||
/// 未读
|
|||
/// </summary>
|
|||
UnRead = 10 |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
public class AbpMessageServiceDbProperties |
|||
{ |
|||
public const string DefaultTablePrefix = "App"; |
|||
|
|||
public const string DefaultSchema = null; |
|||
} |
|||
} |
|||
@ -1,9 +1,18 @@ |
|||
using Volo.Abp.Modularity; |
|||
using LINGYUN.Abp.MessageService.Mapper; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.MessageService |
|||
{ |
|||
[DependsOn(typeof(AbpAutoMapperModule))] |
|||
public class AbpMessageServiceDomainModule : AbpModule |
|||
{ |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<MessageServiceDomainAutoMapperProfile>(validate: true); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,37 @@ |
|||
using LINGYUN.Abp.MessageService.Notifications; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.BackgroundJobs; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.BackgroundJobs |
|||
{ |
|||
public class NotificationExpritionCleanupJob : AsyncBackgroundJob<CleanupNotificationJobArgs> |
|||
{ |
|||
private readonly ICurrentTenant _currentTenant; |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
private readonly INotificationRepository _notificationRepository; |
|||
public NotificationExpritionCleanupJob( |
|||
ICurrentTenant currentTenant, |
|||
IUnitOfWorkManager unitOfWorkManager, |
|||
INotificationRepository notificationRepository) |
|||
{ |
|||
_currentTenant = currentTenant; |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
_notificationRepository = notificationRepository; |
|||
} |
|||
|
|||
public override async Task ExecuteAsync(CleanupNotificationJobArgs args) |
|||
{ |
|||
using (var unitOfWork = _unitOfWorkManager.Begin()) |
|||
{ |
|||
using (_currentTenant.Change(args.TenantId)) |
|||
{ |
|||
await _notificationRepository.DeleteExpritionAsync(args.Count); |
|||
|
|||
await unitOfWork.SaveChangesAsync(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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!" |
|||
} |
|||
} |
|||
@ -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": "用户拒绝您发送的消息!" |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
using AutoMapper; |
|||
using LINGYUN.Abp.IM.Messages; |
|||
using LINGYUN.Abp.MessageService.Messages; |
|||
using LINGYUN.Abp.MessageService.Notifications; |
|||
using LINGYUN.Abp.MessageService.Subscriptions; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Mapper |
|||
{ |
|||
public class MessageServiceDomainAutoMapperProfile : Profile |
|||
{ |
|||
public MessageServiceDomainAutoMapperProfile() |
|||
{ |
|||
CreateMap<Notification, NotificationInfo>() |
|||
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId)) |
|||
.ForMember(dto => dto.Name, map => map.MapFrom(src => src.NotificationName)) |
|||
.ForMember(dto => dto.NotificationType, map => map.MapFrom(src => src.Type)) |
|||
.ForMember(dto => dto.NotificationSeverity, map => map.MapFrom(src => src.Severity)) |
|||
.ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) => |
|||
{ |
|||
var notificationDataType = Type.GetType(src.NotificationTypeName); |
|||
var notificationData = JsonConvert.DeserializeObject(src.NotificationData, notificationDataType); |
|||
if(notificationData != null) |
|||
{ |
|||
return notificationData as NotificationData; |
|||
} |
|||
return new NotificationData(); |
|||
})); |
|||
|
|||
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()); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,34 +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; } |
|||
/// <summary>
|
|||
/// 阅读状态
|
|||
/// </summary>
|
|||
public virtual ReadStatus ReadStatus { get; protected set; } |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications |
|||
{ |
|||
public interface INotificationRepository : IBasicRepository<Notification, long> |
|||
{ |
|||
Task<Notification> GetByIdAsync(long notificationId); |
|||
|
|||
Task DeleteExpritionAsync(int batchCount); |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
using LINGYUN.Abp.Notifications; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.MessageService.Notifications |
|||
{ |
|||
public interface INotificationStore |
|||
{ |
|||
Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue