сделал отправку на почту и присваивание ачивки за ранее
This commit is contained in:
		| @@ -2,7 +2,10 @@ using Mapster; | |||||||
| using Microsoft.AspNetCore.Authorization; | using Microsoft.AspNetCore.Authorization; | ||||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Hangfire; | ||||||
|  | using MailKit.Net.Smtp; | ||||||
|  | using MailKit.Security; | ||||||
|  | using MimeKit; | ||||||
| namespace CyberBoom.Controllers; | namespace CyberBoom.Controllers; | ||||||
|  |  | ||||||
| [ApiController] | [ApiController] | ||||||
| @@ -32,16 +35,19 @@ public class UserWriteToMetingController : ControllerBase | |||||||
|  |  | ||||||
|         var user = await _applicationContext.Users.FirstAsync(u => u.Id == write.UserId); |         var user = await _applicationContext.Users.FirstAsync(u => u.Id == write.UserId); | ||||||
|  |  | ||||||
|         var newStats = await _applicationContext.GetStatistic(write.UserId); |          | ||||||
|  |         var delay = meeting.Time - DateTime.UtcNow - new TimeSpan(2, 0, 0); | ||||||
|  |          | ||||||
|  |         BackgroundJob.Schedule<IEmailService>((_emailService) => _emailService.SendEmailAsync(user.Email!, "Вход в Муза", $"Здравcтвуйте. У вас мероприятие через 2 часа под названием {meeting.Title}"), delay); // за начало до встречи | ||||||
|  |  | ||||||
|         var achievments = await WriteAchievment(newStats, write.UserId); |         BackgroundJob.Schedule<ApplicationContext>((context) => AfterEnd(write.UserId, context), meeting.Time - DateTime.UtcNow); // за начало до встречи | ||||||
|  |  | ||||||
|         await _applicationContext.SaveChangesAsync(); |         await _applicationContext.SaveChangesAsync(); | ||||||
|  |  | ||||||
|         return Ok(new { dbWr.Id, Achievments = achievments }); |         return Ok(new { dbWr.Id}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async Task<List<Achievment>> WriteAchievment(StatsData stats, string userId) |     async Task<List<Achievment>> WriteAchievment(StatsData stats, string userId, ApplicationContext context) | ||||||
|     { |     { | ||||||
|         List<Achievment> achievments = new List<Achievment>(); |         List<Achievment> achievments = new List<Achievment>(); | ||||||
|         if (stats.Count > 0 && stats.Count % 5 == 0) |         if (stats.Count > 0 && stats.Count % 5 == 0) | ||||||
| @@ -54,8 +60,9 @@ public class UserWriteToMetingController : ControllerBase | |||||||
|                 UserId = userId |                 UserId = userId | ||||||
|             }; |             }; | ||||||
|             achievments.Add(achievment); |             achievments.Add(achievment); | ||||||
|             await _applicationContext.Achievments.AddAsync(achievment); |             await context.Achievments.AddAsync(achievment); | ||||||
|         } |         } | ||||||
|  |          | ||||||
|         var achievedTags = stats.StatsByTag.Where(st => st.Count > 0 && st.Count % 5 == 0); |         var achievedTags = stats.StatsByTag.Where(st => st.Count > 0 && st.Count % 5 == 0); | ||||||
|         if (achievedTags.Count() > 0 && stats.Count % 5 == 0) |         if (achievedTags.Count() > 0 && stats.Count % 5 == 0) | ||||||
|         { |         { | ||||||
| @@ -69,7 +76,7 @@ public class UserWriteToMetingController : ControllerBase | |||||||
|                     UserId = userId |                     UserId = userId | ||||||
|                 }; |                 }; | ||||||
|                 achievments.Add(achievment); |                 achievments.Add(achievment); | ||||||
|                 await _applicationContext.Achievments.AddAsync(achievment); |                 await context.Achievments.AddAsync(achievment); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return achievments; |         return achievments; | ||||||
| @@ -93,6 +100,16 @@ public class UserWriteToMetingController : ControllerBase | |||||||
|         return Ok(); |         return Ok(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     async Task AfterEnd(string userId, ApplicationContext context) | ||||||
|  |     { | ||||||
|  |         var newStats = await context.GetStatistic(userId); | ||||||
|  |  | ||||||
|  |         await WriteAchievment(newStats, userId, context); | ||||||
|  |  | ||||||
|  |         await context.SaveChangesAsync(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     [HttpGet] |     [HttpGet] | ||||||
|     public async Task<IActionResult> Get(string id) |     public async Task<IActionResult> Get(string id) | ||||||
|     { |     { | ||||||
| @@ -112,3 +129,45 @@ public class UserWriteToMetingController : ControllerBase | |||||||
|         return Ok(reviews); |         return Ok(reviews); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public interface IEmailService | ||||||
|  | { | ||||||
|  |     public Task SendEmailAsync(string email, string subject, string message); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class EmailService : IEmailService | ||||||
|  | { | ||||||
|  |     private readonly IConfiguration _configuration; | ||||||
|  |     private ILogger<EmailService> _logger; | ||||||
|  |  | ||||||
|  |     public EmailService(IConfiguration configuration, ILogger<EmailService> logger) | ||||||
|  |     { | ||||||
|  |         _configuration = configuration; | ||||||
|  |         _logger = logger; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task SendEmailAsync(string email, string subject, string message) | ||||||
|  |     { | ||||||
|  |         var emailMessage = new MimeMessage(); | ||||||
|  |  | ||||||
|  |         emailMessage.From.Add(new MailboxAddress(_configuration["Email:Name"], _configuration["Email:Address"])); | ||||||
|  |         emailMessage.To.Add(new MailboxAddress("", email)); | ||||||
|  |         emailMessage.Subject = subject; | ||||||
|  |         emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html) | ||||||
|  |         { | ||||||
|  |             Text = message | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         using var client = new SmtpClient(); | ||||||
|  |         client.Timeout = 15000; | ||||||
|  |         await client.ConnectAsync(_configuration["Email:Host"], int.Parse(_configuration["Email:Port"]!), SecureSocketOptions.None); | ||||||
|  |         await client.AuthenticateAsync(_configuration["Email:Address"], _configuration["Email:Password"]); | ||||||
|  |         await client.SendAsync(emailMessage); | ||||||
|  |          | ||||||
|  |         _logger.LogInformation("Письмо отправлено на почту {Email}", email); | ||||||
|  |          | ||||||
|  |         await client.DisconnectAsync(true); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -9,6 +9,11 @@ | |||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Hangfire.AspNetCore" Version="1.8.6" /> | ||||||
|  |     <PackageReference Include="Hangfire.Core" Version="1.8.6" /> | ||||||
|  |     <PackageReference Include="Hangfire.PostgreSql" Version="1.20.4" /> | ||||||
|  |     <PackageReference Include="Hangfire.PostgreSql.Npgsql5" Version="1.19.11" /> | ||||||
|  |     <PackageReference Include="MailKit" Version="4.3.0" /> | ||||||
|     <PackageReference Include="Mapster" Version="7.4.0" /> |     <PackageReference Include="Mapster" Version="7.4.0" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="7.0.14" /> |     <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="7.0.14" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.14" /> |     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.14" /> | ||||||
|   | |||||||
| @@ -7,7 +7,9 @@ using Microsoft.Extensions.FileProviders; | |||||||
| using Microsoft.OpenApi.Models; | using Microsoft.OpenApi.Models; | ||||||
| using Microsoft.AspNetCore.Authentication.Google; | using Microsoft.AspNetCore.Authentication.Google; | ||||||
| using Microsoft.AspNetCore.HttpOverrides; | using Microsoft.AspNetCore.HttpOverrides; | ||||||
|  | using Hangfire; | ||||||
|  | using Hangfire.PostgreSql; | ||||||
|  | using Hangfire.Dashboard; | ||||||
|  |  | ||||||
| TypeAdapterConfig<PutMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames());  | TypeAdapterConfig<PutMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames());  | ||||||
| TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames()); | TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames()); | ||||||
| @@ -50,6 +52,16 @@ builder.Services.AddAuthentication(opt => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | builder.Services.AddHangfire(configuration => configuration | ||||||
|  |         .SetDataCompatibilityLevel(CompatibilityLevel.Version_180) | ||||||
|  |         .UseSimpleAssemblyNameTypeSerializer() | ||||||
|  |         .UseRecommendedSerializerSettings() | ||||||
|  |         .UsePostgreSqlStorage(c => | ||||||
|  |         c.UseNpgsqlConnection(builder.Configuration["CONNECTION_STRING"]))); | ||||||
|  |         //.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"))); | ||||||
|  |  | ||||||
|  |     // Add the processing server as IHostedService | ||||||
|  | builder.Services.AddHangfireServer(); | ||||||
|  |  | ||||||
|  |  | ||||||
| builder.Services.AddControllers(); | builder.Services.AddControllers(); | ||||||
| @@ -87,12 +99,16 @@ builder.Services.AddCors(); | |||||||
|  |  | ||||||
| var app = builder.Build(); | var app = builder.Build(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| app.UseCors(builder => builder.AllowAnyMethod()); | app.UseCors(builder => builder.AllowAnyMethod()); | ||||||
| app.UseForwardedHeaders(new ForwardedHeadersOptions | app.UseForwardedHeaders(new ForwardedHeadersOptions | ||||||
| { | { | ||||||
|       ForwardedHeaders = ForwardedHeaders.XForwardedProto |       ForwardedHeaders = ForwardedHeaders.XForwardedProto | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| app.UseStaticFiles(new StaticFileOptions | app.UseStaticFiles(new StaticFileOptions | ||||||
| { | { | ||||||
|     FileProvider = new PhysicalFileProvider( |     FileProvider = new PhysicalFileProvider( | ||||||
| @@ -100,18 +116,44 @@ app.UseStaticFiles(new StaticFileOptions | |||||||
|     RequestPath = "/api/cyber-boom-files" |     RequestPath = "/api/cyber-boom-files" | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // Configure the HTTP request pipeline. | // Configure the HTTP request pipeline. | ||||||
| app.UseSwagger(); | app.UseSwagger(); | ||||||
| app.UseSwaggerUI(); | app.UseSwaggerUI(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| app.UseAuthentication();    // подключение аутентификации | app.UseAuthentication();    // подключение аутентификации | ||||||
| app.UseAuthorization(); | app.UseAuthorization(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | app.UseHangfireDashboard("/workers", new DashboardOptions | ||||||
|  | { | ||||||
|  |     Authorization = new [] { new AdminAuthorizationFilter() } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| app.MapControllers(); | app.MapControllers(); | ||||||
|  | app.MapHangfireDashboard(); | ||||||
| //app.MapRazorPages(); | //app.MapRazorPages(); | ||||||
|  |  | ||||||
| app.Run(); | app.Run(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public class AdminAuthorizationFilter : IDashboardAuthorizationFilter | ||||||
|  | { | ||||||
|  |     public bool Authorize(DashboardContext context) | ||||||
|  |     { | ||||||
|  |         var user = context.GetHttpContext().User; | ||||||
|  |  | ||||||
|  |         if (user.IsInRole("модератор")) | ||||||
|  |             return true; | ||||||
|  |  | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -8,5 +8,4 @@ | |||||||
|   }, |   }, | ||||||
|    |    | ||||||
|   "CONNECTION_STRING": "Host=localhost; Database=CyberBoomWellBeing; Username=postgres; Password=supper_password_123" |   "CONNECTION_STRING": "Host=localhost; Database=CyberBoomWellBeing; Username=postgres; Password=supper_password_123" | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user