From 3d83e95613430e0c1430ddc746aed678cca25413 Mon Sep 17 00:00:00 2001 From: kham vilaythong Date: Sun, 20 Sep 2026 14:32:59 +1000 Subject: [PATCH] put in new ui and backend store image to table --- .../Controllers/FileUploadController.cs | 38 +++++++- .../Controllers/PersonController.cs | 1 + API/FamilyTreeAPI/Entities/FileContent.cs | 5 +- API/FamilyTreeAPI/Helper/Helpers.cs | 8 +- API/FamilyTreeAPI/Interface/IPersonPhoto.cs | 5 +- .../Repository/PersonPhotoRepository.cs | 94 +++++++++++++++---- .../Repository/PersonRepository.cs | 10 +- UI/src/app/attachphoto/photolist.html | 3 +- UI/src/app/attachphoto/photolist.ts | 2 +- UI/src/app/models/enum.ts | 5 +- UI/src/app/person/person.edit.ts | 23 +++-- UI/src/app/person/person.service.ts | 45 +++++++-- UI/src/app/pickperson/image.display.ts | 10 +- 13 files changed, 194 insertions(+), 55 deletions(-) diff --git a/API/FamilyTreeAPI/Controllers/FileUploadController.cs b/API/FamilyTreeAPI/Controllers/FileUploadController.cs index 61d000b..7c098fd 100644 --- a/API/FamilyTreeAPI/Controllers/FileUploadController.cs +++ b/API/FamilyTreeAPI/Controllers/FileUploadController.cs @@ -3,6 +3,7 @@ using FamilyTreeAPI.Repository; namespace FamilyTreeAPI.Controllers; +using DocumentFormat.OpenXml.Drawing.Charts; using FamilyTreeAPI.Interface; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; @@ -115,9 +116,30 @@ public class FileUploadController : ControllerBase public async Task DownloadPersonPhoto(DownloadFileCriteria criteria) { - var result = await _personPhoto.DownloadPersonPhoto(criteria.Id, criteria.FileName); + var result = await _personPhoto.DownloadPersonPhoto(criteria.Id,criteria.PhotoType ,criteria.FileName); + if (result.StatusCode > 0) + return File(result.Data.Content, result.Data.ContentType, result.Data.FileName); + else + return NotFound("not found image"); + } + [HttpPost("[action]")] + public async Task DownloadPersonPhoto64(DownloadFileCriteria criteria) + { - return File(result.Data.Content, result.Data.ContentType, result.Data.FileName); + var result = await _personPhoto.DownloadPersonPhoto(criteria.Id,criteria.PhotoType ,criteria.FileName); + if (result.StatusCode > 0) + { + byte[] file64 = result.Data.Content; + string rval = Convert.ToBase64String(file64); + ResultModel retval = new() { + Data = rval, + StatusCode = 1, + Message = "" + }; + return Ok(retval); + } + else + return NotFound("not found image"); } [HttpPost("[action]")] public async Task DeletePersonPhoto(DeleteFileCriteria criteria) @@ -127,8 +149,18 @@ public class FileUploadController : ControllerBase if ( criteria.Id > 0) { - ret = await _personPhoto.DeletePersonPhoto(criteria.Id); + ret = await _personPhoto.DeletePersonPhoto(criteria.Id, criteria.PhotoType); } return Ok(ret); } + [HttpPost("[action]")] + public async Task DeletePersonPhotoById(DeleteCriteria criteria) + { + + ResultModel ret = new(); + + ret = await _personPhoto.DeletePersonPhotoById(criteria.Id); + + return Ok(ret); + } } diff --git a/API/FamilyTreeAPI/Controllers/PersonController.cs b/API/FamilyTreeAPI/Controllers/PersonController.cs index 83d5343..3ea5a8c 100644 --- a/API/FamilyTreeAPI/Controllers/PersonController.cs +++ b/API/FamilyTreeAPI/Controllers/PersonController.cs @@ -14,6 +14,7 @@ namespace FamilyTreeAPI.Controllers { _repo = repo; } + [HttpPost("[action]")] public async Task UploadImage(IFormFile file) { diff --git a/API/FamilyTreeAPI/Entities/FileContent.cs b/API/FamilyTreeAPI/Entities/FileContent.cs index 8a027e4..e4aa614 100644 --- a/API/FamilyTreeAPI/Entities/FileContent.cs +++ b/API/FamilyTreeAPI/Entities/FileContent.cs @@ -15,16 +15,19 @@ public class DownloadFileCriteria { public string FileName { get; set; } public int Id { get; set; } + + public int PhotoType {get; set;} } public class UploadCriteria { public string FileName { get; set; } public int PersonId { get; set; } - public int? PhotoType {get; set;} + public int PhotoType {get; set;} public IFormFile File { get; set; } } public class DeleteFileCriteria { public int Id { get; set; } public string Filename { get; set; } + public int PhotoType {get; set;} } \ No newline at end of file diff --git a/API/FamilyTreeAPI/Helper/Helpers.cs b/API/FamilyTreeAPI/Helper/Helpers.cs index 32d826b..95fd464 100644 --- a/API/FamilyTreeAPI/Helper/Helpers.cs +++ b/API/FamilyTreeAPI/Helper/Helpers.cs @@ -2,6 +2,12 @@ { public class Helpers { + public static string GetFileExtension(string fileName) + { + string result = System.IO.Path.GetExtension(fileName); + + return result; + } public static string GetFileContent(string extension) { string contentType = ""; @@ -82,7 +88,7 @@ if (date.HasValue) { result = date.Value.ToString("yyyy-MM-dd"); - } + } return result; } public static DateTime? DateToDateTime(string? date) diff --git a/API/FamilyTreeAPI/Interface/IPersonPhoto.cs b/API/FamilyTreeAPI/Interface/IPersonPhoto.cs index 8c6f038..b73a6cf 100644 --- a/API/FamilyTreeAPI/Interface/IPersonPhoto.cs +++ b/API/FamilyTreeAPI/Interface/IPersonPhoto.cs @@ -5,8 +5,9 @@ namespace FamilyTreeAPI.Interface; public interface IPersonPhoto { Task> SaveAsync(UploadCriteria criteria); - Task> DownloadPersonPhoto(int id, string? filename); + Task> DownloadPersonPhoto(int id, int photoType, string filename); - Task> DeletePersonPhoto(int id); + Task> DeletePersonPhoto(int id, int photoType); + Task> DeletePersonPhotoById(int id); Task>> LoadPersonPhoto(int personId); } diff --git a/API/FamilyTreeAPI/Repository/PersonPhotoRepository.cs b/API/FamilyTreeAPI/Repository/PersonPhotoRepository.cs index 8dca496..b1c917a 100644 --- a/API/FamilyTreeAPI/Repository/PersonPhotoRepository.cs +++ b/API/FamilyTreeAPI/Repository/PersonPhotoRepository.cs @@ -3,6 +3,7 @@ using FamilyTreeAPI.Entities; using FamilyTreeAPI.Helper; using FamilyTreeAPI.Interface; using FamilyTreeAPI.Models; +using HotChocolate.CostAnalysis.Types; using Microsoft.EntityFrameworkCore; namespace FamilyTreeAPI.Repository @@ -31,12 +32,12 @@ namespace FamilyTreeAPI.Repository dto.PhotoType = model.PhotoType; return dto; } - private PersonPhoto FillModel(PersonPhoto model, int personId, string filename) + private PersonPhoto FillModel(PersonPhoto model, int personId, int photoType, string filename) { model.PersonId = personId; model.Photo = filename; - model.PhotoType = System.IO.Path.GetExtension(filename); + model.PhotoType = photoType.ToString(); //System.IO.Path.GetExtension(filename); return model; } @@ -46,8 +47,8 @@ namespace FamilyTreeAPI.Repository int statuscode = 0; string error = "";//Other string photoType = "2"; // - if (criteria.PhotoType.HasValue) - photoType = criteria.PhotoType.Value.ToString(); + if (criteria.PhotoType > 0) + photoType = criteria.PhotoType.ToString(); HttpContext? httpContext = _httpContext.HttpContext; string loginName = ""; if (httpContext != null) @@ -64,8 +65,8 @@ namespace FamilyTreeAPI.Repository PersonPhoto model; model = new(); - model.PhotoType = photoType; - model = FillModel(model,criteria.PersonId, formfile.FileName); + + model = FillModel(model,criteria.PersonId, criteria.PhotoType,formfile.FileName); using (var stream = new MemoryStream()) { @@ -93,14 +94,15 @@ namespace FamilyTreeAPI.Repository }; } - public async Task> DownloadPersonPhoto(int id, string? filename) + public async Task> DownloadPersonPhoto(int personId, int photoType, string filename) { int statusCode = -1; string error = ""; + string extension = ""; PersonPhoto? model = null; FileContent fileContent = new(); - if (id < 1) + if (personId < 1) { var rlist = await _context.PersonPhotos.Where(x => x.Photo == filename).ToListAsync(); if (rlist != null) @@ -111,19 +113,26 @@ namespace FamilyTreeAPI.Repository } } } + else { - model = await _context.PersonPhotos.FindAsync(id); - } + var rlist = await _context.PersonPhotos.Where (x => x.PersonId == personId && photoType.ToString() == x.PhotoType).ToListAsync(); + for ( int i = 0; i < rlist.Count; i++) + { + model = rlist[i]; + + break; + } + } if (model != null) { - fileContent.ContentType = Helpers.GetFileContent(model.PhotoType); + extension = Helpers.GetFileExtension(model.Photo); + fileContent.ContentType = Helpers.GetFileContent(extension); fileContent.Content = (byte[])model.ImagePhoto; fileContent.FileName = model.Photo; statusCode = 1; } - return new ResultModel() { Data = fileContent, @@ -132,20 +141,69 @@ namespace FamilyTreeAPI.Repository }; } - public async Task> DeletePersonPhoto(int id) + public async Task> DeletePersonPhoto(int personId, int photoType) { int result = default(int); int statuscode = 0; string error = ""; + PersonPhoto? model; try { - PersonPhoto? model = await _context.PersonPhotos.FindAsync(id); - if (model != null) + if (photoType < 1) { - _context.PersonPhotos.Remove(model); - await _context.SaveChangesAsync(); - statuscode = 1; + List list = await _context.PersonPhotos.Where ( x => x.PersonId == personId).ToListAsync(); + for (int i = 0; i< list.Count; i++) + { + model = list[i]; + _context.PersonPhotos.Remove(model); + await _context.SaveChangesAsync(); + statuscode = 1; + } } + else + { + List list = await _context.PersonPhotos.Where ( x => x.PersonId == personId && x.PhotoType == photoType.ToString()).ToListAsync(); + for (int i = 0; i< list.Count; i++) + { + model = list[i]; + _context.PersonPhotos.Remove(model); + await _context.SaveChangesAsync(); + statuscode = 1; + } + } + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = -1; + } + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + public async Task> DeletePersonPhotoById(int id) + { + int result = default(int); + int statuscode = 0; + string error = ""; + + try + { + + PersonPhoto? model = await _context.PersonPhotos.FindAsync(id); + if (model != null) + { + + _context.PersonPhotos.Remove(model); + await _context.SaveChangesAsync(); + statuscode = 1; + } + } catch (Exception ex) { diff --git a/API/FamilyTreeAPI/Repository/PersonRepository.cs b/API/FamilyTreeAPI/Repository/PersonRepository.cs index 448ac53..6523b92 100644 --- a/API/FamilyTreeAPI/Repository/PersonRepository.cs +++ b/API/FamilyTreeAPI/Repository/PersonRepository.cs @@ -283,7 +283,7 @@ public partial class PersonRepository : IPerson node.Key = item.Id.ToString(); node.Type = type; if (item.Image != null) - node.Data.Image = await LoadPersonImage(item.Id,item.Image); + node.Data.Image = await LoadPersonImage(item.Id, (int) enumPhotoType.Profile, item.Image); node.Icon = "T"; node.StyleClass = getStyleClass(node.Icon); @@ -392,7 +392,7 @@ public partial class PersonRepository : IPerson citem.Data = new(); citem.Label = pName; if (image != null) - citem.Data.Image = await LoadPersonImage(personId,image); + citem.Data.Image = await LoadPersonImage(personId, (int) enumPhotoType.Profile, image); citem.Icon = "P"; @@ -413,7 +413,7 @@ public partial class PersonRepository : IPerson child.Type = type; image = dto.Image; if (image != null) - child.Data.Image = await LoadPersonImage(dto.Id,image); + child.Data.Image = await LoadPersonImage(dto.Id,(int) enumPhotoType.Profile, image); child.Icon = "C"; child.StyleClass = getStyleClass(child.Icon); child.Label = dto.FirstName; @@ -750,13 +750,13 @@ public partial class PersonRepository : IPerson return result; } - private async Task LoadPersonImage(int personId,string filename) + private async Task LoadPersonImage(int personId, int photoType, string filename) { string result = ""; // DownloadFileCriteria criteria = new() { FileName = filename }; - var resultModel = await _personPhoto.DownloadPersonPhoto(personId, filename); + var resultModel = await _personPhoto.DownloadPersonPhoto(personId, photoType , filename); //if (resultModel.Data.Content) string base64String = Convert.ToBase64String(resultModel.Data.Content); diff --git a/UI/src/app/attachphoto/photolist.html b/UI/src/app/attachphoto/photolist.html index 3cfb85f..4818c72 100644 --- a/UI/src/app/attachphoto/photolist.html +++ b/UI/src/app/attachphoto/photolist.html @@ -16,7 +16,7 @@ Id Description - + Photo Type Action @@ -25,6 +25,7 @@ {{item.id}} {{item.photo}} + {{item.photoType}}