-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/ab#9075 Applicant Profile Add Attachments #2224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6e768d9
e310fcb
f4de4de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,14 +21,16 @@ public partial class S3BlobProvider : BlobProviderBase, ITransientDependency | |
| { | ||
| private readonly IHttpContextAccessor _httpContextAccessor; | ||
| private readonly IApplicationAttachmentRepository _applicationAttachmentRepository; | ||
| private readonly IAssessmentAttachmentRepository _assessmentAttachmentRepository; | ||
| private readonly IAssessmentAttachmentRepository _assessmentAttachmentRepository; | ||
| private readonly IApplicantAttachmentRepository _applicantAttachmentRepository; | ||
| private readonly AmazonS3Client _amazonS3Client; | ||
|
|
||
| public S3BlobProvider(IHttpContextAccessor httpContextAccessor, IApplicationAttachmentRepository attachmentRepository, IAssessmentAttachmentRepository assessmentAttachmentRepository, IConfiguration configuration) | ||
| public S3BlobProvider(IHttpContextAccessor httpContextAccessor, IApplicationAttachmentRepository attachmentRepository, IAssessmentAttachmentRepository assessmentAttachmentRepository, IApplicantAttachmentRepository applicantAttachmentRepository, IConfiguration configuration) | ||
| { | ||
| _httpContextAccessor = httpContextAccessor; | ||
| _applicationAttachmentRepository = attachmentRepository; | ||
| _assessmentAttachmentRepository = assessmentAttachmentRepository; | ||
| _applicantAttachmentRepository = applicantAttachmentRepository; | ||
|
|
||
| AmazonS3Config s3config = new() | ||
| { | ||
|
|
@@ -89,6 +91,19 @@ public override async Task<bool> DeleteAsync(BlobProviderDeleteArgs args) | |
| await _assessmentAttachmentRepository.DeleteAsync(attachment); | ||
| } | ||
| } | ||
| else if (attachmentType == "Applicant") | ||
| { | ||
| if (attachmentTypeId.IsNullOrEmpty()) | ||
| { | ||
| throw new AbpValidationException("Missing ApplicantId"); | ||
| } | ||
| IQueryable<ApplicantAttachment> queryableAttachment = _applicantAttachmentRepository.GetQueryableAsync().Result; | ||
| ApplicantAttachment? attachment = queryableAttachment.FirstOrDefault(a => a.S3ObjectKey.Equals(s3ObjectKey) && a.ApplicantId.Equals(new Guid(attachmentTypeId.ToString()))); | ||
| if (attachment != null) | ||
| { | ||
| await _applicantAttachmentRepository.DeleteAsync(attachment); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| throw new AbpValidationException("Wrong AttachmentType:"+attachmentType); | ||
|
|
@@ -146,30 +161,34 @@ public override async Task SaveAsync(BlobProviderSaveArgs args) | |
| var httpContext = _httpContextAccessor.HttpContext ?? throw new InvalidOperationException("No active HttpContext."); | ||
| var queryParams = httpContext.Request?.Query ?? throw new InvalidOperationException("No query parameters in the current request."); | ||
| var routeData = _httpContextAccessor.HttpContext.GetRouteData(); | ||
| var assessmentId = routeData.Values["assessmentId"]; | ||
|
|
||
| var assessmentId = routeData.Values["assessmentId"]; | ||
| var applicationId = routeData.Values["applicationId"]; | ||
| var applicantId = routeData.Values["applicantId"]; | ||
| queryParams.TryGetValue("userId", out StringValues currentUserId); | ||
| if (assessmentId != null) | ||
| { | ||
| queryParams.TryGetValue("userId", out StringValues currentUserId); | ||
| #pragma warning disable CS8604 // Possible null reference argument. | ||
|
|
||
| #pragma warning disable CS8604 // Possible null reference argument. | ||
| await UploadAssessmentAttachment(args, assessmentId.ToString(), currentUserId.ToString()); | ||
| #pragma warning restore CS8604 // Possible null reference argument. | ||
| #pragma warning restore CS8604 // Possible null reference argument. | ||
| } | ||
| else if(applicationId != null) | ||
| { | ||
| #pragma warning disable CS8604 // Possible null reference argument. | ||
| await UploadApplicationAttachment(args, applicationId.ToString(), currentUserId.ToString()); | ||
| #pragma warning restore CS8604 // Possible null reference argument. | ||
| } | ||
| else if (applicantId != null) | ||
| { | ||
| #pragma warning disable CS8604 // Possible null reference argument. | ||
| await UploadApplicantAttachment(args, applicantId.ToString(), currentUserId.ToString()); | ||
| #pragma warning restore CS8604 // Possible null reference argument. | ||
| } | ||
| else | ||
| { | ||
| var applicationId = routeData.Values["applicationId"]; | ||
| if(applicationId != null) | ||
| { | ||
| queryParams.TryGetValue("userId", out StringValues currentUserId); | ||
| #pragma warning disable CS8604 // Possible null reference argument. | ||
| await UploadApplicationAttachment(args, applicationId.ToString(), currentUserId.ToString()); | ||
| #pragma warning restore CS8604 // Possible null reference argument. | ||
| } | ||
| else | ||
| { | ||
| throw new AbpValidationException("Missing parameter: applicationId/assessmentId"); | ||
| } | ||
| } | ||
| throw new AbpValidationException("Missing parameter: applicationId/assessmentId/applicantId"); | ||
| } | ||
| } | ||
|
|
||
| private async Task UploadAssessmentAttachment(BlobProviderSaveArgs args, string assessmentId, string currentUserId) | ||
|
|
@@ -246,6 +265,43 @@ await _applicationAttachmentRepository.InsertAsync( | |
| } | ||
| } | ||
|
|
||
| private async Task UploadApplicantAttachment(BlobProviderSaveArgs args, string applicantId, string currentUserId) | ||
| { | ||
| var config = args.Configuration.GetS3BlobProviderConfiguration(); | ||
| var bucket = config.Bucket; | ||
| var folder = args.Configuration.GetS3BlobProviderConfiguration().ApplicantS3Folder; | ||
| if (!folder.EndsWith('/')) | ||
| { | ||
| folder += "/"; | ||
| } | ||
| folder += applicantId; | ||
| var key = folder + "/" + args.BlobName; | ||
| var escapedKey = folder + "/" + Uri.EscapeDataString(args.BlobName); | ||
| var mimeType = GetMimeType(args.BlobName); | ||
| await UploadToS3(args, bucket, escapedKey, mimeType); | ||
| IQueryable<ApplicantAttachment> queryableAttachment = _applicantAttachmentRepository.GetQueryableAsync().Result; | ||
| ApplicantAttachment? attachment = queryableAttachment.FirstOrDefault(a => a.S3ObjectKey.Equals(key) && a.ApplicantId.Equals(new Guid(applicantId))); | ||
| if (attachment == null) | ||
| { | ||
| await _applicantAttachmentRepository.InsertAsync( | ||
| new ApplicantAttachment | ||
| { | ||
| ApplicantId = new Guid(applicantId), | ||
| S3ObjectKey = key, | ||
| UserId = new Guid(currentUserId), | ||
| FileName = args.BlobName, | ||
| Time = DateTime.UtcNow, | ||
| }); | ||
| } | ||
| else | ||
| { | ||
| attachment.UserId = new Guid(currentUserId); | ||
| attachment.FileName = args.BlobName; | ||
| attachment.Time = DateTime.UtcNow; | ||
| await _applicantAttachmentRepository.UpdateAsync(attachment); | ||
| } | ||
| } | ||
|
Comment on lines
+268
to
+303
|
||
|
|
||
| public async Task UploadToS3(BlobProviderSaveArgs args, string bucket, string key, string mimeType) | ||
| { | ||
| byte[] fileBytes; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,5 +8,6 @@ public enum AttachmentType | |
| APPLICATION = 0, | ||
| ASSESSMENT = 1, | ||
| CHEFS = 2, | ||
| EMAIL = 3 | ||
| EMAIL = 3, | ||
| APPLICANT = 4 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| using System; | ||
| using System.ComponentModel.DataAnnotations.Schema; | ||
| using Unity.GrantManager.Attachments; | ||
|
|
||
| namespace Unity.GrantManager.Applications; | ||
|
|
||
| public class ApplicantAttachment : AbstractS3Attachment | ||
| { | ||
| [NotMapped] | ||
| public override AttachmentType AttachmentType => AttachmentType.APPLICANT; | ||
| public Guid ApplicantId { get; set; } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Threading.Tasks; | ||
| using Volo.Abp.Domain.Repositories; | ||
|
|
||
| namespace Unity.GrantManager.Applications | ||
| { | ||
| public interface IApplicantAttachmentRepository : IRepository<ApplicantAttachment, Guid> | ||
| { | ||
| Task<List<ApplicantAttachment>> GetListAsync( | ||
| int skipCount, | ||
| int maxResultCount, | ||
| string sorting, | ||
| string filter | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new Applicant delete branch uses
GetQueryableAsync().Result(sync-over-async) inside an async method. This can cause thread-pool starvation and makes failures harder to diagnose. AwaitGetQueryableAsync()and keep the query fully async.