diff --git a/VNH.Application/Common/Contants/ConstantNofication.cs b/VNH.Application/Common/Contants/ConstantNofication.cs new file mode 100644 index 0000000..7d3e573 --- /dev/null +++ b/VNH.Application/Common/Contants/ConstantNofication.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VNH.Application.Common.Contants +{ + public static class ConstantNofication + { + // Post + public static string CommentPost(string name) + { + return "[ "+name+" ]" + " đã bình luận một bài viết của bạn"; + } + public static string LikePost(string name) + { + return "[ " + name + " ]" + " đã thích một bài viết của bạn"; + } + + // Forum + public static string CommentAnswer(string name) + { + return "[ " + name + " ]" + " đã bình luận trong câu hỏi của bạn"; + } + public static string AnswerTheQuestion(string name) + { + return "[ " + name + " ]" + " đã 'trả lời' một câu hỏi của bạn"; + } + public static string LikeQuestion(string name) + { + return "[ " + name + " ]" + " đã tán thành một câu hỏi của bạn"; + } + public static string LikeAnswer(string name) + { + return "[ " + name + " ]" + " đã 'tán thành' một câu trả lời của bạn"; + } + } +} diff --git a/VNH.Application/Common/Contants/ConstantUrl.cs b/VNH.Application/Common/Contants/ConstantUrl.cs new file mode 100644 index 0000000..6be1838 --- /dev/null +++ b/VNH.Application/Common/Contants/ConstantUrl.cs @@ -0,0 +1,9 @@ + +namespace VNH.Application.Common.Contants +{ + public static class ConstantUrl + { + public const string UrlPostDetail = "/discover/"; + public const string UrlQuestionDetail = "/forum/"; + } +} diff --git a/VNH.Application/Common/Contants/SystemConstants.cs b/VNH.Application/Common/Contants/SystemConstants.cs index 7f3ebaf..b965aad 100644 --- a/VNH.Application/Common/Contants/SystemConstants.cs +++ b/VNH.Application/Common/Contants/SystemConstants.cs @@ -5,13 +5,13 @@ public static class SystemConstants public const string Token = "Token"; public const string BaseAddress = "BaseAddress"; - //public const string UrlWeb = "https://tyls.fun/"; - //public const string ConnectString = "Data Source=202.92.7.204\\MSSQLSERVER2022, 1438;Initial Catalog=tyls;User Id=toiyeulichsu;Password=MheZDu9$oGbrYlL#S%ApJ^qf;TrustServerCertificate=true; "; + public const string UrlWeb = "https://tyls.fun/"; + public const string ConnectString = "Data Source=202.92.7.204\\MSSQLSERVER2022, 1438;Initial Catalog=tyls;User Id=toiyeulichsu;Password=MheZDu9$oGbrYlL#S%ApJ^qf;TrustServerCertificate=true; "; //public const string UrlWeb = "https://vuanhpham25-001-site1.gtempurl.com/"; //public const string ConnectString = "Data Source=SQL5112.site4now.net;Initial Catalog=db_aa121e_vuanhpham25;User Id=db_aa121e_vuanhpham25_admin;Password=30102002Mai"; - public const string UrlWeb = "https://localhost:7138/"; - public const string ConnectString = "Data Source=.;Initial Catalog=tyls;Integrated Security=True;Encrypt=true;TrustServerCertificate=true;"; + //public const string UrlWeb = "https://localhost:7138/"; + //public const string ConnectString = "Data Source=.;Initial Catalog=tyls;Integrated Security=True;Encrypt=true;TrustServerCertificate=true;"; } } diff --git a/VNH.Application/DTOs/Catalog/Notifications/NotificationDto.cs b/VNH.Application/DTOs/Catalog/Notifications/NotificationDto.cs new file mode 100644 index 0000000..41fea2c --- /dev/null +++ b/VNH.Application/DTOs/Catalog/Notifications/NotificationDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VNH.Application.DTOs.Catalog.Notifications +{ + public class NotificationDto + { + public Guid? Id { get; set; } + public Guid UserId { get; set; } + public Guid? NotificationId { get; set; } = Guid.Empty; + public Guid? IdObject { get; set; } + public string? Content { get; set; } + public DateTime? Date { get; set; } + public string? Url { get; set; } + + } +} diff --git a/VNH.Application/Interfaces/Catalog/Forum/IAnswerService.cs b/VNH.Application/Interfaces/Catalog/Forum/IAnswerService.cs index 1480c56..eb0e3db 100644 --- a/VNH.Application/Interfaces/Catalog/Forum/IAnswerService.cs +++ b/VNH.Application/Interfaces/Catalog/Forum/IAnswerService.cs @@ -9,7 +9,7 @@ public interface IAnswerService { Task>> GetAnswer(string questionId); - Task>> CreateAnswer(AnswerQuestionDto answer); + Task>> CreateAnswer(AnswerQuestionDto answer, string? id); Task>> UpdateAnswer(AnswerQuestionDto answer); Task> DeteleAnswer(string id); diff --git a/VNH.Application/Interfaces/Catalog/NotificationServices/INotificationService.cs b/VNH.Application/Interfaces/Catalog/NotificationServices/INotificationService.cs new file mode 100644 index 0000000..5cc4032 --- /dev/null +++ b/VNH.Application/Interfaces/Catalog/NotificationServices/INotificationService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VNH.Application.DTOs.Catalog.Notifications; +using VNH.Application.DTOs.Common.ResponseNotification; +using VNH.Domain.Entities; + +namespace VNH.Application.Implement.Catalog.NotificationServices +{ + public interface INotificationService + { + Task>> GetAll(string userId); + Task> Add(string title); + Task AddNotificationDetail(NotificationDto notification); + Task> Update(NotificationDto notification); + } +} diff --git a/VNH.Application/Interfaces/Catalog/Posts/IPostService.cs b/VNH.Application/Interfaces/Catalog/Posts/IPostService.cs index b671a43..e2d781f 100644 --- a/VNH.Application/Interfaces/Catalog/Posts/IPostService.cs +++ b/VNH.Application/Interfaces/Catalog/Posts/IPostService.cs @@ -23,7 +23,7 @@ public interface IPostService Task> GetSave(PostFpkDto postFpk); Task>> GetPostByTag(string tag); Task>> GetComment(string postId); - Task>> CreateComment(CommentPostDto comment); + Task>> CreateComment(CommentPostDto comment, string userId); Task>> UpdateComment(CommentPostDto comment); Task>> DeteleComment(string id); Task>> GetMyPostSaved(string id); diff --git a/VNH.Application/Mappers/NotifiMapper.cs b/VNH.Application/Mappers/NotifiMapper.cs new file mode 100644 index 0000000..581f0b2 --- /dev/null +++ b/VNH.Application/Mappers/NotifiMapper.cs @@ -0,0 +1,20 @@ +using AutoMapper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VNH.Application.DTOs.Catalog.MultipleChoiceDto; +using VNH.Domain.Entities; +using VNH.Domain; +using VNH.Application.DTOs.Catalog.Notifications; + +namespace VNH.Application.Mappers +{ + public class NotifiMapper : Profile + { + public NotifiMapper() { + CreateMap().ReverseMap(); + } + } +} diff --git a/VNH.Application/VNH.Application.csproj b/VNH.Application/VNH.Application.csproj index ced845f..44a16ec 100644 --- a/VNH.Application/VNH.Application.csproj +++ b/VNH.Application/VNH.Application.csproj @@ -16,7 +16,6 @@ - diff --git a/VNH.Domain/Entities/ExamHistory.cs b/VNH.Domain/Entities/ExamHistory.cs index c2b6e80..264bd40 100644 --- a/VNH.Domain/Entities/ExamHistory.cs +++ b/VNH.Domain/Entities/ExamHistory.cs @@ -21,23 +21,13 @@ public partial class ExamHistory public Guid UserId { get; set; } public float Scores { get; set; } - public int CompletionTime { get; set; } [Column(TypeName = "datetime")] public DateTime StarDate { get; set; } - - - [ForeignKey("MultipleChoiceId")] + [InverseProperty("ExamHistory")] public virtual MultipleChoice MultipleChoice { get; set; } - - - - - - - } } diff --git a/VNH.Domain/Entities/ExamHistoryMultipleChoice.cs b/VNH.Domain/Entities/ExamHistoryMultipleChoice.cs new file mode 100644 index 0000000..e3391ef --- /dev/null +++ b/VNH.Domain/Entities/ExamHistoryMultipleChoice.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VNH.Domain.Entities +{ + public class ExamHistoryMultipleChoice + { + [Key] + public Guid Id { get; set; } + public Guid ExamHistoryId { get; set; } + public ExamHistory ExamHistory { get; set; } + + public Guid MultipleChoiceId { get; set; } + public MultipleChoice MultipleChoice { get; set; } + } +} diff --git a/VNH.Domain/Entities/MultipleChoice.cs b/VNH.Domain/Entities/MultipleChoice.cs index 2295416..adbbf76 100644 --- a/VNH.Domain/Entities/MultipleChoice.cs +++ b/VNH.Domain/Entities/MultipleChoice.cs @@ -12,7 +12,6 @@ namespace VNH.Domain.Entities [Table("MultipleChoise")] public partial class MultipleChoice { - [Key] public Guid Id { get; set; } @@ -22,30 +21,20 @@ public partial class MultipleChoice [Column(TypeName = "datetime")] public DateTime CreatedAt { get; set; } = DateTime.Now; - [Column(TypeName = "datetime")] public DateTime? UpdatedAt { get; set; } public int WorkTime { get; set; } - public Guid UserId { get; set; } - - - [InverseProperty("MultipleChoice")] public virtual ICollection Quiz { get; set; } - [ForeignKey("UserId")] public virtual User User { get; set; } [InverseProperty("MultipleChoice")] - public virtual ExamHistory ExamHistories { get; set; } - - - - + public virtual ICollection ExamHistory { get; set; } } } diff --git a/VNH.Domain/Entities/NotificationDetail.cs b/VNH.Domain/Entities/NotificationDetail.cs index 143b3db..a01e9b1 100644 --- a/VNH.Domain/Entities/NotificationDetail.cs +++ b/VNH.Domain/Entities/NotificationDetail.cs @@ -15,8 +15,10 @@ public class NotificationDetail public Guid Id { get; set; } public Guid NotificationId { get; set; } public Guid UserId { get; set; } + public Guid? IdObject { get; set; } public string? Content { get; set; } public DateTime Date { get; set; } + public string? Url { get; set; } public Confirm IsRead { get; set; } diff --git a/VNH.Infrastructure/DependencyInjectionInfrastructure.cs b/VNH.Infrastructure/DependencyInjectionInfrastructure.cs index 5e07495..7aa7ad0 100644 --- a/VNH.Infrastructure/DependencyInjectionInfrastructure.cs +++ b/VNH.Infrastructure/DependencyInjectionInfrastructure.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using VNH.Application.Services.Catalog.Users; @@ -38,6 +37,8 @@ using VNH.Infrastructure.Implement.Catalog.ExamHistorys; using VNH.Application.Interfaces.Catalog.NewsHistory; using VNH.Infrastructure.Implement.Catalog.NewsHistory; +using VNH.Application.Implement.Catalog.NotificationServices; +using VNH.Infrastructure.Implement.Catalog.NotificationServices; namespace VNH.Infrastructure { @@ -127,6 +128,7 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSignalR(); diff --git a/VNH.Infrastructure/Implement/Catalog/ExamHistorys/ExamHistoryService.cs b/VNH.Infrastructure/Implement/Catalog/ExamHistorys/ExamHistoryService.cs index a226333..1046bcf 100644 --- a/VNH.Infrastructure/Implement/Catalog/ExamHistorys/ExamHistoryService.cs +++ b/VNH.Infrastructure/Implement/Catalog/ExamHistorys/ExamHistoryService.cs @@ -47,7 +47,7 @@ public async Task> Create(CreateExamHistoryDt examhistory.MultipleChoiceId = requestDto.MultipleChoiceId; examhistory.UserId = requestDto.UserId; examhistory.StarDate = requestDto.StarDate; - examhistory.Scores = requestDto.Scores; + examhistory.Scores = float.Parse(requestDto.Scores.ToString()); examhistory.CompletionTime = requestDto.CompletionTime; try { @@ -95,7 +95,7 @@ public async Task> Update(CreateExamHistoryDto return new ApiErrorResult("Có lỗi xảy ra khi cập nhập kết quả!"); } updateExamHistory.StarDate = DateTime.Now; - updateExamHistory.Scores = requestDto.Scores; + updateExamHistory.Scores = float.Parse(requestDto.Scores.ToString()); updateExamHistory.CompletionTime = requestDto.CompletionTime; try diff --git a/VNH.Infrastructure/Implement/Catalog/Forum/AnswerService.cs b/VNH.Infrastructure/Implement/Catalog/Forum/AnswerService.cs index a609035..ade44e5 100644 --- a/VNH.Infrastructure/Implement/Catalog/Forum/AnswerService.cs +++ b/VNH.Infrastructure/Implement/Catalog/Forum/AnswerService.cs @@ -1,11 +1,16 @@ using AutoMapper; +using DocumentFormat.OpenXml.Office2010.Excel; +using DocumentFormat.OpenXml.Spreadsheet; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; +using VNH.Application.Common.Contants; using VNH.Application.DTOs.Catalog.Forum.Answer; +using VNH.Application.DTOs.Catalog.Notifications; using VNH.Application.DTOs.Catalog.Users; using VNH.Application.DTOs.Common; using VNH.Application.DTOs.Common.ResponseNotification; +using VNH.Application.Implement.Catalog.NotificationServices; using VNH.Application.Interfaces.Catalog.Forum; using VNH.Domain; using VNH.Infrastructure.Presenters; @@ -19,16 +24,16 @@ public class AnswerService : IAnswerService private readonly VietNamHistoryContext _dataContext; private readonly IHubContext _answerHubContext; private readonly IMapper _mapper; - + private readonly INotificationService _notificationService; public AnswerService(UserManager userManager, IHubContext answerHubContext, - IMapper mapper, - VietNamHistoryContext vietNamHistoryContext) + IMapper mapper, VietNamHistoryContext vietNamHistoryContext, INotificationService notificationService) { _userManager = userManager; _dataContext = vietNamHistoryContext; _mapper = mapper; _answerHubContext = answerHubContext; + _notificationService = notificationService; } private UserShortDto? GetUserShort(List users, Guid? IdUser) @@ -111,7 +116,7 @@ public async Task>> GetAnswer(string questionI - public async Task>> CreateAnswer(AnswerQuestionDto answer) + public async Task>> CreateAnswer(AnswerQuestionDto answer, string? id) { var question = await _dataContext.Questions.FirstOrDefaultAsync(x => x.Id.Equals(Guid.Parse(answer.QuestionId)) && !x.IsDeleted); if (question == null) @@ -121,9 +126,23 @@ public async Task>> CreateAnswer(AnswerQuestio Answer answerQuestion = _mapper.Map(answer); answerQuestion.QuestionId = question.Id; + _dataContext.Answers.Add(answerQuestion); await _dataContext.SaveChangesAsync(); + var user = await _dataContext.User.FirstOrDefaultAsync(x => x.Id.ToString().Equals(id) && !x.IsDeleted); + var noti = new NotificationDto() + { + Id = Guid.NewGuid(), + UserId = user.Id, + IdObject = question.Id, + Content = ConstantNofication.AnswerTheQuestion(user?.Fullname ?? ""), + Date = DateTime.Now, + Url = ConstantUrl.UrlQuestionDetail, + NotificationId = Guid.NewGuid() + }; + await _notificationService.AddNotificationDetail(noti); + var answers = await GetAnswer(answer.QuestionId); await _answerHubContext.Clients.All.SendAsync("ReceiveAnswer", answers); @@ -285,6 +304,21 @@ public async Task> VoteConfirmByUser(AnswerFpkDto answe AnswerId = Guid.Parse(answer.AnswerId), UserId = Guid.Parse(answer.UserId) }; + + var ans = await _dataContext.Answers.FirstOrDefaultAsync(x => !x.IsDeleted && x.Id.ToString() == answer.AnswerId); + var user = await _dataContext.User.FirstOrDefaultAsync(x => x.Id.ToString().Equals(ans.AuthorId) && !x.IsDeleted); + var noti = new NotificationDto() + { + Id = Guid.NewGuid(), + UserId = user.Id, + IdObject = Guid.Parse(answer.QuestionId), + Content = ConstantNofication.CommentAnswer(user?.Fullname ?? ""), + Date = DateTime.Now, + Url = ConstantUrl.UrlQuestionDetail, + NotificationId = Guid.NewGuid() + }; + await _notificationService.AddNotificationDetail(noti); + _dataContext.AnswerVotes.Add(answerVote); await _dataContext.SaveChangesAsync(); var numberVote = await _dataContext.AnswerVotes.Where(x => x.AnswerId == Guid.Parse(answer.AnswerId)).CountAsync(); diff --git a/VNH.Infrastructure/Implement/Catalog/Forum/QuestionService.cs b/VNH.Infrastructure/Implement/Catalog/Forum/QuestionService.cs index 457ad6e..d1ec637 100644 --- a/VNH.Infrastructure/Implement/Catalog/Forum/QuestionService.cs +++ b/VNH.Infrastructure/Implement/Catalog/Forum/QuestionService.cs @@ -4,10 +4,13 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; +using VNH.Application.Common.Contants; using VNH.Application.DTOs.Catalog.Forum.Question; +using VNH.Application.DTOs.Catalog.Notifications; using VNH.Application.DTOs.Catalog.Posts; using VNH.Application.DTOs.Common; using VNH.Application.DTOs.Common.ResponseNotification; +using VNH.Application.Implement.Catalog.NotificationServices; using VNH.Application.Interfaces.Catalog.Forum; using VNH.Domain; using VNH.Infrastructure.Implement.Common; @@ -20,15 +23,17 @@ public class QuestionService : IQuestionService private readonly UserManager _userManager; private readonly VietNamHistoryContext _dataContext; + private readonly INotificationService _notificationService; private readonly IMapper _mapper; public QuestionService(UserManager userManager, - IMapper mapper, + IMapper mapper, INotificationService notificationService, VietNamHistoryContext vietNamHistoryContext) { _userManager = userManager; _dataContext = vietNamHistoryContext; _mapper = mapper; + _notificationService = notificationService; } @@ -357,12 +362,25 @@ public async Task> AddOrUnLikeQuestion(QuestionFpkDto q var likeNumber = await _dataContext.QuestionLikes.Where(x => x.QuestionId == question.Id).CountAsync(); if (check is null) { + var user = await _dataContext.User.FirstOrDefaultAsync(x => !x.IsDeleted && x.Id == question.AuthorId); var like = new QuestionLike() { Id = Guid.NewGuid(), QuestionId = question.Id, UserId = Guid.Parse(questionFpk.UserId) }; + var noti = new NotificationDto() + { + Id = Guid.NewGuid(), + UserId = question.AuthorId ?? Guid.NewGuid(), + IdObject = question.Id, + Content = ConstantNofication.LikeQuestion(user?.Fullname ?? ""), + Date = DateTime.Now, + Url = ConstantUrl.UrlQuestionDetail, + NotificationId = Guid.NewGuid() + }; + await _notificationService.AddNotificationDetail(noti); + _dataContext.QuestionLikes.Add(like); await _dataContext.SaveChangesAsync(); return new ApiSuccessResult(new() { Check = true, Quantity = likeNumber + 1 }); @@ -468,7 +486,7 @@ orderby matchCount descending item.UserShort.Image = userShort.Image; } questions.Add(item); - } + } return new ApiSuccessResult>(questions); } diff --git a/VNH.Infrastructure/Implement/Catalog/MultipleChoices/MultipleChoiceService.cs b/VNH.Infrastructure/Implement/Catalog/MultipleChoices/MultipleChoiceService.cs index ae961b5..fbd54d4 100644 --- a/VNH.Infrastructure/Implement/Catalog/MultipleChoices/MultipleChoiceService.cs +++ b/VNH.Infrastructure/Implement/Catalog/MultipleChoices/MultipleChoiceService.cs @@ -335,7 +335,7 @@ public async Task> Update(CreateQuizDto requestDto, string nam { var user = await _userManager.FindByEmailAsync(name); - var updateMultipleChoice = _dataContext.MultipleChoices.First(x => x.Id.Equals(Guid.Parse(requestDto.Id))); + var updateMultipleChoice = await _dataContext.MultipleChoices.FirstOrDefaultAsync(x => x.Id == Guid.Parse(requestDto.Id)); if (updateMultipleChoice is null) { return new ApiErrorResult("Lỗi :Không được cập nhập (không tìm thấy bài thi nào)"); @@ -394,36 +394,61 @@ public async Task> UpdateQuizById(QuizDto requestDto) public async Task> Delete(string id, string userId) { - var multiple = await _dataContext.MultipleChoices.FirstOrDefaultAsync(x => x.Id.Equals(Guid.Parse(id)) && x.UserId.Equals(Guid.Parse(userId))); + var multiple = await _dataContext.MultipleChoices + .FirstOrDefaultAsync(x => x.Id.Equals(Guid.Parse(id)) && x.UserId.Equals(Guid.Parse(userId))); + if (multiple is null) { return new ApiErrorResult("Không tìm thấy bài thi"); } - var quizs = await _dataContext.Quizzes.ToListAsync(); - var quizsAnswer = await _dataContext.QuizAnswers.ToListAsync(); - foreach (var item in quizs) + var multipleChoiceId = multiple.Id; + + // Xoá lịch sử bài thi + var examHistoriesToDelete = _dataContext.ExamHistories + .Where(x => x.MultipleChoiceId == multipleChoiceId) + .ToList(); + + if (examHistoriesToDelete.Any()) { - if (item.MultipleChoiceId.Equals(id)) - { - foreach (var item1 in quizsAnswer) - { - if (item1.QuizId.Equals(item.Id)) - { - _dataContext.QuizAnswers.Remove(item1); - await _dataContext.SaveChangesAsync(); - } - } - _dataContext.Quizzes.Remove(item); - await _dataContext.SaveChangesAsync(); - } + _dataContext.ExamHistories.RemoveRange(examHistoriesToDelete); + } + + // Xoá câu trả lời của từng câu hỏi + var quizIdsToDelete = _dataContext.Quizzes + .Where(x => x.MultipleChoiceId.Equals(multipleChoiceId)) + .Select(x => x.Id) + .ToList(); + + var quizAnswerToDelete = _dataContext.QuizAnswers + .Where(x => quizIdsToDelete.Contains(x.QuizId)) + .ToList(); + + if (quizAnswerToDelete.Any()) + { + _dataContext.QuizAnswers.RemoveRange(quizAnswerToDelete); } + // Xoá câu hỏi + var quizzesToDelete = _dataContext.Quizzes + .Where(x => x.MultipleChoiceId.Equals(multipleChoiceId)) + .ToList(); + + if (quizzesToDelete.Any()) + { + _dataContext.Quizzes.RemoveRange(quizzesToDelete); + } + + // Xoá bài thi _dataContext.MultipleChoices.Remove(multiple); + + // Lưu thay đổi vào cơ sở dữ liệu await _dataContext.SaveChangesAsync(); + return new ApiSuccessResult("Xoá bài thi thành công"); } + public async Task> DeleteQuizById(string id) { var quiz = await _dataContext.Quizzes.FirstOrDefaultAsync(x => x.Id.Equals(Guid.Parse(id))); diff --git a/VNH.Infrastructure/Implement/Catalog/NotificationServices/NotificationService.cs b/VNH.Infrastructure/Implement/Catalog/NotificationServices/NotificationService.cs new file mode 100644 index 0000000..c9593ea --- /dev/null +++ b/VNH.Infrastructure/Implement/Catalog/NotificationServices/NotificationService.cs @@ -0,0 +1,91 @@ +using AutoMapper; +using Microsoft.AspNetCore.SignalR; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VNH.Application.DTOs.Catalog.Notifications; +using VNH.Application.DTOs.Common.ResponseNotification; +using VNH.Application.Implement.Catalog.NotificationServices; +using VNH.Domain.Entities; +using VNH.Domain.Enums; +using VNH.Infrastructure.Presenters; +using VNH.Infrastructure.Presenters.Migrations; + +namespace VNH.Infrastructure.Implement.Catalog.NotificationServices +{ + public class NotificationService : INotificationService + { + private readonly VietNamHistoryContext _dataContext; + private readonly IHubContext _notiHubContext; + private readonly IMapper _mapper; + public NotificationService(VietNamHistoryContext vietNamHistoryContext, IHubContext chatSignalR, + IMapper mapper ) + { + _dataContext = vietNamHistoryContext; + _notiHubContext = chatSignalR; + _mapper = mapper; + } + public async Task> Add(string title) + { + var noti = new Notification() + { + Title = title, + Id = Guid.NewGuid(), + Date = DateTime.Now, + }; + _dataContext.Notifications.Add(noti); + await _dataContext.SaveChangesAsync(); + + return new ApiSuccessResult(new()); + } + + public async Task AddNotificationDetail(NotificationDto notification) + { + var noti = await _dataContext.Notifications.FirstOrDefaultAsync(); + if (noti == null) + { + return; + } + var notificationDetail = new NotificationDetail() + { + Id = Guid.NewGuid(), + NotificationId = noti.Id, + UserId = notification.UserId, + Content = notification.Content, + Url = notification.Url, + Date = DateTime.Now, + IsRead = Confirm.No, + IdObject = notification.IdObject + }; + + _dataContext.NotificationDetails.Add(notificationDetail); + await _dataContext.SaveChangesAsync(); + await _notiHubContext.Clients.Group(notification.UserId.ToString()).SendAsync("ReceiveNoti", notification); + } + + public async Task>> GetAll(string userId) + { + var notidetails = await _dataContext.NotificationDetails.Where(x => x.UserId == Guid.Parse(userId)).ToListAsync(); + if (notidetails.Any()) + { + List result = new(); + foreach (var item in notidetails) + { + var notificationDetail = new NotificationDto(); + notificationDetail = _mapper.Map(item); + result.Add(notificationDetail); + } + return new ApiSuccessResult>(result); + } + return new ApiSuccessResult>(new()); + } + + public Task> Update(NotificationDto notification) + { + throw new NotImplementedException(); + } + } +} diff --git a/VNH.Infrastructure/Implement/Catalog/Posts/PostService.cs b/VNH.Infrastructure/Implement/Catalog/Posts/PostService.cs index b16e017..25e496c 100644 --- a/VNH.Infrastructure/Implement/Catalog/Posts/PostService.cs +++ b/VNH.Infrastructure/Implement/Catalog/Posts/PostService.cs @@ -6,10 +6,13 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; +using VNH.Application.Common.Contants; +using VNH.Application.DTOs.Catalog.Notifications; using VNH.Application.DTOs.Catalog.Posts; using VNH.Application.DTOs.Catalog.Users; using VNH.Application.DTOs.Common; using VNH.Application.DTOs.Common.ResponseNotification; +using VNH.Application.Implement.Catalog.NotificationServices; using VNH.Application.Interfaces.Common; using VNH.Application.Interfaces.Posts; using VNH.Domain; @@ -28,10 +31,11 @@ public class PostService : IPostService private readonly IStorageService _storageService; private readonly IHubContext _commentHubContext; private readonly IMapper _mapper; + private readonly INotificationService _notificationService; public PostService(UserManager userManager, IMapper mapper, IImageService image, VietNamHistoryContext vietNamHistoryContext, IStorageService storageService, - IHubContext chatSignalR) + IHubContext chatSignalR, INotificationService notificationService) { _userManager = userManager; _mapper = mapper; @@ -39,6 +43,7 @@ public PostService(UserManager userManager, IMapper mapper, IImageService _dataContext = vietNamHistoryContext; _storageService = storageService; _commentHubContext = chatSignalR; + _notificationService = notificationService; } public async Task> Create(CreatePostDto requestDto, string name) { @@ -281,14 +286,27 @@ public async Task> AddOrUnLikePost(PostFpkDto postFpk) var likeNumber = await _dataContext.PostLikes.Where(x => x.PostId == post.Id).CountAsync(); if (check is null) { + var user = await _dataContext.User.FirstOrDefaultAsync(x => !x.IsDeleted && x.Id == Guid.Parse(postFpk.UserId)); var like = new PostLike() { Id = Guid.NewGuid(), PostId = post.Id, UserId = Guid.Parse(postFpk.UserId) }; + var noti = new NotificationDto() + { + Id = Guid.NewGuid(), + UserId = post.UserId, + IdObject = Guid.Parse(post.Id), + Content = ConstantNofication.LikePost(user?.Fullname ?? ""), + Date = DateTime.Now, + Url = ConstantUrl.UrlPostDetail, + NotificationId = Guid.NewGuid() + }; + _dataContext.PostLikes.Add(like); await _dataContext.SaveChangesAsync(); + await _notificationService.AddNotificationDetail(noti); return new ApiSuccessResult(new() { Check = true, Quantity = likeNumber + 1}); } else { @@ -462,7 +480,7 @@ public async Task>> GetComment(string postId) .FirstOrDefault(); } - public async Task>> CreateComment(CommentPostDto comment) + public async Task>> CreateComment(CommentPostDto comment, string userId) { var post = await _dataContext.Posts.FirstOrDefaultAsync(x=>x.SubId.Equals(comment.PostId) && !x.IsDeleted); if (post == null) @@ -472,6 +490,25 @@ public async Task>> CreateComment(CommentPostDto PostComment postComment = _mapper.Map(comment); postComment.PostId = post.Id; postComment.UpdatedAt = DateTime.Now; + + if (userId != post.UserId.ToString()) + { + var user = await _dataContext.User.FirstOrDefaultAsync(x => x.Id.ToString().Equals(userId) && !x.IsDeleted); + var noti = new NotificationDto() + { + Id = Guid.NewGuid(), + UserId = post.UserId, + IdObject = Guid.Parse(post.Id), + Content = ConstantNofication.CommentPost(user?.Fullname ?? ""), + Date = DateTime.Now, + Url = ConstantUrl.UrlPostDetail, + NotificationId = Guid.NewGuid() + }; + + await _notificationService.AddNotificationDetail(noti); + } + + _dataContext.PostComments.Add(postComment); await _dataContext.SaveChangesAsync(); var comments = await GetComment(comment.PostId); diff --git a/VNH.Infrastructure/Implement/Common/StorageService.cs b/VNH.Infrastructure/Implement/Common/StorageService.cs index 957f922..2e6420c 100644 --- a/VNH.Infrastructure/Implement/Common/StorageService.cs +++ b/VNH.Infrastructure/Implement/Common/StorageService.cs @@ -44,8 +44,7 @@ public async Task SaveDocFileAsync(Stream mediaBinaryStream, string fileName) } public async Task DeleteFileAsync(string fileName) { - string name = Path.GetFileName(new Uri(fileName).LocalPath); - var filePath = Path.Combine(_userContentFolder, name); + var filePath = Path.Combine(_userContentFolder, fileName); if (File.Exists(filePath)) { await Task.Run(() => File.Delete(filePath)); diff --git a/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.Designer.cs b/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.Designer.cs new file mode 100644 index 0000000..4c8c567 --- /dev/null +++ b/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.Designer.cs @@ -0,0 +1,1916 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using VNH.Infrastructure.Presenters.Migrations; + +#nullable disable + +namespace VNH.Infrastructure.Migrations +{ + [DbContext(typeof(VietNamHistoryContext))] + [Migration("20231227095837_u_multi_exam_2")] + partial class u_multi_exam_2 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.13") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("AppRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(max)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId"); + + b.ToTable("AppUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserId", "RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId"); + + b.ToTable("AppUserTokens", (string)null); + }); + + modelBuilder.Entity("VNH.Domain.Answer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("Confirm") + .HasColumnType("bit"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MostConfirm") + .HasColumnType("bit"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("QuestionId"); + + b.ToTable("Answer"); + }); + + modelBuilder.Entity("VNH.Domain.AnswerVote", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AnswerId") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("AnswerId"); + + b.HasIndex("UserId"); + + b.ToTable("AnswerVote"); + }); + + modelBuilder.Entity("VNH.Domain.Course", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CourseName") + .IsRequired() + .HasMaxLength(255) + .IsUnicode(false) + .HasColumnType("varchar(255)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Image") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Course"); + }); + + modelBuilder.Entity("VNH.Domain.CourseComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("UserId"); + + b.ToTable("CourseComment"); + }); + + modelBuilder.Entity("VNH.Domain.CourseRating", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Score") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("UserId"); + + b.ToTable("CourseRating"); + }); + + modelBuilder.Entity("VNH.Domain.CourseSave", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("UserId"); + + b.ToTable("CourseSave"); + }); + + modelBuilder.Entity("VNH.Domain.CourseSubComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("PreCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PreCommentId"); + + b.HasIndex("UserId"); + + b.ToTable("CourseSubComment"); + }); + + modelBuilder.Entity("VNH.Domain.Document", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DownloadNumber") + .HasColumnType("int"); + + b.Property("FileName") + .HasColumnType("nvarchar(max)"); + + b.Property("FilePath") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("SubId") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ViewNumber") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Document"); + }); + + modelBuilder.Entity("VNH.Domain.DocumentSave", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("DocumentId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("UserId"); + + b.ToTable("DocumentSave"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.ExamHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CompletionTime") + .HasColumnType("int"); + + b.Property("MultipleChoiceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scores") + .HasColumnType("real"); + + b.Property("StarDate") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("MultipleChoiceId"); + + b.ToTable("ExamHistory"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("WorkTime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MultipleChoise"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.Notification", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Notification"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.NotificationDetail", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("IsRead") + .HasColumnType("int"); + + b.Property("NotificationId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationDetails"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.PostTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("PostId") + .IsRequired() + .HasColumnType("nvarchar(255)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("TagId"); + + b.ToTable("PostTags"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.QuizAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("QuizId") + .HasColumnType("uniqueidentifier"); + + b.Property("isCorrect") + .HasMaxLength(500) + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("QuizId"); + + b.ToTable("QuizAnswer"); + }); + + modelBuilder.Entity("VNH.Domain.Exercise", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Image") + .HasMaxLength(255) + .IsUnicode(false) + .HasColumnType("varchar(255)"); + + b.Property("QuizId") + .HasColumnType("uniqueidentifier"); + + b.Property("Time") + .HasColumnType("time"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(255) + .IsUnicode(false) + .HasColumnType("varchar(255)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.HasKey("Id"); + + b.ToTable("Exercise"); + }); + + modelBuilder.Entity("VNH.Domain.ExerciseDetail", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ExerciseId") + .HasColumnType("uniqueidentifier"); + + b.Property("TestMark") + .HasColumnType("float"); + + b.Property("TestTime") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ExerciseId"); + + b.HasIndex("UserId"); + + b.ToTable("ExerciseDetail"); + }); + + modelBuilder.Entity("VNH.Domain.Lesson", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ExerciseId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Title") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UrlVideo") + .HasMaxLength(255) + .IsUnicode(false) + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Lesson"); + }); + + modelBuilder.Entity("VNH.Domain.News", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Image") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("News"); + }); + + modelBuilder.Entity("VNH.Domain.Post", b => + { + b.Property("Id") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Image") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("SubId") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Title") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("TopicId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ViewNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TopicId"); + + b.HasIndex("UserId"); + + b.ToTable("Post"); + }); + + modelBuilder.Entity("VNH.Domain.PostComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("PostId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostComment"); + }); + + modelBuilder.Entity("VNH.Domain.PostLike", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("PostId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostLike"); + }); + + modelBuilder.Entity("VNH.Domain.PostReportDetail", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Checked") + .HasColumnType("bit"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("PostId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ReportDate") + .HasColumnType("datetime2"); + + b.Property("ReportId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("ReportId"); + + b.HasIndex("UserId"); + + b.ToTable("PostReportDetail"); + }); + + modelBuilder.Entity("VNH.Domain.PostSave", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("PostId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostSave"); + }); + + modelBuilder.Entity("VNH.Domain.PostSubComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("PreCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PreCommentId"); + + b.HasIndex("UserId"); + + b.ToTable("PostSubComment"); + }); + + modelBuilder.Entity("VNH.Domain.Question", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("SubId") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.Property("ViewNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Question"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionLike", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("UserId"); + + b.ToTable("QuestionLike"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionReportDetail", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Checked") + .HasColumnType("bit"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("ReportDate") + .HasColumnType("datetime2"); + + b.Property("ReportId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("ReportId"); + + b.HasIndex("UserId"); + + b.ToTable("QuestionReportDetail"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionSave", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("UserId"); + + b.ToTable("QuestionSave"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionTag", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("TagId"); + + b.ToTable("QuestionTag"); + }); + + modelBuilder.Entity("VNH.Domain.Quiz", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("MultipleChoiceId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("MultipleChoiceId"); + + b.ToTable("Quiz"); + }); + + modelBuilder.Entity("VNH.Domain.Report", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.ToTable("Report"); + }); + + modelBuilder.Entity("VNH.Domain.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("VNH.Domain.Search", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Search"); + }); + + modelBuilder.Entity("VNH.Domain.SubAnswer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("PreAnswerId") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PreAnswerId"); + + b.ToTable("SubAnswer"); + }); + + modelBuilder.Entity("VNH.Domain.Tag", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.ToTable("Tag"); + }); + + modelBuilder.Entity("VNH.Domain.Topic", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("Title") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Topic"); + }); + + modelBuilder.Entity("VNH.Domain.TopicDetail", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("PostId") + .HasColumnType("nvarchar(255)"); + + b.Property("TopicId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("TopicId"); + + b.ToTable("TopicDetail"); + }); + + modelBuilder.Entity("VNH.Domain.User", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("DateOfBirth") + .HasColumnType("datetime"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("Fullname") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Gender") + .HasColumnType("int"); + + b.Property("Image") + .HasMaxLength(3145728) + .HasColumnType("nvarchar(max)"); + + b.Property("Introduction") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(max)"); + + b.Property("NumberConfirm") + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("VNH.Domain.Answer", b => + { + b.HasOne("VNH.Domain.User", "Author") + .WithMany("Answers") + .HasForeignKey("AuthorId") + .HasConstraintName("FK__Answer__AuthorId__1AD3FDA4"); + + b.HasOne("VNH.Domain.Question", "Questions") + .WithMany("Answers") + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__Answer__QuestionId__1AD3FVA4"); + + b.Navigation("Author"); + + b.Navigation("Questions"); + }); + + modelBuilder.Entity("VNH.Domain.AnswerVote", b => + { + b.HasOne("VNH.Domain.Answer", "Answer") + .WithMany("AnswerVotes") + .HasForeignKey("AnswerId") + .HasConstraintName("FK__AnswerVot__Answe__1DB06A4F"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("AnswerVotes") + .HasForeignKey("UserId") + .HasConstraintName("FK__AnswerVot__UserI__1EA48E88"); + + b.Navigation("Answer"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Course", b => + { + b.HasOne("VNH.Domain.User", "User") + .WithMany("Courses") + .HasForeignKey("UserId") + .HasConstraintName("FK__Course__UserId__787EE5A0"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.CourseComment", b => + { + b.HasOne("VNH.Domain.Course", "Course") + .WithMany("CourseComments") + .HasForeignKey("CourseId") + .HasConstraintName("FK__CourseCom__Cours__7A672E12"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("CourseComments") + .HasForeignKey("UserId") + .HasConstraintName("FK__CourseCom__UserI__797309D9"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.CourseRating", b => + { + b.HasOne("VNH.Domain.Course", "Course") + .WithMany("CourseRatings") + .HasForeignKey("CourseId") + .HasConstraintName("FK__CourseRat__Cours__7D439ABD"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("CourseRatings") + .HasForeignKey("UserId") + .HasConstraintName("FK__CourseRat__UserI__7E37BEF6"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.CourseSave", b => + { + b.HasOne("VNH.Domain.Course", "Course") + .WithMany("CourseSaves") + .HasForeignKey("CourseId") + .HasConstraintName("FK__CourseSav__Cours__04E4BC85"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("CourseSaves") + .HasForeignKey("UserId") + .HasConstraintName("FK__CourseSav__UserI__03F0984C"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.CourseSubComment", b => + { + b.HasOne("VNH.Domain.CourseComment", "PreComment") + .WithMany("CourseSubComments") + .HasForeignKey("PreCommentId") + .HasConstraintName("FK__CourseSub__PreCo__7C4F7684"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("CourseSubComments") + .HasForeignKey("UserId") + .HasConstraintName("FK__CourseSub__UserI__7B5B524B"); + + b.Navigation("PreComment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Document", b => + { + b.HasOne("VNH.Domain.User", "User") + .WithMany("Documents") + .HasForeignKey("UserId") + .HasConstraintName("FK__Document__UserId__0A9D95DB"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.DocumentSave", b => + { + b.HasOne("VNH.Domain.Document", "Document") + .WithMany("DocumentSaves") + .HasForeignKey("DocumentId") + .HasConstraintName("FK__DocumentS__Docum__0C85DE4D"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("DocumentSaves") + .HasForeignKey("UserId") + .HasConstraintName("FK__DocumentS__UserI__0B91BA14"); + + b.Navigation("Document"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.ExamHistory", b => + { + b.HasOne("VNH.Domain.Entities.MultipleChoice", "MultipleChoice") + .WithMany("ExamHistory") + .HasForeignKey("MultipleChoiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__MultipleChoice__ExamHistoryId__06CD04F7"); + + b.Navigation("MultipleChoice"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => + { + b.HasOne("VNH.Domain.User", "User") + .WithMany("MultipleChoices") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__MultipleChoice__UserId__06CD04F7"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.NotificationDetail", b => + { + b.HasOne("VNH.Domain.Entities.Notification", "Notification") + .WithMany("NotificationDetails") + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__NotificationDetail__NotificationId__1EQ48E88"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("NotificationDetails") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__NotificationDetail__UserId__1EA48E88"); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.PostTag", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("PostTags") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("VNH.Domain.Tag", "Tag") + .WithMany("PostTags") + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + + b.Navigation("Tag"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.QuizAnswer", b => + { + b.HasOne("VNH.Domain.Quiz", "Quiz") + .WithMany("QuizAnswers") + .HasForeignKey("QuizId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__QuizAnswers__QuizId__1AD3FVA4"); + + b.Navigation("Quiz"); + }); + + modelBuilder.Entity("VNH.Domain.Exercise", b => + { + b.HasOne("VNH.Domain.Lesson", "IdNavigation") + .WithOne("Exercise") + .HasForeignKey("VNH.Domain.Exercise", "Id") + .IsRequired() + .HasConstraintName("FK__Exercise__Id__282DF8C2"); + + b.Navigation("IdNavigation"); + }); + + modelBuilder.Entity("VNH.Domain.ExerciseDetail", b => + { + b.HasOne("VNH.Domain.Exercise", "Exercise") + .WithMany("ExerciseDetails") + .HasForeignKey("ExerciseId") + .HasConstraintName("FK__ExerciseD__Exerc__02084FDA"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("ExerciseDetails") + .HasForeignKey("UserId") + .HasConstraintName("FK__ExerciseD__UserI__01142BA1"); + + b.Navigation("Exercise"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Lesson", b => + { + b.HasOne("VNH.Domain.Course", "Course") + .WithMany("Lessons") + .HasForeignKey("CourseId") + .HasConstraintName("FK__Lesson__CourseId__7F2BE32F"); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("VNH.Domain.Post", b => + { + b.HasOne("VNH.Domain.Topic", "Topic") + .WithMany("Posts") + .HasForeignKey("TopicId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__Post__TopicId__76969D2E"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("Posts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__Post__UserId__778AC167"); + + b.Navigation("Topic"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.PostComment", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("PostComments") + .HasForeignKey("PostId") + .HasConstraintName("FK__PostComme__PostI__0F624AF8"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("PostComments") + .HasForeignKey("UserId") + .HasConstraintName("FK__PostComme__UserI__10566F31"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.PostLike", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("PostLikes") + .HasForeignKey("PostId") + .HasConstraintName("FK__PostLike__PostId__1332DBDC"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("PostLikes") + .HasForeignKey("UserId") + .HasConstraintName("FK__PostLike__UserId__14270015"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.PostReportDetail", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("PostReportDetails") + .HasForeignKey("PostId") + .HasConstraintName("FK__PostRepor__PostI__17036CC0"); + + b.HasOne("VNH.Domain.Report", "Report") + .WithMany("PostReportDetails") + .HasForeignKey("ReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__PostRepor__Repor__151B244E"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("PostReportDetails") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__PostRepor__UserI__160F4887"); + + b.Navigation("Post"); + + b.Navigation("Report"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.PostSave", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("PostSaves") + .HasForeignKey("PostId") + .HasConstraintName("FK__PostSave__PostId__08B54D69"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("PostSaves") + .HasForeignKey("UserId") + .HasConstraintName("FK__PostSave__UserId__09A971A2"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.PostSubComment", b => + { + b.HasOne("VNH.Domain.PostComment", "PreComment") + .WithMany("PostSubComments") + .HasForeignKey("PreCommentId") + .HasConstraintName("FK__PostSubCo__PreCo__114A936A"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("PostSubComments") + .HasForeignKey("UserId") + .HasConstraintName("FK__PostSubCo__UserI__123EB7A3"); + + b.Navigation("PreComment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.Question", b => + { + b.HasOne("VNH.Domain.User", "Author") + .WithMany("Questions") + .HasForeignKey("AuthorId") + .HasConstraintName("FK__Question__Author__18EBB532"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionLike", b => + { + b.HasOne("VNH.Domain.Question", "Question") + .WithMany("QuestionLikes") + .HasForeignKey("QuestionId") + .HasConstraintName("FK__QuestionL__Quest__1F98B2C1"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("QuestionLikes") + .HasForeignKey("UserId") + .HasConstraintName("FK__QuestionL__UserI__208CD6FA"); + + b.Navigation("Question"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionReportDetail", b => + { + b.HasOne("VNH.Domain.Question", "Question") + .WithMany("QuestionReportDetails") + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__QuestionR__Quest__2180FB33"); + + b.HasOne("VNH.Domain.Report", "Report") + .WithMany("QuestionReportDetails") + .HasForeignKey("ReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__QuestionR__Quest__22751F6C"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("QuestionReportDetails") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__QuestionR__UserI__236943A5"); + + b.Navigation("Question"); + + b.Navigation("Report"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionSave", b => + { + b.HasOne("VNH.Domain.Question", "Question") + .WithMany("QuestionSaves") + .HasForeignKey("QuestionId") + .HasConstraintName("FK__QuestionS__Quest__25518C17"); + + b.HasOne("VNH.Domain.User", "User") + .WithMany("QuestionSaves") + .HasForeignKey("UserId") + .HasConstraintName("FK__QuestionS__UserI__245D67DE"); + + b.Navigation("Question"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.QuestionTag", b => + { + b.HasOne("VNH.Domain.Question", "Question") + .WithMany("QuestionTag") + .HasForeignKey("QuestionId") + .HasConstraintName("FK__QuestionTag__Id__2739D489"); + + b.HasOne("VNH.Domain.Tag", "Tag") + .WithMany("QuestionTags") + .HasForeignKey("TagId") + .HasConstraintName("FK__QuestionT__TagId__2645B050"); + + b.Navigation("Question"); + + b.Navigation("Tag"); + }); + + modelBuilder.Entity("VNH.Domain.Quiz", b => + { + b.HasOne("VNH.Domain.Entities.MultipleChoice", "MultipleChoice") + .WithMany("Quiz") + .HasForeignKey("MultipleChoiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK__MultipleChoice__Id__07C12930"); + + b.Navigation("MultipleChoice"); + }); + + modelBuilder.Entity("VNH.Domain.Search", b => + { + b.HasOne("VNH.Domain.User", "User") + .WithMany("Searches") + .HasForeignKey("UserId") + .HasConstraintName("FK__Search__UserId__17F790F9"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VNH.Domain.SubAnswer", b => + { + b.HasOne("VNH.Domain.User", "Author") + .WithMany("SubAnswers") + .HasForeignKey("AuthorId") + .HasConstraintName("FK__SubAnswer__Autho__1CBC4616"); + + b.HasOne("VNH.Domain.Answer", "PreAnswer") + .WithMany("SubAnswers") + .HasForeignKey("PreAnswerId") + .HasConstraintName("FK__SubAnswer__PreAn__1BC821DD"); + + b.Navigation("Author"); + + b.Navigation("PreAnswer"); + }); + + modelBuilder.Entity("VNH.Domain.Topic", b => + { + b.HasOne("VNH.Domain.User", "Author") + .WithMany("Topics") + .HasForeignKey("AuthorId") + .HasConstraintName("FK__Topic__AuthorId__05D8E0BE"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("VNH.Domain.TopicDetail", b => + { + b.HasOne("VNH.Domain.Post", "Post") + .WithMany("TopicDetails") + .HasForeignKey("PostId") + .HasConstraintName("FK__TopicDeta__TagId__07C12930"); + + b.HasOne("VNH.Domain.Topic", "Topic") + .WithMany("TopicDetails") + .HasForeignKey("TopicId") + .HasConstraintName("FK__TopicDeta__Topic__06CD04F7"); + + b.Navigation("Post"); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("VNH.Domain.Answer", b => + { + b.Navigation("AnswerVotes"); + + b.Navigation("SubAnswers"); + }); + + modelBuilder.Entity("VNH.Domain.Course", b => + { + b.Navigation("CourseComments"); + + b.Navigation("CourseRatings"); + + b.Navigation("CourseSaves"); + + b.Navigation("Lessons"); + }); + + modelBuilder.Entity("VNH.Domain.CourseComment", b => + { + b.Navigation("CourseSubComments"); + }); + + modelBuilder.Entity("VNH.Domain.Document", b => + { + b.Navigation("DocumentSaves"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => + { + b.Navigation("ExamHistory"); + + b.Navigation("Quiz"); + }); + + modelBuilder.Entity("VNH.Domain.Entities.Notification", b => + { + b.Navigation("NotificationDetails"); + }); + + modelBuilder.Entity("VNH.Domain.Exercise", b => + { + b.Navigation("ExerciseDetails"); + }); + + modelBuilder.Entity("VNH.Domain.Lesson", b => + { + b.Navigation("Exercise"); + }); + + modelBuilder.Entity("VNH.Domain.Post", b => + { + b.Navigation("PostComments"); + + b.Navigation("PostLikes"); + + b.Navigation("PostReportDetails"); + + b.Navigation("PostSaves"); + + b.Navigation("PostTags"); + + b.Navigation("TopicDetails"); + }); + + modelBuilder.Entity("VNH.Domain.PostComment", b => + { + b.Navigation("PostSubComments"); + }); + + modelBuilder.Entity("VNH.Domain.Question", b => + { + b.Navigation("Answers"); + + b.Navigation("QuestionLikes"); + + b.Navigation("QuestionReportDetails"); + + b.Navigation("QuestionSaves"); + + b.Navigation("QuestionTag"); + }); + + modelBuilder.Entity("VNH.Domain.Quiz", b => + { + b.Navigation("QuizAnswers"); + }); + + modelBuilder.Entity("VNH.Domain.Report", b => + { + b.Navigation("PostReportDetails"); + + b.Navigation("QuestionReportDetails"); + }); + + modelBuilder.Entity("VNH.Domain.Tag", b => + { + b.Navigation("PostTags"); + + b.Navigation("QuestionTags"); + }); + + modelBuilder.Entity("VNH.Domain.Topic", b => + { + b.Navigation("Posts"); + + b.Navigation("TopicDetails"); + }); + + modelBuilder.Entity("VNH.Domain.User", b => + { + b.Navigation("AnswerVotes"); + + b.Navigation("Answers"); + + b.Navigation("CourseComments"); + + b.Navigation("CourseRatings"); + + b.Navigation("CourseSaves"); + + b.Navigation("CourseSubComments"); + + b.Navigation("Courses"); + + b.Navigation("DocumentSaves"); + + b.Navigation("Documents"); + + b.Navigation("ExerciseDetails"); + + b.Navigation("MultipleChoices"); + + b.Navigation("NotificationDetails"); + + b.Navigation("PostComments"); + + b.Navigation("PostLikes"); + + b.Navigation("PostReportDetails"); + + b.Navigation("PostSaves"); + + b.Navigation("PostSubComments"); + + b.Navigation("Posts"); + + b.Navigation("QuestionLikes"); + + b.Navigation("QuestionReportDetails"); + + b.Navigation("QuestionSaves"); + + b.Navigation("Questions"); + + b.Navigation("Searches"); + + b.Navigation("SubAnswers"); + + b.Navigation("Topics"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.cs b/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.cs new file mode 100644 index 0000000..977729d --- /dev/null +++ b/VNH.Infrastructure/Migrations/20231227095837_u_multi_exam_2.cs @@ -0,0 +1,129 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace VNH.Infrastructure.Migrations +{ + /// + public partial class u_multi_exam_2 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ExamHistory_MultipleChoise_MultipleChoiceId", + table: "ExamHistory"); + + migrationBuilder.DropIndex( + name: "IX_ExamHistory_MultipleChoiceId", + table: "ExamHistory"); + + + migrationBuilder.CreateIndex( + name: "IX_ExamHistory_MultipleChoiceId", + table: "ExamHistory", + column: "MultipleChoiceId"); + + migrationBuilder.AddForeignKey( + name: "FK__MultipleChoice__ExamHistoryId__06CD04F7", + table: "ExamHistory", + column: "MultipleChoiceId", + principalTable: "MultipleChoise", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK__MultipleChoice__ExamHistoryId__06CD04F7", + table: "ExamHistory"); + + migrationBuilder.DropIndex( + name: "IX_ExamHistory_MultipleChoiceId", + table: "ExamHistory"); + + migrationBuilder.InsertData( + table: "Report", + columns: new[] { "Id", "CreatedAt", "Description", "Title" }, + values: new object[,] + { + { new Guid("25752490-4ba5-4abb-ac3b-192205cd1b6e"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(393), "Sử dụng khi bạn thấy nội dung bài đăng chứa lời lẽ xúc phạm, kỳ thị hoặc có tính chất đe doạ đến người khác.", "Nội dung xấu, xúc phạm, hay kỳ thị" }, + { new Guid("3043c693-b3c9-453e-9876-31c943222576"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(411), "Dùng khi bạn muốn báo cáo vì nó quá nhiều thông báo hoặc quảng cáo không mong muốn.", "Nội dung xuất hiện quá nhiều thông báo hoặc quảng cáo không mong muốn" }, + { new Guid("349ed807-6107-436f-9a4c-9d6183fbc444"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(403), "Sử dụng khi bạn thấy nội dung chứa hình ảnh tự tử hoặc khuyến khích hành vi tự gây thương tổn.", "Chứa nội dung tự tử hoặc tự gây thương tổn" }, + { new Guid("4a780087-9058-41c9-b84b-944d1a502010"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(408), "Sử dụng khi bạn thấy rằng nội dung chứa thông tin sai lệch, giả mạo hoặc vi phạm quy tắc về sự thật và trung thực.", "Bài đăng chứa thông tin sai lệch hoặc giả mạo" }, + { new Guid("bab1da58-6921-44b9-837f-c58d3998497b"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(400), "Dùng khi bạn thấy nội dung chứa hình ảnh hoặc video bạo lực hoặc đội nhóm xấu, hoặc khuyến khích hành vi bạo lực.", "Chứa nội dung bạo lực hoặc đội nhóm xấu" }, + { new Guid("c4ddb872-06c5-4779-a8a3-a55e5b2c5347"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(406), "Sử dụng khi bạn cho rằng Nội dung vi phạm quyền sở hữu trí tuệ hoặc bản quyền, chẳng hạn như sử dụng hình ảnh hoặc video mà bạn sở hữu mà không có sự cho phép.", "Nội dung vi phạm bản quyền hoặc sở hữu trí tuệ" }, + { new Guid("d30e1353-0163-43c1-b757-7957981b0eda"), new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(380), " Báo cáo này được sử dụng khi người dùng chia sẻ nội dung cá nhân của bạn mà bạn cho rằng vi phạm quyền riêng tư của bạn.", "Nội dung vi phạm quy định về quyền riêng tư" } + }); + + migrationBuilder.InsertData( + table: "Roles", + columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" }, + values: new object[,] + { + { new Guid("5d4e4081-91f8-4fc0-b8eb-9860b7849604"), "fd6f7cf8-8977-4b47-85a9-22d25d605913", "student", "student" }, + { new Guid("a18be9c0-aa65-4af8-bd17-00bd9344e575"), "7384f037-6d8d-48a6-a154-195d3a5db7ab", "admin", "admin" }, + { new Guid("cfafcfcd-d796-43f4-8ac0-ead43bd2f18a"), "a6163b8e-97ec-498b-8fd9-e465ff3543e1", "teacher", "teacher" } + }); + + migrationBuilder.InsertData( + table: "User", + columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "DateOfBirth", "Email", "EmailConfirmed", "Fullname", "Gender", "Image", "Introduction", "IsDeleted", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "NumberConfirm", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName" }, + values: new object[] { new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), 0, "655f7435-dbfe-418e-a873-2a98f7518f62", new DateTime(2002, 3, 18, 0, 0, 0, 0, DateTimeKind.Local), "admin@gmail.com", true, "Lương Xuân Nhất", 0, "", null, false, false, null, "onionwebdev@gmail.com", "admin", null, "AQAAAAEAACcQAAAAEOtQFl2yzdrxjnrsTdsQC9KSysBJv5jjIYf4CZbwHIO7kgkPifjNSf1I4MigYSkbRw==", null, false, "", false, "admin" }); + + migrationBuilder.InsertData( + table: "UserRoles", + columns: new[] { "RoleId", "UserId" }, + values: new object[] { new Guid("a18be9c0-aa65-4af8-bd17-00bd9344e575"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5") }); + + migrationBuilder.InsertData( + table: "Topic", + columns: new[] { "Id", "AuthorId", "CreatedAt", "Title", "UpdatedAt" }, + values: new object[,] + { + { new Guid("00000000-0000-0000-0000-000000000000"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Lịch sử Cổ đại", null }, + { new Guid("208c6340-0a32-492f-afcb-e522ee62a379"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Thời kỳ đổi mới", null }, + { new Guid("30006f7c-d22b-4f57-a4a0-2004bbd7cc5d"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Đời sống trong xã cổ Đông Sơn.", null }, + { new Guid("301eba8b-5332-4501-ae39-4a0475784012"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Anh hùng", null }, + { new Guid("3167df9b-f1d8-4da8-a719-2d9c72618788"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Phong trào Duy Tân", null }, + { new Guid("3a5050ee-fc0c-4063-b81e-4dbd58bd1bf2"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Thời kỳ thuộc địa Pháp", null }, + { new Guid("45b5a102-1a0f-4a01-b3ad-87033c628a74"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Văn hóa và Nghệ thuật", null }, + { new Guid("493af5b6-a3f9-45b4-a2e4-25feef7ad6d8"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Văn hóa dân gian", null }, + { new Guid("52463519-05b1-4ad8-a501-ce6073592f7b"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Những thăng trầm của triều đại Lê", null }, + { new Guid("570b164e-e22e-464c-b224-d2a0309e3065"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Nghệ thuật và văn hóa đương đại", null }, + { new Guid("5c414d41-5620-48a4-88c7-61c9a0174243"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Lịch sử thời kỳ thuộc địa", null }, + { new Guid("68b43a88-5ef2-494a-b0fe-5bb1705e0736"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Nhà Hậu Lê", null }, + { new Guid("80bc02ad-9401-4280-a76d-9fa5f7813dd1"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Thời kỳ Trung đại", null }, + { new Guid("8b2d71a5-ccfd-45ae-9bf3-565b56b73931"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Vương quốc Âu Lạc.", null }, + { new Guid("92d0fb18-3849-46a7-b6b0-fe76898549a1"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Chính sách đổi mới", null }, + { new Guid("987d7996-c324-4585-b86a-cb2a13e2171d"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Nhà Nguyễn", null }, + { new Guid("cc7d45d9-1ffb-460e-9966-8a81e8803896"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Chiến tranh Việt Nam", null }, + { new Guid("d4a56cbc-e450-4323-be8f-a0606ed5dfe5"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Thách thức hiện đại hóa", null }, + { new Guid("dd41bdc9-d9d0-4e4f-a8f7-7066fbda0cdc"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Giao lưu văn hóa quốc tế", null }, + { new Guid("e932683e-fa11-4adb-8409-93fb40e23315"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Chiến tranh Pháp-Đông Dương", null }, + { new Guid("faa13d37-2f3a-447b-92ab-0a26126273e8"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Triều đại Lý.", null }, + { new Guid("fd826d64-1f87-436d-82c9-7009d2571199"), new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), null, "Chiến tranh Việt Nam", null } + }); + + migrationBuilder.CreateIndex( + name: "IX_ExamHistory_MultipleChoiceId", + table: "ExamHistory", + column: "MultipleChoiceId", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_ExamHistory_MultipleChoise_MultipleChoiceId", + table: "ExamHistory", + column: "MultipleChoiceId", + principalTable: "MultipleChoise", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/VNH.Infrastructure/Migrations/20231227092843_u_exam_history.Designer.cs b/VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.Designer.cs similarity index 97% rename from VNH.Infrastructure/Migrations/20231227092843_u_exam_history.Designer.cs rename to VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.Designer.cs index a35a75e..c08fb8f 100644 --- a/VNH.Infrastructure/Migrations/20231227092843_u_exam_history.Designer.cs +++ b/VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.Designer.cs @@ -12,8 +12,8 @@ namespace VNH.Infrastructure.Migrations { [DbContext(typeof(VietNamHistoryContext))] - [Migration("20231227092843_u_exam_history")] - partial class u_exam_history + [Migration("20231228061045_update_notification_detail")] + partial class update_notification_detail { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -410,30 +410,9 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("ExamHistory"); - }); - - modelBuilder.Entity("VNH.Domain.Entities.ExamHistoryMultipleChoice", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ExamHistoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("MultipleChoiceId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("ExamHistoryId"); - b.HasIndex("MultipleChoiceId"); - b.ToTable("ExamHistoryMultipleChoice"); + b.ToTable("ExamHistory"); }); modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => @@ -496,12 +475,18 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Date") .HasColumnType("datetime2"); + b.Property("IdObject") + .HasColumnType("uniqueidentifier"); + b.Property("IsRead") .HasColumnType("int"); b.Property("NotificationId") .HasColumnType("uniqueidentifier"); + b.Property("Url") + .HasColumnType("nvarchar(max)"); + b.Property("UserId") .HasColumnType("uniqueidentifier"); @@ -1382,21 +1367,14 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("User"); }); - modelBuilder.Entity("VNH.Domain.Entities.ExamHistoryMultipleChoice", b => + modelBuilder.Entity("VNH.Domain.Entities.ExamHistory", b => { - b.HasOne("VNH.Domain.Entities.ExamHistory", "ExamHistory") - .WithMany("ExamHistoryMultipleChoice") - .HasForeignKey("ExamHistoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - b.HasOne("VNH.Domain.Entities.MultipleChoice", "MultipleChoice") - .WithMany("ExamHistoryMultipleChoice") + .WithMany("ExamHistory") .HasForeignKey("MultipleChoiceId") .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("ExamHistory"); + .IsRequired() + .HasConstraintName("FK__MultipleChoice__ExamHistoryId__06CD04F7"); b.Navigation("MultipleChoice"); }); @@ -1805,14 +1783,9 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("DocumentSaves"); }); - modelBuilder.Entity("VNH.Domain.Entities.ExamHistory", b => - { - b.Navigation("ExamHistoryMultipleChoice"); - }); - modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => { - b.Navigation("ExamHistoryMultipleChoice"); + b.Navigation("ExamHistory"); b.Navigation("Quiz"); }); diff --git a/VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.cs b/VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.cs new file mode 100644 index 0000000..54604ff --- /dev/null +++ b/VNH.Infrastructure/Migrations/20231228061045_update_notification_detail.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace VNH.Infrastructure.Migrations +{ + /// + public partial class update_notification_detail : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IdObject", + table: "NotificationDetails", + type: "uniqueidentifier", + nullable: true); + + migrationBuilder.AddColumn( + name: "Url", + table: "NotificationDetails", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IdObject", + table: "NotificationDetails"); + + migrationBuilder.DropColumn( + name: "Url", + table: "NotificationDetails"); + } + } +} diff --git a/VNH.Infrastructure/Migrations/VietNamHistoryContextModelSnapshot.cs b/VNH.Infrastructure/Migrations/VietNamHistoryContextModelSnapshot.cs index 15fb6fe..8cd9804 100644 --- a/VNH.Infrastructure/Migrations/VietNamHistoryContextModelSnapshot.cs +++ b/VNH.Infrastructure/Migrations/VietNamHistoryContextModelSnapshot.cs @@ -97,13 +97,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("UserId", "RoleId"); b.ToTable("UserRoles", (string)null); - - b.HasData( - new - { - UserId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - RoleId = new Guid("a18be9c0-aa65-4af8-bd17-00bd9344e575") - }); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => @@ -414,8 +407,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("MultipleChoiceId") - .IsUnique(); + b.HasIndex("MultipleChoiceId"); b.ToTable("ExamHistory"); }); @@ -480,12 +472,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Date") .HasColumnType("datetime2"); + b.Property("IdObject") + .HasColumnType("uniqueidentifier"); + b.Property("IsRead") .HasColumnType("int"); b.Property("NotificationId") .HasColumnType("uniqueidentifier"); + b.Property("Url") + .HasColumnType("nvarchar(max)"); + b.Property("UserId") .HasColumnType("uniqueidentifier"); @@ -1021,57 +1019,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); b.ToTable("Report"); - - b.HasData( - new - { - Id = new Guid("d30e1353-0163-43c1-b757-7957981b0eda"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(380), - Description = " Báo cáo này được sử dụng khi người dùng chia sẻ nội dung cá nhân của bạn mà bạn cho rằng vi phạm quyền riêng tư của bạn.", - Title = "Nội dung vi phạm quy định về quyền riêng tư" - }, - new - { - Id = new Guid("25752490-4ba5-4abb-ac3b-192205cd1b6e"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(393), - Description = "Sử dụng khi bạn thấy nội dung bài đăng chứa lời lẽ xúc phạm, kỳ thị hoặc có tính chất đe doạ đến người khác.", - Title = "Nội dung xấu, xúc phạm, hay kỳ thị" - }, - new - { - Id = new Guid("bab1da58-6921-44b9-837f-c58d3998497b"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(400), - Description = "Dùng khi bạn thấy nội dung chứa hình ảnh hoặc video bạo lực hoặc đội nhóm xấu, hoặc khuyến khích hành vi bạo lực.", - Title = "Chứa nội dung bạo lực hoặc đội nhóm xấu" - }, - new - { - Id = new Guid("349ed807-6107-436f-9a4c-9d6183fbc444"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(403), - Description = "Sử dụng khi bạn thấy nội dung chứa hình ảnh tự tử hoặc khuyến khích hành vi tự gây thương tổn.", - Title = "Chứa nội dung tự tử hoặc tự gây thương tổn" - }, - new - { - Id = new Guid("c4ddb872-06c5-4779-a8a3-a55e5b2c5347"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(406), - Description = "Sử dụng khi bạn cho rằng Nội dung vi phạm quyền sở hữu trí tuệ hoặc bản quyền, chẳng hạn như sử dụng hình ảnh hoặc video mà bạn sở hữu mà không có sự cho phép.", - Title = "Nội dung vi phạm bản quyền hoặc sở hữu trí tuệ" - }, - new - { - Id = new Guid("4a780087-9058-41c9-b84b-944d1a502010"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(408), - Description = "Sử dụng khi bạn thấy rằng nội dung chứa thông tin sai lệch, giả mạo hoặc vi phạm quy tắc về sự thật và trung thực.", - Title = "Bài đăng chứa thông tin sai lệch hoặc giả mạo" - }, - new - { - Id = new Guid("3043c693-b3c9-453e-9876-31c943222576"), - CreatedAt = new DateTime(2023, 12, 22, 13, 54, 20, 961, DateTimeKind.Local).AddTicks(411), - Description = "Dùng khi bạn muốn báo cáo vì nó quá nhiều thông báo hoặc quảng cáo không mong muốn.", - Title = "Nội dung xuất hiện quá nhiều thông báo hoặc quảng cáo không mong muốn" - }); }); modelBuilder.Entity("VNH.Domain.Role", b => @@ -1092,29 +1039,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); b.ToTable("Roles"); - - b.HasData( - new - { - Id = new Guid("a18be9c0-aa65-4af8-bd17-00bd9344e575"), - ConcurrencyStamp = "7384f037-6d8d-48a6-a154-195d3a5db7ab", - Name = "admin", - NormalizedName = "admin" - }, - new - { - Id = new Guid("cfafcfcd-d796-43f4-8ac0-ead43bd2f18a"), - ConcurrencyStamp = "a6163b8e-97ec-498b-8fd9-e465ff3543e1", - Name = "teacher", - NormalizedName = "teacher" - }, - new - { - Id = new Guid("5d4e4081-91f8-4fc0-b8eb-9860b7849604"), - ConcurrencyStamp = "fd6f7cf8-8977-4b47-85a9-22d25d605913", - Name = "student", - NormalizedName = "student" - }); }); modelBuilder.Entity("VNH.Domain.Search", b => @@ -1202,140 +1126,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("AuthorId"); b.ToTable("Topic"); - - b.HasData( - new - { - Id = new Guid("00000000-0000-0000-0000-000000000000"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Lịch sử Cổ đại" - }, - new - { - Id = new Guid("80bc02ad-9401-4280-a76d-9fa5f7813dd1"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Thời kỳ Trung đại" - }, - new - { - Id = new Guid("5c414d41-5620-48a4-88c7-61c9a0174243"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Lịch sử thời kỳ thuộc địa" - }, - new - { - Id = new Guid("fd826d64-1f87-436d-82c9-7009d2571199"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Chiến tranh Việt Nam" - }, - new - { - Id = new Guid("208c6340-0a32-492f-afcb-e522ee62a379"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Thời kỳ đổi mới" - }, - new - { - Id = new Guid("45b5a102-1a0f-4a01-b3ad-87033c628a74"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Văn hóa và Nghệ thuật" - }, - new - { - Id = new Guid("30006f7c-d22b-4f57-a4a0-2004bbd7cc5d"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Đời sống trong xã cổ Đông Sơn." - }, - new - { - Id = new Guid("8b2d71a5-ccfd-45ae-9bf3-565b56b73931"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Vương quốc Âu Lạc." - }, - new - { - Id = new Guid("faa13d37-2f3a-447b-92ab-0a26126273e8"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Triều đại Lý." - }, - new - { - Id = new Guid("52463519-05b1-4ad8-a501-ce6073592f7b"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Những thăng trầm của triều đại Lê" - }, - new - { - Id = new Guid("3a5050ee-fc0c-4063-b81e-4dbd58bd1bf2"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Thời kỳ thuộc địa Pháp" - }, - new - { - Id = new Guid("3167df9b-f1d8-4da8-a719-2d9c72618788"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Phong trào Duy Tân" - }, - new - { - Id = new Guid("e932683e-fa11-4adb-8409-93fb40e23315"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Chiến tranh Pháp-Đông Dương" - }, - new - { - Id = new Guid("cc7d45d9-1ffb-460e-9966-8a81e8803896"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Chiến tranh Việt Nam" - }, - new - { - Id = new Guid("92d0fb18-3849-46a7-b6b0-fe76898549a1"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Chính sách đổi mới" - }, - new - { - Id = new Guid("d4a56cbc-e450-4323-be8f-a0606ed5dfe5"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Thách thức hiện đại hóa" - }, - new - { - Id = new Guid("493af5b6-a3f9-45b4-a2e4-25feef7ad6d8"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Văn hóa dân gian" - }, - new - { - Id = new Guid("570b164e-e22e-464c-b224-d2a0309e3065"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Nghệ thuật và văn hóa đương đại" - }, - new - { - Id = new Guid("dd41bdc9-d9d0-4e4f-a8f7-7066fbda0cdc"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Giao lưu văn hóa quốc tế" - }, - new - { - Id = new Guid("987d7996-c324-4585-b86a-cb2a13e2171d"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Nhà Nguyễn" - }, - new - { - Id = new Guid("301eba8b-5332-4501-ae39-4a0475784012"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Anh hùng" - }, - new - { - Id = new Guid("68b43a88-5ef2-494a-b0fe-5bb1705e0736"), - AuthorId = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - Title = "Nhà Hậu Lê" - }); }); modelBuilder.Entity("VNH.Domain.TopicDetail", b => @@ -1431,29 +1221,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); b.ToTable("User"); - - b.HasData( - new - { - Id = new Guid("d1f771da-b318-42f8-a003-5a15614216f5"), - AccessFailedCount = 0, - ConcurrencyStamp = "655f7435-dbfe-418e-a873-2a98f7518f62", - DateOfBirth = new DateTime(2002, 3, 18, 0, 0, 0, 0, DateTimeKind.Local), - Email = "admin@gmail.com", - EmailConfirmed = true, - Fullname = "Lương Xuân Nhất", - Gender = 0, - Image = "", - IsDeleted = false, - LockoutEnabled = false, - NormalizedEmail = "onionwebdev@gmail.com", - NormalizedUserName = "admin", - PasswordHash = "AQAAAAEAACcQAAAAEOtQFl2yzdrxjnrsTdsQC9KSysBJv5jjIYf4CZbwHIO7kgkPifjNSf1I4MigYSkbRw==", - PhoneNumberConfirmed = false, - SecurityStamp = "", - TwoFactorEnabled = false, - UserName = "admin" - }); }); modelBuilder.Entity("VNH.Domain.Answer", b => @@ -1600,10 +1367,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("VNH.Domain.Entities.ExamHistory", b => { b.HasOne("VNH.Domain.Entities.MultipleChoice", "MultipleChoice") - .WithOne("ExamHistories") - .HasForeignKey("VNH.Domain.Entities.ExamHistory", "MultipleChoiceId") + .WithMany("ExamHistory") + .HasForeignKey("MultipleChoiceId") .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .IsRequired() + .HasConstraintName("FK__MultipleChoice__ExamHistoryId__06CD04F7"); b.Navigation("MultipleChoice"); }); @@ -2014,8 +1782,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("VNH.Domain.Entities.MultipleChoice", b => { - b.Navigation("ExamHistories") - .IsRequired(); + b.Navigation("ExamHistory"); b.Navigation("Quiz"); }); diff --git a/VNH.Infrastructure/Presenters/ChatSignalR.cs b/VNH.Infrastructure/Presenters/ChatSignalR.cs index 7024b57..8f7a072 100644 --- a/VNH.Infrastructure/Presenters/ChatSignalR.cs +++ b/VNH.Infrastructure/Presenters/ChatSignalR.cs @@ -8,7 +8,6 @@ public class ChatSignalR : Hub { public async Task SendComment(CommentPostDto comment) { - // Broadcast the subAnswer to all connected clients await Clients.All.SendAsync("ReceiveComment", comment); } @@ -17,10 +16,21 @@ public async Task SendAnswer(AnswerQuestionDto comment) await Clients.All.SendAsync("ReceiveAnswer", comment); } - //public async Task SendSubAnswer(List subAnswer) - //{ - // await Clients.All.SendAsync("ReceiveSubAnswer", subAnswer); - //} + public async Task AddToGroup(string userId) + { + await Groups.AddToGroupAsync(Context.ConnectionId, userId); + } + public override async Task OnConnectedAsync() + { + Console.WriteLine("Client connected: " + Context.ConnectionId); + await base.OnConnectedAsync(); + } + + public override async Task OnDisconnectedAsync(Exception exception) + { + Console.WriteLine("Client disconnected: " + Context.ConnectionId); + await base.OnDisconnectedAsync(exception); + } } diff --git a/VNH.Infrastructure/Presenters/DbContext/VietNamHistoryContext.cs b/VNH.Infrastructure/Presenters/DbContext/VietNamHistoryContext.cs index 5d2f45e..1443d5f 100644 --- a/VNH.Infrastructure/Presenters/DbContext/VietNamHistoryContext.cs +++ b/VNH.Infrastructure/Presenters/DbContext/VietNamHistoryContext.cs @@ -546,18 +546,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - - entity.HasOne(e => e.ExamHistories).WithOne(d => d.MultipleChoice).HasForeignKey(e => e.MultipleChoiceId); - entity.HasOne(e=>e.User).WithMany(d=>d.MultipleChoices).HasForeignKey(e=>e.UserId).HasConstraintName("FK__MultipleChoice__UserId__06CD04F7"); }); - - - modelBuilder.Entity(entity => { - - entity.HasOne(e => e.MultipleChoice).WithOne(d => d.ExamHistories).HasForeignKey(e => e.MultipleChoiceId); + entity.HasKey(e => e.Id); + entity.HasOne(e=>e.MultipleChoice).WithMany(e=>e.ExamHistory).HasForeignKey(e => e.MultipleChoiceId).HasConstraintName("FK__MultipleChoice__ExamHistoryId__06CD04F7"); }); @@ -567,7 +561,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity>().ToTable("AppUserTokens").HasKey(x => x.UserId); OnModelCreatingPartial(modelBuilder); - new SeedingData(modelBuilder).Seed(); + // new SeedingData(modelBuilder).Seed(); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); diff --git a/VNH.WebAPi/Controllers/AnswerController.cs b/VNH.WebAPi/Controllers/AnswerController.cs index 7e0115a..53c15cc 100644 --- a/VNH.WebAPi/Controllers/AnswerController.cs +++ b/VNH.WebAPi/Controllers/AnswerController.cs @@ -25,15 +25,16 @@ public AnswerController(IAnswerService answerService) public async Task GetAnswers(string questionId) { var result = await _answerService.GetAnswer(questionId); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost()] [Authorize] public async Task CreateAnswer(AnswerQuestionDto answer) { - var result = await _answerService.CreateAnswer(answer); - return result is null ? BadRequest(result) : Ok(result); + var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + var result = await _answerService.CreateAnswer(answer, id); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut] @@ -46,7 +47,7 @@ public async Task UpdateAnswer(AnswerQuestionDto answer) return BadRequest(); } var result = await _answerService.UpdateAnswer(answer); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("delete")] [Authorize] @@ -58,7 +59,7 @@ public async Task DeleteAnswer(string idAnswer) return BadRequest(); } var result = await _answerService.DeteleAnswer(idAnswer); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -67,7 +68,7 @@ public async Task DeleteAnswer(string idAnswer) public async Task CreateSubAnswer(SubAnswerQuestionDto subAnswer) { var result = await _answerService.CreateSubAnswer(subAnswer); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut("SubAnswer")] @@ -80,7 +81,7 @@ public async Task UpdateSubAnswer(SubAnswerQuestionDto subAnswer) return BadRequest(); } var result = await _answerService.UpdateSubAnswer(subAnswer); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -94,7 +95,7 @@ public async Task DeleteSubAnswer(string idSubAnswer) return BadRequest(); } var result = await _answerService.DeteleSubAnswer(idSubAnswer); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Confirm")] diff --git a/VNH.WebAPi/Controllers/DocumentController.cs b/VNH.WebAPi/Controllers/DocumentController.cs index 956c8e6..7ae39b9 100644 --- a/VNH.WebAPi/Controllers/DocumentController.cs +++ b/VNH.WebAPi/Controllers/DocumentController.cs @@ -23,7 +23,7 @@ public DocumentController(IDocumentService documentService) public async Task Index() { var result = await _documentService.GetAll(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut] @@ -32,7 +32,7 @@ public async Task Index() public async Task UpdateDocument([FromForm] CreateDocumentDto requestDto) { var result = await _documentService.Update(requestDto, User.Identity.Name); - return result == null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -42,21 +42,21 @@ public async Task UpdateDocument([FromForm] CreateDocumentDto req public async Task CreateDocument([FromForm] CreateDocumentDto requestDto) { var result = await _documentService.Create(requestDto, User.Identity.Name); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("{id}")] public async Task Detail(string id) { var result = await _documentService.Detail(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("Delete")] public async Task Delete(string Id) { var result = await _documentService.Delete(Id, User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Save")] @@ -64,7 +64,7 @@ public async Task Delete(string Id) public async Task GetSaveDocs([FromQuery] DocumentFpkDto docsFpk) { var result = await _documentService.GetSave(docsFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Save")] @@ -72,7 +72,7 @@ public async Task GetSaveDocs([FromQuery] DocumentFpkDto docsFpk) public async Task Save([FromForm] DocumentFpkDto docsFpk) { var result = await _documentService.AddOrRemoveSaveDocs(docsFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Search")] diff --git a/VNH.WebAPi/Controllers/HashTagController.cs b/VNH.WebAPi/Controllers/HashTagController.cs index 5c930c6..3a7036e 100644 --- a/VNH.WebAPi/Controllers/HashTagController.cs +++ b/VNH.WebAPi/Controllers/HashTagController.cs @@ -18,13 +18,13 @@ public HashTagController(IHashTag hashTagService) { public async Task GetAll() { var result = await _hasgTagService.GetAllTag(0); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("TopTag")] public async Task GetTopTags(int numberTag) { var result = await _hasgTagService.GetAllTag(numberTag); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } } } diff --git a/VNH.WebAPi/Controllers/MultiChoiceController.cs b/VNH.WebAPi/Controllers/MultiChoiceController.cs index bd9fe89..eac7f62 100644 --- a/VNH.WebAPi/Controllers/MultiChoiceController.cs +++ b/VNH.WebAPi/Controllers/MultiChoiceController.cs @@ -26,7 +26,7 @@ public MultiChoiceController(IMultipleChoiceService multipleChoiceService) public async Task CreateMultiChoice([FromForm] CreateQuizDto requestDto) { var result = await _multipleChoiceService.Create(requestDto, User.Identity.Name); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -34,7 +34,7 @@ public async Task CreateMultiChoice([FromForm] CreateQuizDto requ public async Task Detail(string id) { var result = await _multipleChoiceService.Detail(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -42,7 +42,7 @@ public async Task Detail(string id) public async Task Index() { var result = await _multipleChoiceService.GetAll(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -69,7 +69,7 @@ public async Task Delete(string idMultipleChoice) { var result = await _multipleChoiceService.Delete(idMultipleChoice, User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -79,7 +79,7 @@ public async Task DeleteQuizById(string idQuiz) { var result = await _multipleChoiceService.DeleteQuizById(idQuiz); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -88,7 +88,7 @@ public async Task Search([FromQuery] string keyWord) { var result = await _multipleChoiceService.Search(keyWord); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } @@ -100,7 +100,7 @@ public async Task GetMyPost() { var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var result = await _multipleChoiceService.GetMyMultipleChoice(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } diff --git a/VNH.WebAPi/Controllers/NotificationController.cs b/VNH.WebAPi/Controllers/NotificationController.cs new file mode 100644 index 0000000..1b55fb9 --- /dev/null +++ b/VNH.WebAPi/Controllers/NotificationController.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; +using VNH.Application.DTOs.Catalog.Notifications; +using VNH.Application.Implement.Catalog.NotificationServices; + +namespace VNH.WebAPi.Controllers +{ + [Route("[controller]")] + [ApiController] + public class NotificationController : Controller + { + private readonly INotificationService _notificationService; + public NotificationController(INotificationService notification) + { + _notificationService = notification; + } + [HttpGet] + [Authorize] + public async Task Index() + { + var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; + var result = await _notificationService.GetAll(userId); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); + } + + [HttpPost] + [Authorize(Roles = "admin")] + public async Task Add(string title) + { + var result = await _notificationService.Add(title); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); + } + + [HttpPost("AddNotification")] + [Authorize] + public async Task AddNotificationDetail(NotificationDto notification) + { + await _notificationService.AddNotificationDetail(notification); + return Ok(); + } + + [HttpPut] + [Authorize] + public async Task Update(NotificationDto notification) + { + var result = await _notificationService.Update(notification); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); + } + } +} diff --git a/VNH.WebAPi/Controllers/PostController.cs b/VNH.WebAPi/Controllers/PostController.cs index e574814..643d450 100644 --- a/VNH.WebAPi/Controllers/PostController.cs +++ b/VNH.WebAPi/Controllers/PostController.cs @@ -21,19 +21,19 @@ public PostController(IPostService postService) public async Task Index() { var result = await _postService.GetAll(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("DiscoverMobile")] public async Task IndexMobile() { var result = await _postService.GetAllMobile(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("RandomArticle")] public async Task RandomPost(int quantity = 0) { var result = await _postService.GetRandomPost(quantity); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost] [Authorize] @@ -41,7 +41,7 @@ public async Task RandomPost(int quantity = 0) public async Task CreatePost([FromForm] CreatePostDto requestDto) { var result = await _postService.Create(requestDto, User.Identity.Name); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut] @@ -50,21 +50,21 @@ public async Task CreatePost([FromForm] CreatePostDto requestDto) public async Task UpdatePost([FromForm] CreatePostDto requestDto) { var result = await _postService.Update(requestDto, User.Identity.Name); - return result == null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("{id}")] public async Task Detail(string id) { var result = await _postService.Detail(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("Delete")] public async Task Delete(string Id) { var result = await _postService.Delete(Id, User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("Remove")] @@ -72,13 +72,13 @@ public async Task Delete(string Id) public async Task DeleteAdmin(string Id) { var result = await _postService.DeleteAdmin(Id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Like")] public async Task GetLikePost([FromQuery] PostFpkDto postFpk) { var result = await _postService.GetLike(postFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Like")] @@ -86,14 +86,14 @@ public async Task GetLikePost([FromQuery] PostFpkDto postFpk) public async Task Like([FromForm] PostFpkDto postFpk) { var result = await _postService.AddOrUnLikePost(postFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Save")] [Authorize] public async Task GetSavePost([FromQuery] PostFpkDto postFpk) { var result = await _postService.GetSave(postFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("MyPostSaved")] [Authorize] @@ -101,7 +101,7 @@ public async Task GetMyPostSaved() { var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var result = await _postService.GetMyPostSaved(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("MyPost")] [Authorize] @@ -109,7 +109,7 @@ public async Task GetMyPost() { var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var result = await _postService.GetMyPost(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Save")] @@ -117,7 +117,7 @@ public async Task GetMyPost() public async Task Save([FromForm] PostFpkDto postFpk) { var result = await _postService.AddOrRemoveSavePost(postFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Report")] @@ -139,26 +139,27 @@ public async Task GetReport() public async Task GetPostByTag(string tag) { var result = await _postService.GetPostByTag(tag); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Search")] public async Task Search([FromQuery] string keyWord) { var result = await _postService.SearchPosts(keyWord); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Chat")] public async Task GetComments(string PostId) { var result = await _postService.GetComment(PostId); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Chat")] [Authorize] public async Task CreateComment(CommentPostDto comment) { - var result = await _postService.CreateComment(comment); - return result is null ? BadRequest(result) : Ok(result); + var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; + var result = await _postService.CreateComment(comment, userId); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut("Chat")] [Authorize] @@ -170,7 +171,7 @@ public async Task UpdateComment(CommentPostDto comment) return BadRequest(); } var result = await _postService.UpdateComment(comment); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("Chat")] [Authorize] @@ -182,7 +183,7 @@ public async Task DeleteComment(string idComment) return BadRequest(); } var result = await _postService.DeteleComment(idComment); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Chat/NumberComment")] public async Task GetCommentPost(string PostId) @@ -196,7 +197,7 @@ public async Task GetCommentPost(string PostId) public async Task FindByTopic(string TopicName) { var result = await _postService.FindByTopic(TopicName); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } } } diff --git a/VNH.WebAPi/Controllers/QuestionController.cs b/VNH.WebAPi/Controllers/QuestionController.cs index d37bbcc..7222e4c 100644 --- a/VNH.WebAPi/Controllers/QuestionController.cs +++ b/VNH.WebAPi/Controllers/QuestionController.cs @@ -26,7 +26,7 @@ public QuestionController(IQuestionService questionService) public async Task CreateQuestion([FromForm] CreateQuestionDto requestDto) { var result = await _questionService.Create(requestDto, User.Identity.Name); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut] @@ -60,41 +60,41 @@ public async Task SubDetail(string subId) public async Task Index() { var result = await _questionService.GetAll(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete("Delete")] public async Task Delete(string Id) { var result = await _questionService.Delete(Id, User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Like")] [Authorize] public async Task Like([FromForm] QuestionFpkDto questionFpk) { var result = await _questionService.AddOrUnLikeQuestion(questionFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Like")] public async Task GetLikePost([FromQuery] QuestionFpkDto questionFpk) { var result = await _questionService.GetLike(questionFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Save")] [Authorize] public async Task GetSaveQuestion([FromQuery] QuestionFpkDto questionFpk) { var result = await _questionService.GetSave(questionFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Save")] [Authorize] public async Task Save([FromForm] QuestionFpkDto questionFpk) { var result = await _questionService.AddOrRemoveSaveQuestion(questionFpk); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("MyQuestionSaved")] [Authorize] @@ -102,7 +102,7 @@ public async Task GetMyQuestionSaved() { var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var result = await _questionService.GetMyQuestionSaved(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("MyQuestion")] [Authorize] @@ -110,14 +110,14 @@ public async Task GetMyQuestion() { var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var result = await _questionService.GetMyQuestion(id); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost("Report")] [Authorize] public async Task Report([FromBody] ReportQuestionDto reportquestionDto) { var result = await _questionService.ReportQuestion(reportquestionDto); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Report")] @@ -125,26 +125,26 @@ public async Task Report([FromBody] ReportQuestionDto reportquest public async Task GetReport() { var result = await _questionService.GetReport(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("Search")] public async Task Search([FromQuery] string keyWord) { var result = await _questionService.SearchQuestions(keyWord); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("AllTag")] public async Task GetAllTag( int numberTag) { var result = await _questionService.GetAllTag(numberTag); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("FindByTag")] public async Task GetQuestionByTag(string tag) { var result = await _questionService.GetQuestionByTag(tag); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } } diff --git a/VNH.WebAPi/Controllers/TopicController.cs b/VNH.WebAPi/Controllers/TopicController.cs index e8ed2c6..7ad2102 100644 --- a/VNH.WebAPi/Controllers/TopicController.cs +++ b/VNH.WebAPi/Controllers/TopicController.cs @@ -20,34 +20,34 @@ public TopicController(ITopicService topicService) { public async Task GetAllTopic() { var result = await _topicService.GetAllTopic(); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpGet("GetById")] public async Task GetById(string idTopic) { var result = await _topicService.GetById(idTopic); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPost] [Authorize] public async Task CreateTopic(string topic) { var result = await _topicService.CreateTopic(topic, User.Identity.Name); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpPut] [Authorize] public async Task UpdateTopic(Guid topicId ,string topic) { var result = await _topicService.UpdateTopic(topicId, topic); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } [HttpDelete] [Authorize] public async Task DeleteTopic(Guid topicId ) { var result = await _topicService.DeleteTopic(topicId); - return result is null ? BadRequest(result) : Ok(result); + return !result.IsSuccessed ? BadRequest(result) : Ok(result); } } diff --git a/VNH.WebAPi/appsettings.json b/VNH.WebAPi/appsettings.json index 5da3361..320e892 100644 --- a/VNH.WebAPi/appsettings.json +++ b/VNH.WebAPi/appsettings.json @@ -13,7 +13,7 @@ "ConnectionStrings": { "LocalDataConnect": "Data Source=.;Initial Catalog=tyls;Integrated Security=True;Encrypt=true;TrustServerCertificate=true;", //"DataConnect": "Data Source=SQL5112.site4now.net;Initial Catalog=db_aa121e_vuanhpham25;User Id=db_aa121e_vuanhpham25_admin;Password=30102002Mai" - // "DataConnect": "Data Source=.\\MSSQLSERVER2022;Initial Catalog=tyls;User Id=toiyeulichsu;Password=MheZDu9$oGbrYlL#S%ApJ^qf;TrustServerCertificate=True;Encrypt=False" + "DataConnect": "Data Source=.\\MSSQLSERVER2022;Initial Catalog=tyls;User Id=toiyeulichsu;Password=MheZDu9$oGbrYlL#S%ApJ^qf;TrustServerCertificate=True;Encrypt=False" }, "MailSettings": { diff --git a/VNH.WebAPi/wwwroot/Documents/Bai-tap-ngay-041223-012025.081174.docx b/VNH.WebAPi/wwwroot/Documents/Bai-tap-ngay-041223-012025.081174.docx new file mode 100644 index 0000000..6117fc9 Binary files /dev/null and b/VNH.WebAPi/wwwroot/Documents/Bai-tap-ngay-041223-012025.081174.docx differ diff --git a/VNH.WebAPi/wwwroot/Documents/Bo-tai-lieu-su-moi-nhat-104557.795228.pdf b/VNH.WebAPi/wwwroot/Documents/Bo-tai-lieu-su-moi-nhat-104557.795228.pdf new file mode 100644 index 0000000..1c3ff06 Binary files /dev/null and b/VNH.WebAPi/wwwroot/Documents/Bo-tai-lieu-su-moi-nhat-104557.795228.pdf differ diff --git a/VNH.WebAPi/wwwroot/Documents/Tai-lieu-trac-nghiemh-104435.415345.docx b/VNH.WebAPi/wwwroot/Documents/Tai-lieu-trac-nghiemh-104435.415345.docx new file mode 100644 index 0000000..52336de Binary files /dev/null and b/VNH.WebAPi/wwwroot/Documents/Tai-lieu-trac-nghiemh-104435.415345.docx differ diff --git a/VNH.WebAPi/wwwroot/Documents/Trac-nghiem-moi-nhat-ve-lich-su-104726.808297.pdf b/VNH.WebAPi/wwwroot/Documents/Trac-nghiem-moi-nhat-ve-lich-su-104726.808297.pdf new file mode 100644 index 0000000..68d4879 Binary files /dev/null and b/VNH.WebAPi/wwwroot/Documents/Trac-nghiem-moi-nhat-ve-lich-su-104726.808297.pdf differ diff --git a/VNH.WebAPi/wwwroot/Images/8869b5cb-2505-4aa1-8df3-a24c38088301.png b/VNH.WebAPi/wwwroot/Images/8869b5cb-2505-4aa1-8df3-a24c38088301.png new file mode 100644 index 0000000..d14beef Binary files /dev/null and b/VNH.WebAPi/wwwroot/Images/8869b5cb-2505-4aa1-8df3-a24c38088301.png differ diff --git a/VNH.WebAPi/wwwroot/Images/e5ba794b-f6a6-4bb4-b37f-d1898492b32b.avif b/VNH.WebAPi/wwwroot/Images/e5ba794b-f6a6-4bb4-b37f-d1898492b32b.avif new file mode 100644 index 0000000..437a15b Binary files /dev/null and b/VNH.WebAPi/wwwroot/Images/e5ba794b-f6a6-4bb4-b37f-d1898492b32b.avif differ