forked from CyberBloom/CyberBloomBackend
сделал авторизация доабвил оптимизацию
This commit is contained in:
parent
6a32bc4fa9
commit
b4b5bfc1ed
@ -6,7 +6,9 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using static Consts;
|
||||
|
||||
namespace CyberBoom.Controllers;
|
||||
|
||||
@ -14,10 +16,6 @@ namespace CyberBoom.Controllers;
|
||||
[Route("/api/[controller]")]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
private readonly ApplicationContext _applicationContext;
|
||||
|
||||
private readonly UserManager<User> _userManager;
|
||||
@ -131,6 +129,25 @@ public class UsersController : ControllerBase
|
||||
role
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("stats")]
|
||||
public async Task<IActionResult> GetUserStats(string id)
|
||||
{
|
||||
var user = await _userManager.FindByIdAsync(id);
|
||||
|
||||
if(user is null)
|
||||
return BadRequest();
|
||||
|
||||
var stats = await _applicationContext.GetStatistic(id);
|
||||
|
||||
var achievmnets = _applicationContext.Achievments.Where(c => c.UserId == id);
|
||||
|
||||
|
||||
return Ok(new {
|
||||
Stats = stats,
|
||||
Achievments = achievmnets
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -202,7 +219,7 @@ public class MeetingsController : ControllerBase
|
||||
[HttpGet("list")]
|
||||
public IActionResult GetList(int offset, int limit)
|
||||
{
|
||||
var meetings = _applicationContext.Meetings.Skip(offset).Take(limit);
|
||||
var meetings = _applicationContext.Meetings.AsNoTracking().Skip(offset).Take(limit);
|
||||
|
||||
|
||||
return Ok(meetings);
|
||||
@ -272,7 +289,7 @@ public class ReviewsController : ControllerBase
|
||||
[HttpGet("list")]
|
||||
public IActionResult GetList(int offset, int limit)
|
||||
{
|
||||
var reviews = _applicationContext.Reviews
|
||||
var reviews = _applicationContext.Reviews.AsNoTracking()
|
||||
.Include(c => c.User)
|
||||
.Skip(offset)
|
||||
.Take(limit);
|
||||
@ -341,7 +358,7 @@ public class QuestionsController : ControllerBase
|
||||
[HttpGet("list")]
|
||||
public IActionResult GetList(int offset, int limit)
|
||||
{
|
||||
var questions = _applicationContext.Questions
|
||||
var questions = _applicationContext.Questions.AsNoTracking()
|
||||
.Include(c => c.User)
|
||||
.Skip(offset)
|
||||
.Take(limit);
|
||||
@ -398,32 +415,23 @@ public class ReactionsController : ControllerBase
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get(string id)
|
||||
{
|
||||
var review = await _applicationContext.Reviews
|
||||
var reaction = await _applicationContext.Reactions
|
||||
.FirstAsync(s => s.Id == id);
|
||||
|
||||
var user = await _applicationContext.Users.FirstAsync(s => s.Id == review.UserId);
|
||||
return Ok(new {
|
||||
review,
|
||||
user
|
||||
});
|
||||
|
||||
return Ok(reaction);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("list")]
|
||||
public IActionResult GetList(int offset, int limit)
|
||||
{
|
||||
var reviews = _applicationContext.Reviews
|
||||
var reactions = _applicationContext.Reactions.AsNoTracking()
|
||||
.Skip(offset)
|
||||
.Take(limit);
|
||||
|
||||
var users = _applicationContext.Users.Where(u => reviews.Select(u => u.UserId).Contains(u.Id));
|
||||
|
||||
return Ok(
|
||||
reviews.Select(s => new {
|
||||
review = s,
|
||||
user = users.First(u => u.Id == s.UserId)
|
||||
})
|
||||
);
|
||||
return Ok(reactions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,22 +457,83 @@ public class UserWriteToMetingController : ControllerBase
|
||||
{
|
||||
var dbWr = write.Adapt<UserWriteToMeting>();
|
||||
|
||||
var meeting = await _applicationContext.Meetings.FirstAsync(m => m.Id == write.MeetingId);
|
||||
|
||||
|
||||
|
||||
if(DateTime.UtcNow > meeting.Time)
|
||||
return BadRequest();
|
||||
|
||||
|
||||
|
||||
await _applicationContext.UserWriteToMetings.AddAsync(dbWr);
|
||||
|
||||
|
||||
var user = await _applicationContext.Users.FirstAsync(u => u.Id == write.UserId);
|
||||
|
||||
|
||||
var newStats = await _applicationContext.GetStatistic(write.UserId);
|
||||
|
||||
|
||||
var achievments = await WriteAchievment(newStats, write.UserId);
|
||||
|
||||
|
||||
await _applicationContext.SaveChangesAsync();
|
||||
|
||||
return Ok(new {
|
||||
dbWr.Id
|
||||
dbWr.Id,
|
||||
Achievments = achievments
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async Task<List<Achievment>> WriteAchievment(StatsData stats, string userId)
|
||||
{
|
||||
List <Achievment> achievments = new List<Achievment>();
|
||||
if(stats.Count > 0 && stats.Count % 5 == 0)
|
||||
{
|
||||
var achievment = new Achievment{
|
||||
Name = $"Редстоун Наблюдатель Level {stats.Count / 5}",
|
||||
Text = "Вы cамый настоящий Редстоун Наблюдатель из игры Майнкрафт, который не пропускате ни единой всречи!",
|
||||
UserId = userId
|
||||
};
|
||||
achievments.Add(achievment);
|
||||
await _applicationContext.Achievments.AddAsync(
|
||||
achievment
|
||||
);
|
||||
}
|
||||
var achievedTags = stats.StatsByTag.Where(st => st.Count > 0 && st.Count % 5 == 0);
|
||||
if(achievedTags.Count() > 0 && stats.Count % 5 == 0)
|
||||
{
|
||||
|
||||
foreach(var tag in achievedTags)
|
||||
{
|
||||
var achievment = new Achievment{
|
||||
Name = $"Вкачаю все в {tag.Tag} Level {tag.Count / 5}",
|
||||
Text = $"Вы нежалеете очки времени на ветку {tag.Tag}, продолжайте в том же духе!",
|
||||
UserId = userId
|
||||
};
|
||||
achievments.Add(achievment);
|
||||
await _applicationContext.Achievments.AddAsync(
|
||||
achievment
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
return achievments;
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
public async Task<IActionResult> Delete(string id)
|
||||
{
|
||||
|
||||
var fReview = await _applicationContext.UserWriteToMetings.FirstAsync(r => r.Id == id);
|
||||
|
||||
|
||||
var meeting = await _applicationContext.Meetings.FirstAsync(m => m.Id == fReview.MeetingId);
|
||||
|
||||
if(DateTime.UtcNow > meeting.Time)
|
||||
return BadRequest();
|
||||
|
||||
_applicationContext.UserWriteToMetings.Remove(fReview);
|
||||
|
||||
|
||||
@ -487,7 +556,7 @@ public class UserWriteToMetingController : ControllerBase
|
||||
[HttpGet("list")]
|
||||
public IActionResult GetList(int offset, int limit)
|
||||
{
|
||||
var reviews = _applicationContext.UserWriteToMetings
|
||||
var reviews = _applicationContext.UserWriteToMetings.AsNoTracking()
|
||||
.Skip(offset)
|
||||
.Take(limit);
|
||||
|
||||
|
@ -15,6 +15,8 @@ public class User : IdentityUser
|
||||
public string TelegramBotUrl { get; set; } = null!;
|
||||
|
||||
public int Level { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class UserPost
|
||||
@ -30,6 +32,23 @@ public class UserPost
|
||||
public string TelegramBotUrl { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class StatsData
|
||||
{
|
||||
public double Hours{ get; set; }
|
||||
|
||||
public int Count { get; set; }
|
||||
|
||||
public List<TagStats> StatsByTag { get; set; } = new List<TagStats>();
|
||||
|
||||
public class TagStats
|
||||
{
|
||||
public string Tag { get; set; } = null!;
|
||||
|
||||
public int Count { get; set; }
|
||||
|
||||
public double Hours { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class UserPut
|
||||
{
|
||||
@ -148,7 +167,7 @@ public class Meeting
|
||||
|
||||
public string SpeackerImage { get; set; } = null!;
|
||||
|
||||
public string Splecializations { get; set; } = null!;
|
||||
public string Splecializations { get; set; } = null!; //speacker specilization
|
||||
|
||||
|
||||
public string Type { get; set; } = "онлайн/офлайн";
|
||||
@ -254,6 +273,18 @@ public class Review
|
||||
}
|
||||
|
||||
|
||||
public class Achievment
|
||||
{
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public string Id { get; set; } = null!;
|
||||
|
||||
public string UserId { get; set; } = null!;
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
public string Text { get; set; } = null!;
|
||||
}
|
||||
|
||||
|
||||
public class PostReactionDto
|
||||
{
|
||||
@ -293,6 +324,9 @@ public class ApplicationContext : IdentityDbContext<User>
|
||||
|
||||
public DbSet<Question> Questions { get; set; }
|
||||
|
||||
|
||||
public DbSet<Achievment> Achievments { get; set; }
|
||||
|
||||
public ApplicationContext(DbContextOptions<ApplicationContext> options)
|
||||
: base(options)
|
||||
{
|
||||
@ -318,5 +352,7 @@ public class ApplicationContext : IdentityDbContext<User>
|
||||
|
||||
builder.Entity<Meeting>().HasMany<UserWriteToMeting>().WithOne().HasForeignKey(c => c.MeetingId);
|
||||
builder.Entity<UserWriteToMeting>().HasOne<User>().WithMany().HasForeignKey(c => c.UserId);
|
||||
|
||||
builder.Entity<Achievment>().HasOne<User>().WithMany().HasForeignKey(c => c.UserId);
|
||||
}
|
||||
}
|
@ -12,9 +12,9 @@ TypeAdapterConfig<PutMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage,
|
||||
TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.SpeackerImage, s => s.SpeackerImage.JoinFileNames());
|
||||
|
||||
|
||||
TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.Splecializations, s => String.Join(FILES_SEPORATOR_IN_STORE, s.Splecializations));
|
||||
TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.Splecializations, s => String.Join(TOKENS_SEPORATOR, s.Splecializations));
|
||||
|
||||
TypeAdapterConfig<PutMeetingDto, Meeting>.NewConfig().Map(d => d.Splecializations, s => String.Join(FILES_SEPORATOR_IN_STORE, s.Splecializations));
|
||||
TypeAdapterConfig<PutMeetingDto, Meeting>.NewConfig().Map(d => d.Splecializations, s => String.Join(TOKENS_SEPORATOR, s.Splecializations));
|
||||
|
||||
|
||||
TypeAdapterConfig<PostMeetingDto, Meeting>.NewConfig().Map(d => d.Time, s => s.Time.ToUniversalTime());
|
||||
@ -109,13 +109,24 @@ public class AuthOptions
|
||||
|
||||
public static class Consts
|
||||
{
|
||||
public const char FILES_SEPORATOR_IN_STORE = ';';
|
||||
public const char TOKENS_SEPORATOR = ';';
|
||||
}
|
||||
public static class PhileDataHelpers
|
||||
public static class DataHelpers
|
||||
{
|
||||
public static string JoinFileNames(this IEnumerable<IFormFile> files) => files.Select(s => s.FileName).JoinStrings();
|
||||
|
||||
public static string JoinStrings(this IEnumerable<string> files) => String.Join(FILES_SEPORATOR_IN_STORE, files.Select(s => s));
|
||||
public static string JoinStrings(this IEnumerable<string> files) => String.Join(TOKENS_SEPORATOR, files.Select(s => s));
|
||||
|
||||
public static TimeSpan ParseDuration(this string duration)
|
||||
{
|
||||
var durArr = duration.Split(TOKENS_SEPORATOR, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var hours = int.Parse(durArr.First());
|
||||
var minutes = int.Parse(durArr[1]);
|
||||
|
||||
return new TimeSpan(hours, minutes, 0);
|
||||
|
||||
}
|
||||
|
||||
public static async Task WriteFileToDirectory(this IFormFile file)
|
||||
{
|
||||
@ -133,4 +144,53 @@ public static class PhileDataHelpers
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async Task<StatsData> GetStatistic(this ApplicationContext applicationContext, string id)
|
||||
{
|
||||
var specialities = await applicationContext.UserWriteToMetings.Where(c => c.UserId == id)
|
||||
.Join(applicationContext.Meetings,
|
||||
m => m.MeetingId,
|
||||
m => m.Id,
|
||||
(c,m) => new {
|
||||
m.Tags,
|
||||
m.Id,
|
||||
m.Duration,
|
||||
m.Time
|
||||
}
|
||||
).Where(t => DateTime.UtcNow > t.Time).ToArrayAsync();
|
||||
|
||||
var selectedSpecialities = specialities.Select(s => new {
|
||||
s.Id,
|
||||
Tags = s.Tags.Split(TOKENS_SEPORATOR, StringSplitOptions.RemoveEmptyEntries),
|
||||
Duration = s.Duration.ParseDuration().TotalHours
|
||||
});
|
||||
|
||||
var allTags = selectedSpecialities.SelectMany(s => s.Tags).Distinct();
|
||||
var count = selectedSpecialities.Count();
|
||||
|
||||
StatsData stats = new StatsData{
|
||||
Count = count,
|
||||
Hours = selectedSpecialities.Sum(m => m.Duration) * count
|
||||
|
||||
};
|
||||
foreach(var tag in allTags)
|
||||
{
|
||||
//StatsData.TagStats
|
||||
var specByTag = selectedSpecialities.Where(f => f.Tags.Contains(tag));
|
||||
var countByTag = specByTag.Count();
|
||||
var hours = selectedSpecialities.Sum(s => s.Duration) * countByTag;
|
||||
|
||||
var stat = new StatsData.TagStats
|
||||
{
|
||||
Count = countByTag,
|
||||
Tag = tag,
|
||||
Hours = hours
|
||||
};
|
||||
stats.StatsByTag.Add(stat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user