check add person photo finish
This commit is contained in:
@@ -3,8 +3,9 @@ using FamilyTreeAPI.Repository;
|
|||||||
|
|
||||||
namespace FamilyTreeAPI.Controllers;
|
namespace FamilyTreeAPI.Controllers;
|
||||||
|
|
||||||
|
using FamilyTreeAPI.Interface;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -15,11 +16,15 @@ public class FileUploadController : ControllerBase
|
|||||||
private readonly IWebHostEnvironment _hostingEnvironment;
|
private readonly IWebHostEnvironment _hostingEnvironment;
|
||||||
private readonly ImportPersonRepository _importPersonRepository;
|
private readonly ImportPersonRepository _importPersonRepository;
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _config;
|
||||||
public FileUploadController(IWebHostEnvironment hostingEnvironment, ImportPersonRepository importPersonRepository, IConfiguration config)
|
private readonly IPersonPhoto _personPhoto;
|
||||||
|
public FileUploadController(IWebHostEnvironment hostingEnvironment,
|
||||||
|
IPersonPhoto personPhoto,
|
||||||
|
ImportPersonRepository importPersonRepository, IConfiguration config)
|
||||||
{
|
{
|
||||||
_hostingEnvironment = hostingEnvironment;
|
_hostingEnvironment = hostingEnvironment;
|
||||||
_importPersonRepository = importPersonRepository;
|
_importPersonRepository = importPersonRepository;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
_personPhoto = personPhoto;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("[action]")]
|
[HttpPost("[action]")]
|
||||||
@@ -79,4 +84,51 @@ public class FileUploadController : ControllerBase
|
|||||||
var rev = await _importPersonRepository.DownloadFile(criteria);
|
var rev = await _importPersonRepository.DownloadFile(criteria);
|
||||||
return Ok(rev);
|
return Ok(rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> SavePersonPhoto(List<IFormFile> files)
|
||||||
|
{
|
||||||
|
var keys = Request.Form;
|
||||||
|
var ffiles = Request.Form.Files;
|
||||||
|
ResultModel<int> ret = new();
|
||||||
|
if (files.Count > 0)
|
||||||
|
{
|
||||||
|
StringValues sdocCId = "";
|
||||||
|
keys.TryGetValue("personId", out sdocCId);
|
||||||
|
for (int i = 0; i < files.Count; i++)
|
||||||
|
{
|
||||||
|
var file = files[i];
|
||||||
|
UploadCriteria criteria = new();
|
||||||
|
criteria.File = file;
|
||||||
|
criteria.PersonId = int.Parse(sdocCId);
|
||||||
|
criteria.FileName = file.FileName;
|
||||||
|
|
||||||
|
ret = await _personPhoto.SaveAsync(criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> DownloadPersonPhoto(DownloadFileCriteria criteria)
|
||||||
|
{
|
||||||
|
|
||||||
|
var result = await _personPhoto.DownloadPersonPhoto(criteria.Id, criteria.FileName);
|
||||||
|
|
||||||
|
return File(result.Data.Content, result.Data.ContentType, result.Data.FileName);
|
||||||
|
}
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<ActionResult> DeletePersonPhoto(DeleteFileCriteria criteria)
|
||||||
|
{
|
||||||
|
|
||||||
|
ResultModel<int> ret = new();
|
||||||
|
if ( criteria.Id > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
ret = await _personPhoto.DeletePersonPhoto(criteria.Id);
|
||||||
|
}
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ namespace FamilyTreeAPI.Controllers
|
|||||||
{
|
{
|
||||||
StringValues familyId = "";
|
StringValues familyId = "";
|
||||||
|
|
||||||
keys.TryGetValue("familyId", out familyId);
|
keys.TryGetValue("personId", out familyId);
|
||||||
|
|
||||||
UploadCriteria criteria = new();
|
UploadCriteria criteria = new();
|
||||||
criteria.File = file;
|
criteria.File = file;
|
||||||
criteria.FamilyId = familyId;
|
criteria.PersonId = int.Parse(familyId);
|
||||||
|
|
||||||
criteria.FileName = file.FileName;
|
criteria.FileName = file.FileName;
|
||||||
|
|
||||||
|
|||||||
@@ -9,20 +9,22 @@ public class FileContent
|
|||||||
{
|
{
|
||||||
public byte[] Content { get; set; }
|
public byte[] Content { get; set; }
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
|
public string ContentType { get; set; }
|
||||||
}
|
}
|
||||||
public class DownloadFileCriteria
|
public class DownloadFileCriteria
|
||||||
{
|
{
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
}
|
}
|
||||||
public class UploadCriteria
|
public class UploadCriteria
|
||||||
{
|
{
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
public string FamilyId { get; set; }
|
public int PersonId { get; set; }
|
||||||
|
|
||||||
public IFormFile File { get; set; }
|
public IFormFile File { get; set; }
|
||||||
}
|
}
|
||||||
public class DeleteFileCriteria
|
public class DeleteFileCriteria
|
||||||
{
|
{
|
||||||
public int FamilyId { get; set; }
|
public int Id { get; set; }
|
||||||
public string Filename { get; set; }
|
public string Filename { get; set; }
|
||||||
}
|
}
|
||||||
@@ -49,5 +49,6 @@ public partial class PersonDto
|
|||||||
public int? MotherId { get; set; }
|
public int? MotherId { get; set; }
|
||||||
|
|
||||||
public List<RelationShipDto>? RelationShips { get; set; }
|
public List<RelationShipDto>? RelationShips { get; set; }
|
||||||
|
public List<PersonPhotoDto>? PersonPhotos { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace FamilyTreeAPI.Entities;
|
||||||
|
|
||||||
|
public class PersonPhotoDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int PersonId { get; set; }
|
||||||
|
public string Photo { get; set; }
|
||||||
|
public string? PhotoType { get; set; }
|
||||||
|
}
|
||||||
@@ -2,6 +2,80 @@
|
|||||||
{
|
{
|
||||||
public class Helpers
|
public class Helpers
|
||||||
{
|
{
|
||||||
|
public static string GetFileContent(string extension)
|
||||||
|
{
|
||||||
|
string contentType = "";
|
||||||
|
/*
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types
|
||||||
|
*/
|
||||||
|
switch (extension)
|
||||||
|
{
|
||||||
|
case ".pdf":
|
||||||
|
contentType = "application/pdf";
|
||||||
|
break;
|
||||||
|
case ".txt":
|
||||||
|
contentType = "text/plain";
|
||||||
|
break;
|
||||||
|
case ".xlsx":
|
||||||
|
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||||
|
break;
|
||||||
|
case ".xls":
|
||||||
|
contentType = "application/vnd.ms-excel";
|
||||||
|
break;
|
||||||
|
case ".doc":
|
||||||
|
contentType = "application/msword";
|
||||||
|
break;
|
||||||
|
case ".odt":
|
||||||
|
contentType = "application/vnd.oasis.opendocument.text";
|
||||||
|
break;
|
||||||
|
case ".docx":
|
||||||
|
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||||
|
break;
|
||||||
|
case ".gif":
|
||||||
|
contentType = "image/gif";
|
||||||
|
break;
|
||||||
|
case ".ppt":
|
||||||
|
contentType = "application/vnd.ms-powerpoint";
|
||||||
|
break;
|
||||||
|
case ".ico":
|
||||||
|
contentType = "image/vnd.microsoft.icon";
|
||||||
|
break;
|
||||||
|
case ".png":
|
||||||
|
contentType = "image/png";
|
||||||
|
break;
|
||||||
|
case ".rar":
|
||||||
|
contentType = "application/vnd.rar";
|
||||||
|
break;
|
||||||
|
case ".zip":
|
||||||
|
contentType = "application/zip";
|
||||||
|
break;
|
||||||
|
case ".tar":
|
||||||
|
contentType = "application/x-tar";
|
||||||
|
break;
|
||||||
|
case ".mp4":
|
||||||
|
contentType = "video/mp4";
|
||||||
|
break;
|
||||||
|
case ".jpeg":
|
||||||
|
case ".jpg":
|
||||||
|
contentType = "image/jpeg";
|
||||||
|
break;
|
||||||
|
case ".3gp":
|
||||||
|
contentType = "video/3gpp";
|
||||||
|
break;
|
||||||
|
case ".7z":
|
||||||
|
contentType = "application/x-7z-compressed";
|
||||||
|
break;
|
||||||
|
case ".tif":
|
||||||
|
case ".tiff":
|
||||||
|
contentType = "image/tiff";
|
||||||
|
break;
|
||||||
|
// and so on
|
||||||
|
// default:
|
||||||
|
// throw new ArgumentOutOfRangeException($"Unable to find Content Type for file name {file.NameWithExtension}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
public static string? DateToStr(DateTime? date)
|
public static string? DateToStr(DateTime? date)
|
||||||
{
|
{
|
||||||
string? result = null;
|
string? result = null;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using FamilyTreeAPI.Entities;
|
||||||
|
|
||||||
|
namespace FamilyTreeAPI.Interface;
|
||||||
|
|
||||||
|
public interface IPersonPhoto
|
||||||
|
{
|
||||||
|
Task<ResultModel<int>> SaveAsync(UploadCriteria criteria);
|
||||||
|
Task<ResultModel<FileContent>> DownloadPersonPhoto(int id, string? filename);
|
||||||
|
|
||||||
|
Task<ResultModel<int>> DeletePersonPhoto(int id);
|
||||||
|
Task<ResultModel<List<PersonPhotoDto>>> LoadPersonPhoto(int personId);
|
||||||
|
}
|
||||||
@@ -80,7 +80,11 @@ namespace FamilyTreeAPI.Models
|
|||||||
|
|
||||||
entity.Property(e => e.Id).HasColumnName("id");
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
entity.Property(e => e.PersonId).HasColumnName("personid");
|
entity.Property(e => e.PersonId).HasColumnName("personid");
|
||||||
entity.Property(e => e.Photo).HasColumnName("photo");
|
entity.Property(e => e.Photo)
|
||||||
|
.HasColumnName("photo");
|
||||||
|
entity.Property(e => e.PhotoType)
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnName("phototype");
|
||||||
entity.Property(e => e.ImagePhoto).HasColumnName("imagephot"); //try to store binary in table. "bytea"
|
entity.Property(e => e.ImagePhoto).HasColumnName("imagephot"); //try to store binary in table. "bytea"
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
public int PersonId { get; set; }
|
public int PersonId { get; set; }
|
||||||
public string Photo { get; set; }
|
public string Photo { get; set; }
|
||||||
|
public string? PhotoType { get; set; }
|
||||||
|
|
||||||
public byte[] ImagePhoto { get; set; }
|
public byte[] ImagePhoto { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ services.AddGraphQLServer()
|
|||||||
|
|
||||||
services.AddScoped<ILookup, LookupRepository>();
|
services.AddScoped<ILookup, LookupRepository>();
|
||||||
services.AddScoped<IStaff, StaffRepository>();
|
services.AddScoped<IStaff, StaffRepository>();
|
||||||
|
services.AddScoped<IPersonPhoto, PersonPhotoRepository>();
|
||||||
services.AddScoped<IRelationShipd,RelationShipRepository>();
|
services.AddScoped<IRelationShipd,RelationShipRepository>();
|
||||||
services.AddScoped<IPerson, PersonRepository>();
|
services.AddScoped<IPerson, PersonRepository>();
|
||||||
services.AddScoped<IUserService, UserServiceRepository>();
|
services.AddScoped<IUserService, UserServiceRepository>();
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
|
using FamilyTreeAPI.Entities;
|
||||||
|
using FamilyTreeAPI.Helper;
|
||||||
|
using FamilyTreeAPI.Interface;
|
||||||
|
using FamilyTreeAPI.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace FamilyTreeAPI.Repository
|
||||||
|
{
|
||||||
|
public class PersonPhotoRepository: IPersonPhoto
|
||||||
|
{
|
||||||
|
private readonly FamilyTreeDBContext _context;
|
||||||
|
private readonly IHttpContextAccessor _httpContext;
|
||||||
|
private readonly IConfiguration _config;
|
||||||
|
public PersonPhotoRepository(IConfiguration config,
|
||||||
|
FamilyTreeDBContext context,
|
||||||
|
IRelationShipd relationship,
|
||||||
|
IHttpContextAccessor httpContext)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_config = config;
|
||||||
|
_httpContext = httpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PersonPhotoDto FillDto(PersonPhoto model)
|
||||||
|
{
|
||||||
|
PersonPhotoDto dto = new();
|
||||||
|
dto.Id = model.Id;
|
||||||
|
dto.PersonId = model.PersonId;
|
||||||
|
dto.Photo = model.Photo;
|
||||||
|
dto.PhotoType = model.PhotoType;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
private PersonPhoto FillModel(PersonPhoto model, int personId, string filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
model.PersonId = personId;
|
||||||
|
model.Photo = filename;
|
||||||
|
model.PhotoType = System.IO.Path.GetExtension(filename);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveAsync(UploadCriteria criteria)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
|
||||||
|
HttpContext? httpContext = _httpContext.HttpContext;
|
||||||
|
string loginName = "";
|
||||||
|
if (httpContext != null)
|
||||||
|
{
|
||||||
|
UserDto? user = (UserDto?)httpContext.Items["User"];
|
||||||
|
if (user != null)
|
||||||
|
loginName = user.FirstName + " " + user.LastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFormFile formfile = criteria.File;
|
||||||
|
|
||||||
|
PersonPhoto model;
|
||||||
|
|
||||||
|
model = new();
|
||||||
|
|
||||||
|
model = FillModel(model,criteria.PersonId, formfile.FileName);
|
||||||
|
|
||||||
|
using (var stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
await formfile.CopyToAsync(stream);
|
||||||
|
model.ImagePhoto = stream.ToArray();
|
||||||
|
}
|
||||||
|
_context.PersonPhotos.Add(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
statuscode = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = -1;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<FileContent>> DownloadPersonPhoto(int id, string? filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
int statusCode = -1;
|
||||||
|
string error = "";
|
||||||
|
PersonPhoto? model = null;
|
||||||
|
FileContent fileContent = new();
|
||||||
|
if (id < 1)
|
||||||
|
{
|
||||||
|
var rlist = await _context.PersonPhotos.Where(x => x.Photo == filename).ToListAsync();
|
||||||
|
if (rlist != null)
|
||||||
|
{
|
||||||
|
if (rlist.Count > 0)
|
||||||
|
{
|
||||||
|
model = rlist[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model = await _context.PersonPhotos.FindAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
fileContent.ContentType = Helpers.GetFileContent(model.PhotoType);
|
||||||
|
fileContent.Content = (byte[])model.ImagePhoto;
|
||||||
|
fileContent.FileName = model.Photo;
|
||||||
|
statusCode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<FileContent>()
|
||||||
|
{
|
||||||
|
Data = fileContent,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<int>> DeletePersonPhoto(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)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = -1;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<PersonPhotoDto>>> LoadPersonPhoto(int personId)
|
||||||
|
{
|
||||||
|
List<PersonPhotoDto> result = new();
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
PersonPhotoDto dto;
|
||||||
|
PersonPhoto? model;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<PersonPhoto?> mlist = await _context.PersonPhotos.Where( x => x.PersonId == personId ).ToListAsync();
|
||||||
|
for (int i = 0; i< mlist.Count; i++)
|
||||||
|
{
|
||||||
|
model = mlist[i];
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
dto = FillDto(model);
|
||||||
|
result.Add(dto);
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<List<PersonPhotoDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,12 +20,15 @@ public partial class PersonRepository : IPerson
|
|||||||
private readonly FamilyTreeDBContext _context;
|
private readonly FamilyTreeDBContext _context;
|
||||||
private readonly IRelationShipd _relationship;
|
private readonly IRelationShipd _relationship;
|
||||||
private readonly IHttpContextAccessor _httpContext;
|
private readonly IHttpContextAccessor _httpContext;
|
||||||
|
private readonly IPersonPhoto _personPhoto;
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _config;
|
||||||
const string dateFormat = "yyyy-MM-dd";
|
const string dateFormat = "yyyy-MM-dd";
|
||||||
public PersonRepository(IConfiguration config, FamilyTreeDBContext context,
|
public PersonRepository(IConfiguration config, FamilyTreeDBContext context,
|
||||||
IRelationShipd relationship,
|
IRelationShipd relationship,
|
||||||
|
IPersonPhoto personPhoto,
|
||||||
IHttpContextAccessor httpContext)
|
IHttpContextAccessor httpContext)
|
||||||
{
|
{
|
||||||
|
_personPhoto = personPhoto;
|
||||||
_context = context;
|
_context = context;
|
||||||
_relationship = relationship;
|
_relationship = relationship;
|
||||||
_config = config;
|
_config = config;
|
||||||
@@ -410,6 +413,8 @@ public partial class PersonRepository : IPerson
|
|||||||
statuscode = 1;
|
statuscode = 1;
|
||||||
ResultModel<List<RelationShipDto>> rlist = await _relationship.GetByPersonIdAsync(dto.Id);
|
ResultModel<List<RelationShipDto>> rlist = await _relationship.GetByPersonIdAsync(dto.Id);
|
||||||
dto.RelationShips = rlist.Data;
|
dto.RelationShips = rlist.Data;
|
||||||
|
ResultModel<List<PersonPhotoDto>> personPhoto = await _personPhoto.LoadPersonPhoto(id);
|
||||||
|
dto.PersonPhotos = personPhoto.Data;
|
||||||
statuscode = rlist.StatusCode;
|
statuscode = rlist.StatusCode;
|
||||||
error = rlist.Message;
|
error = rlist.Message;
|
||||||
}
|
}
|
||||||
@@ -626,7 +631,7 @@ public partial class PersonRepository : IPerson
|
|||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
extention = System.IO.Path.GetExtension(criteria.FileName);
|
extention = System.IO.Path.GetExtension(criteria.FileName);
|
||||||
filename = criteria.FamilyId + "_" + sdate + extention;
|
filename = criteria.PersonId + "_" + sdate + extention;
|
||||||
|
|
||||||
using (var fileStream = new FileStream(System.IO.Path.Combine(path, filename), FileMode.Create))
|
using (var fileStream = new FileStream(System.IO.Path.Combine(path, filename), FileMode.Create))
|
||||||
{
|
{
|
||||||
@@ -670,7 +675,7 @@ public partial class PersonRepository : IPerson
|
|||||||
result = 1;
|
result = 1;
|
||||||
|
|
||||||
statusCode = 1;
|
statusCode = 1;
|
||||||
Person? model = _context.Persons.Find(criteria.FamilyId);
|
Person? model = _context.Persons.Find(criteria.Id);
|
||||||
if (model != null)
|
if (model != null)
|
||||||
{
|
{
|
||||||
model.Image = null;
|
model.Image = null;
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<div class="card gap-2">
|
||||||
|
<div class="mt-4">
|
||||||
|
<input type="file" class="file-input hidden" (change)="onFileSelected($event)" #fileUpload multiple>
|
||||||
|
<div class="file-upload">
|
||||||
|
<label>{{fileName || "Photo upload:"}}</label>
|
||||||
|
<button pButton type="button" icon="pi pi-paperclip"
|
||||||
|
class="p-button-rounded p-button-text p-button-raised ml-2" pTooltip="attach file"
|
||||||
|
(click)="fileUpload.click()"></button>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-end justify-end mt-4">
|
||||||
|
@if (files)
|
||||||
|
{
|
||||||
|
<button pButton pRipple type="button" icon="pi pi-upload" label="Add Photo" class="p-button-sm mr-2"
|
||||||
|
(click)="upload($event)"></button>
|
||||||
|
}
|
||||||
|
<button pButton pRipple type="button" icon="pi pi-times" label="Cancel" class="p-button-sm"
|
||||||
|
(click)="cancel($event)"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
import { ChangeDetectorRef, Component, inject, Inject, OnDestroy, OnInit, signal } from '@angular/core';
|
||||||
|
import { DynamicDialogModule, DynamicDialogRef ,DynamicDialogConfig} from 'primeng/dynamicdialog';
|
||||||
|
|
||||||
|
import { LookupEdit } from '../models';
|
||||||
|
import { UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { Subject, Subscription } from 'rxjs';
|
||||||
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||||
|
import { LookupService } from '../shares';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { CheckboxModule } from 'primeng/checkbox';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
@Component({
|
||||||
|
selector: 'add-photo',
|
||||||
|
imports: [CommonModule, ReactiveFormsModule,
|
||||||
|
ButtonModule, InputTextModule,
|
||||||
|
DynamicDialogModule, CheckboxModule],
|
||||||
|
templateUrl: './add.photo.html',
|
||||||
|
styleUrls: ['./add.photo.css'],
|
||||||
|
providers: [ConfirmationService]
|
||||||
|
})
|
||||||
|
export class AddPhoto implements OnInit, OnDestroy {
|
||||||
|
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||||
|
selType = "";
|
||||||
|
_error = "";
|
||||||
|
downloadFile = signal(false);
|
||||||
|
files: File[] = [];
|
||||||
|
fileName = "";
|
||||||
|
disabled: boolean = true;
|
||||||
|
subChanged$ = new Subject<boolean>();
|
||||||
|
private formBuilder = inject(UntypedFormBuilder);
|
||||||
|
private cdr = inject(ChangeDetectorRef);
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
lookupForm = this.formBuilder.group({
|
||||||
|
id: [0], //Validators.required
|
||||||
|
description: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
|
codeId: ['', [Validators.required]],
|
||||||
|
parentId: [0],
|
||||||
|
|
||||||
|
active: [false], //Validators.required
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
private lookupService: LookupService,
|
||||||
|
private messageService: MessageService,
|
||||||
|
private confirmationService: ConfirmationService,
|
||||||
|
public ref: DynamicDialogRef, public config: DynamicDialogConfig) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
const id = this.config.data.id;
|
||||||
|
this.selType = this.config.data.type;
|
||||||
|
const maxcodeId = this.config.data.maxCodeId;
|
||||||
|
if (id > 0) {
|
||||||
|
this.lookupService.loadLookupById(id, this.selType).subscribe({
|
||||||
|
next: x => {
|
||||||
|
this.assignValue(x.data);
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
this.subscription.add(this.lookupForm.valueChanges.subscribe(x => this.isChange = false));
|
||||||
|
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||||
|
|
||||||
|
},
|
||||||
|
error: e => {
|
||||||
|
console.error("error", e);
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error on load cleaner ', detail: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//new cleaner
|
||||||
|
const ward:LookupEdit = {
|
||||||
|
id: -1, description: '', codeId: maxcodeId, type: this.selType, active: true,
|
||||||
|
|
||||||
|
};
|
||||||
|
this.assignValue(ward);
|
||||||
|
this.subscription.add(this.lookupForm.valueChanges.subscribe(x => this.isChange = false));
|
||||||
|
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getClassForRequire(prev: string, name: string) {
|
||||||
|
const notok = !this.lookupForm.controls[name].valid &&
|
||||||
|
this.lookupForm.controls[name].touched;
|
||||||
|
let str = prev;
|
||||||
|
if (notok)
|
||||||
|
str += " ng-invalid ng-dirty";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
get isFieldsChange() {
|
||||||
|
const chan = this.isChange || !this.lookupForm.valid; // this disable so need true valid = true not
|
||||||
|
//console.log(this.msg + 'is fields change', chan);
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
assignValue(item: LookupEdit): void {
|
||||||
|
this.lookupForm.patchValue({
|
||||||
|
id: item.id,
|
||||||
|
codeId: item.codeId,
|
||||||
|
description: item.description,
|
||||||
|
active: item.active,
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
// disable use false//true for not disable.
|
||||||
|
this.subChanged$.next(true);
|
||||||
|
}
|
||||||
|
validate(item: LookupEdit): boolean {
|
||||||
|
let result = true;
|
||||||
|
if (item.description!.trim() == "") {
|
||||||
|
this._error = "Description is empty or blank";
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
deleteFile() : void {
|
||||||
|
//const filename = this.requestForm.value.attachmentFile;
|
||||||
|
// const data = { filename };
|
||||||
|
this.fileName ="";
|
||||||
|
//this.requestForm.patchValue({ attachmentFile: "" });
|
||||||
|
/*
|
||||||
|
const delete$ = this.tradePersonService.deleteUploadFile(data);
|
||||||
|
this.subscription.add(delete$.subscribe(
|
||||||
|
{
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1) {
|
||||||
|
{
|
||||||
|
this.requestForm.patchValue({ attachmentFile: "" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error delete upload file', detail: 'Fail to delete upload file: ' + x.message });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: e => {
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error delete upload file', detail: 'Fail to delete upload file: ' + e });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
onFileSelected(event: any) {
|
||||||
|
|
||||||
|
let i =0;
|
||||||
|
for (i = 0; i < event.target.files.length; i++)
|
||||||
|
{
|
||||||
|
const file: File = event.target.files[i];
|
||||||
|
this.files.push(file);
|
||||||
|
if (this.fileName != "")
|
||||||
|
this.fileName = this.fileName + "," + file.name;
|
||||||
|
else
|
||||||
|
this.fileName = file.name;
|
||||||
|
|
||||||
|
this.subChanged$.next(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
upload(e: Event): void {
|
||||||
|
e.preventDefault();
|
||||||
|
this.ref.close(this.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(e: Event): void {
|
||||||
|
e.preventDefault();
|
||||||
|
this.ref.close(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './photolist';
|
||||||
|
export * from './add.photo';
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<div class="shadow-xl rounded-md p-2">
|
||||||
|
<div class="flex fex-row justify-between mb-2">
|
||||||
|
<p> please click save at the end</p>
|
||||||
|
<div class="flex items-end self-end">
|
||||||
|
<button pButton pRipple type="button" icon="pi pi-file" label="Attach Photo" class="p-button-sm"
|
||||||
|
(click)="newSupportDoc($event)"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4">
|
||||||
|
<p-table [value]="FileList" sortMode="multiple" class="p-datatable-sm"
|
||||||
|
[loading]="loading">
|
||||||
|
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th pSortableColumn="description">Description<p-sortIcon field="description"></p-sortIcon>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>Action</th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="body" let-item>
|
||||||
|
<tr>
|
||||||
|
<td>{{item.id}}</td>
|
||||||
|
<td >{{item.photo}}</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<button pButton type="button" icon="pi pi-times" class="p-button-rounded p-button-text p-button-raised"
|
||||||
|
(click)="remove(item.id)"></button>
|
||||||
|
|
||||||
|
@if (item.id > 0) {
|
||||||
|
<button pButton type="button" icon="pi pi-file" class="p-button-rounded p-button-text p-button-raised"
|
||||||
|
(click)="downloadAttachment(item.id)"></button>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
<div class="flex items-end justify-end mt-4">
|
||||||
|
<button pButton pRipple type="button" icon="pi pi-times" label="Close" class="p-button-sm"
|
||||||
|
(click)="onClose($event)"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
//import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal, output } from '@angular/core';
|
||||||
|
import { catchError, EMPTY, finalize, Subscription } from 'rxjs';
|
||||||
|
import { CommonUtilities, HttpUtility, LookupService } from '../shares';
|
||||||
|
import { DialogService ,DynamicDialogConfig,DynamicDialogModule, DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
|
import { AddPhoto } from './add.photo';
|
||||||
|
import { LookupEdit, PersonPhotoDto } from '../models';
|
||||||
|
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { AuthenticationService } from '../user-services';
|
||||||
|
import { HttpResponse } from '@angular/common/http';
|
||||||
|
import { PersonService } from '../person';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'photo-list',
|
||||||
|
imports: [CommonModule, FormsModule, DynamicDialogModule,
|
||||||
|
ButtonModule, TableModule],
|
||||||
|
templateUrl: './photolist.html',
|
||||||
|
styleUrls: ['./photolist.css'],
|
||||||
|
providers: [DialogService]
|
||||||
|
})
|
||||||
|
export class PhotoList implements OnInit, OnDestroy {
|
||||||
|
FileList: PersonPhotoDto[] =[]
|
||||||
|
loading = false;
|
||||||
|
_id = -1;
|
||||||
|
deletePersonPhoto: number[] = [];
|
||||||
|
private authenticationService = inject(AuthenticationService);
|
||||||
|
private cdr = inject(ChangeDetectorRef);
|
||||||
|
private messageService = inject(MessageService);
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
downloadFile = signal(false);
|
||||||
|
constructor(
|
||||||
|
private http: HttpUtility,
|
||||||
|
private personService: PersonService,
|
||||||
|
|
||||||
|
public ref: DynamicDialogRef, public config: DynamicDialogConfig,
|
||||||
|
public dialogService: DialogService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
const id = this.config.data.id;
|
||||||
|
const olist = this.config.data.personPhotos;
|
||||||
|
if (olist && olist.length > 0)
|
||||||
|
{
|
||||||
|
this.FileList = olist;
|
||||||
|
this.assignFileId(olist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assignFileId(files: any[]): void {
|
||||||
|
let i = 0;
|
||||||
|
let id = -1;
|
||||||
|
let mx = 1;
|
||||||
|
for (i = 0; i < files.length; i++)
|
||||||
|
{
|
||||||
|
id = files[i].id;
|
||||||
|
if (id < mx)
|
||||||
|
{
|
||||||
|
mx = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._id = -1 + mx;
|
||||||
|
}
|
||||||
|
downloadAttachment(id: number): void {
|
||||||
|
//GetReportFile
|
||||||
|
|
||||||
|
let typeofCall = "personId_" + id.toString();
|
||||||
|
|
||||||
|
let criteria:any ={id, fileName:''};
|
||||||
|
this.downloadFile.set(false);
|
||||||
|
this.http.getFileResponse("api/FileUpload/downloadPersonPhoto", criteria).pipe(
|
||||||
|
catchError(err => {
|
||||||
|
console.error(err.message);
|
||||||
|
return EMPTY;
|
||||||
|
}),
|
||||||
|
finalize(() => {
|
||||||
|
// this.toastr.success("download completed ok to view now");
|
||||||
|
this.downloadFile.set(false);
|
||||||
|
|
||||||
|
})).subscribe((response: HttpResponse<Blob>) => {
|
||||||
|
if (response) {
|
||||||
|
console.log("the download report response", response);
|
||||||
|
CommonUtilities.downloadFile(response, typeofCall);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onClose(event: Event): void {
|
||||||
|
const nlist = this.FileList.filter( x => x.id < 1);
|
||||||
|
this.ref.close({list: nlist, deleteIds: this.deletePersonPhoto});
|
||||||
|
}
|
||||||
|
newSupportDoc(event: Event): void {
|
||||||
|
this.showEdit(this._id--);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(id: number): void {
|
||||||
|
if (id < 0)
|
||||||
|
{
|
||||||
|
const nlist = this.FileList.filter(x => x.id != id);
|
||||||
|
this.FileList = [...nlist];
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const deletepersonPhoto$ = this.personService.deletePersonPhotoFile(id);
|
||||||
|
this.subscription.add(deletepersonPhoto$.subscribe(
|
||||||
|
{
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1)
|
||||||
|
{
|
||||||
|
const nlist = this.FileList.filter(x => x.id != id);
|
||||||
|
this.FileList = [...nlist];
|
||||||
|
this.deletePersonPhoto.push(id);
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
this.messageService.add({severity:'success', summary: 'delete person photo', detail: "person photo Id " + id });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error:e => console.error("error in client delete person photo", e)
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
showEdit(id: number) {
|
||||||
|
const ref = this.dialogService.open(AddPhoto, {
|
||||||
|
data: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
header: 'Add File',
|
||||||
|
width: '70%',
|
||||||
|
maximizable: true,
|
||||||
|
draggable: true
|
||||||
|
});
|
||||||
|
if (ref)
|
||||||
|
{
|
||||||
|
ref.onClose.subscribe((list: File[]) => {
|
||||||
|
if (list) {
|
||||||
|
//console.log("after close ward edit", item);
|
||||||
|
this.messageService.add({ severity: 'success', summary: 'Attact File', detail: list.length.toString() });
|
||||||
|
let it = id;
|
||||||
|
for (let i = 0; i < list.length; i++)
|
||||||
|
{
|
||||||
|
const item = list[i];
|
||||||
|
this.FileList.push({id: it--, photo: item.name, photoType:'', file: item});
|
||||||
|
}
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<form runat="server">
|
||||||
|
<input accept="image/*" type='file' id="imgInp" />
|
||||||
|
<img id="blah" src="#" alt="your image" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
imgInp.onchange = evt => {
|
||||||
|
const [file] = imgInp.files
|
||||||
|
if (file) {
|
||||||
|
blah.src = URL.createObjectURL(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,3 +8,4 @@ export * from './staff';
|
|||||||
export * from './person';
|
export * from './person';
|
||||||
export * from './job';
|
export * from './job';
|
||||||
export * from './relationship';
|
export * from './relationship';
|
||||||
|
export * from './personphotodto';
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PersonPhotoDto } from "./personphotodto";
|
||||||
import { RelationShip } from "./relationship";
|
import { RelationShip } from "./relationship";
|
||||||
|
|
||||||
export interface FamilySearch {
|
export interface FamilySearch {
|
||||||
@@ -24,6 +25,7 @@ export interface Person {
|
|||||||
fatherName?:string |null;
|
fatherName?:string |null;
|
||||||
motherName?:string |null;
|
motherName?:string |null;
|
||||||
relationShips?: RelationShip[];
|
relationShips?: RelationShip[];
|
||||||
|
personPhotos?: PersonPhotoDto[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PersonContainer
|
export interface PersonContainer
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface PersonPhotoDto {
|
||||||
|
id: number;
|
||||||
|
photo:string|null | undefined;
|
||||||
|
photoType:string |null | undefined;
|
||||||
|
file: File | null | undefined;
|
||||||
|
}
|
||||||
@@ -1,2 +1,13 @@
|
|||||||
|
.profilePhotoBorder
|
||||||
|
{
|
||||||
|
|
||||||
|
border-color: gray;
|
||||||
|
border-width: 2px;
|
||||||
|
border-radius: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profilePhotoWH
|
||||||
|
{
|
||||||
|
width: 150px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
<form [formGroup]="adminuserForm" (ngSubmit)="onSubmit($event)" >
|
<form [formGroup]="adminuserForm" (ngSubmit)="onSubmit($event)" >
|
||||||
<div class="ml-2 grid md:grid-cols-2 gap-3 p-2">
|
<div class="ml-2 grid md:grid-cols-2 gap-3 p-2">
|
||||||
|
<div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<label for="lastname1">Surname<strong class="app-require">*</strong></label>
|
<label for="lastname1">Surname<strong class="app-require">*</strong></label>
|
||||||
<input id="lastname1" pInputText formControlName="lastname" type="text"
|
<input id="lastname1" pInputText formControlName="lastname" type="text" [pAutoFocus]="true"
|
||||||
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','lastname')">
|
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','lastname')">
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
@@ -12,6 +13,15 @@
|
|||||||
<input id="firstname" pInputText formControlName="firstname" type="text"
|
<input id="firstname" pInputText formControlName="firstname" type="text"
|
||||||
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','firstname')">
|
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','firstname')">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--put here photo of person-->
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<div>
|
||||||
|
<div class="">
|
||||||
|
<label for="dob" class="flex w-full">DOB</label>
|
||||||
|
<p-datepicker ariaLabelledBy="dob" formControlName="dob" [iconDisplay]="'input'" [showIcon]="true"
|
||||||
|
dateFormat="dd/mm/yy" ></p-datepicker>
|
||||||
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<label class="flex w-full">Sex <strong class="app-require">*</strong></label>
|
<label class="flex w-full">Sex <strong class="app-require">*</strong></label>
|
||||||
<p-select [options]="sexList" optionLabel="name" optionValue="status" placeholder="Select Gender"
|
<p-select [options]="sexList" optionLabel="name" optionValue="status" placeholder="Select Gender"
|
||||||
@@ -19,10 +29,41 @@
|
|||||||
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','sex')"
|
[class]="getClassForRequire('inputfield w-full p-inputtext-sm','sex')"
|
||||||
class="w-full p-inputtext-sm mr-1"></p-select >
|
class="w-full p-inputtext-sm mr-1"></p-select >
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
|
||||||
<label for="dob" class="flex w-full">DOB</label>
|
|
||||||
<p-datepicker ariaLabelledBy="dob" formControlName="dob" [iconDisplay]="'input'" [showIcon]="true" dateFormat="dd/mm/yy" ></p-datepicker>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-row shadow-md rounded-xl border-gray-100 border-1 p-4">
|
||||||
|
<!--a href="{{hostsite}}/{{adminuserForm.value.image}}" target="_blank" class="text-blue-400">View Attachment
|
||||||
|
</a-->
|
||||||
|
<input type="file" class="file-input hidden" (change)="onFileSelected($event)" #fileUpload>
|
||||||
|
@if (adminuserForm.value.image != "" && adminuserForm.value.image != null)
|
||||||
|
{
|
||||||
|
<img id="blah" [src]= "dislayImage()" alt="your image"
|
||||||
|
class="profilePhotoWH profilePhotoBorder" (click)="doViewImage(adminuserForm.value.image)" />
|
||||||
|
|
||||||
|
}
|
||||||
|
@else
|
||||||
|
{
|
||||||
|
<div class="file-upload profilePhotoBorder profilePhotoWH text-center flex justify-center items-center ">
|
||||||
|
<label class="">{{ adminuserForm.value.image || "No Profile Photo."}}</label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
@if (adminuserForm.value.image != "" && adminuserForm.value.image != null)
|
||||||
|
{
|
||||||
|
<button pButton type="button" icon="pi pi-times" pTooltip="remove profile photo"
|
||||||
|
class="p-button-rounded p-button-text text-red-500 p-button-raised ml-2"
|
||||||
|
(click)="deleteFile()"></button>
|
||||||
|
}
|
||||||
|
<button pButton type="button" icon="pi pi-paperclip"
|
||||||
|
class="self-end p-button-rounded p-button-text p-button-raised ml-2" pTooltip="load photo"
|
||||||
|
(click)="fileUpload.click()"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<label for="login">Email</label>
|
<label for="login">Email</label>
|
||||||
<input id="login" [attr.disabled]="!isNew?true:null" pInputText formControlName="email"
|
<input id="login" [attr.disabled]="!isNew?true:null" pInputText formControlName="email"
|
||||||
@@ -50,41 +91,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="field col-12 md:col-6 sm:col-8">
|
|
||||||
<div class="shadow-md rounded-xl border-gray-100 border-1 p-4">
|
|
||||||
@if (adminuserForm.value.image != "" && adminuserForm.value.image != null)
|
|
||||||
{
|
|
||||||
<div class="ml-6 file-upload">
|
|
||||||
<!--a href="{{hostsite}}/{{adminuserForm.value.image}}" target="_blank" class="text-blue-400">View Attachment
|
|
||||||
</a-->
|
|
||||||
<button pButton type="button" icon="pi pi-image"
|
|
||||||
class ="p-ripple p-button p-button-raised p-button-text p-button-warn p-component"
|
|
||||||
pTooltip="view Image" (click)="doViewImage(adminuserForm.value.image)"></button>
|
|
||||||
<button pButton type="button" icon="pi pi-times" pTooltip="remove attach file"
|
|
||||||
class="p-button-rounded p-button-text text-red-500 p-button-raised ml-2"
|
|
||||||
(click)="deleteFile()"></button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@else
|
|
||||||
{
|
|
||||||
<div class="ml-6 ">
|
|
||||||
<input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload>
|
|
||||||
<div class="file-upload">
|
|
||||||
<label>{{ adminuserForm.value.image || "No attachment file uploaded yet."}}</label>
|
|
||||||
<button pButton type="button" icon="pi pi-paperclip"
|
|
||||||
class="p-button-rounded p-button-text p-button-raised ml-2" pTooltip="attach file"
|
|
||||||
(click)="fileUpload.click()"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-2 w-full">
|
<div class="mt-2 w-full">
|
||||||
<p-button class="flex justify-end mr-2" icon="pi pi-user" [raised]="true" severity="info" label="Add Partner"
|
<div class="flex flex-row justify-between">
|
||||||
|
<p-button icon="pi pi-images" [raised]="true"
|
||||||
|
badge="{{photoList.length}}"
|
||||||
|
severity="success" label="Attach Photos"
|
||||||
|
(onClick)="viewAttachment()"/>
|
||||||
|
<p-button icon="pi pi-user" [raised]="true" severity="info" label="Add Partner"
|
||||||
(onClick)="addPartner()"/>
|
(onClick)="addPartner()"/>
|
||||||
|
</div>
|
||||||
<div class="shadow rounded mt-2 mb-2">
|
<div class="shadow rounded mt-2 mb-2">
|
||||||
<p-table [value]="partners()">
|
<p-table [value]="partners()">
|
||||||
<ng-template #header>
|
<ng-template #header>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { FormControl, ReactiveFormsModule, UntypedFormBuilder, Validators } from
|
|||||||
import { Subject, Subscription} from 'rxjs';
|
import { Subject, Subscription} from 'rxjs';
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||||
import { DatePickerModule } from 'primeng/datepicker';
|
import { DatePickerModule } from 'primeng/datepicker';
|
||||||
import { Code, RelationShipView, Person, mState, RelationShip} from '../models';
|
import { Code, RelationShipView, Person, mState, RelationShip, PersonPhotoDto} from '../models';
|
||||||
import { AppSettingService, LookupService, Utils } from '../shares';
|
import { AppSettingService, LookupService, Utils } from '../shares';
|
||||||
import { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from 'primeng/button';
|
||||||
@@ -19,6 +19,9 @@ import { TableModule } from 'primeng/table';
|
|||||||
import { Pickperson } from '../pickperson/pickperson';
|
import { Pickperson } from '../pickperson/pickperson';
|
||||||
import { ImageDisplayComponent } from '../pickperson/image.display';
|
import { ImageDisplayComponent } from '../pickperson/image.display';
|
||||||
import { TooltipModule } from 'primeng/tooltip';
|
import { TooltipModule } from 'primeng/tooltip';
|
||||||
|
import { AutoFocusModule } from 'primeng/autofocus';
|
||||||
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
|
import { PhotoList } from '../attachphoto/photolist';
|
||||||
|
|
||||||
export interface FileUploadEvent {
|
export interface FileUploadEvent {
|
||||||
originalEvent: HttpEvent<any>;
|
originalEvent: HttpEvent<any>;
|
||||||
@@ -32,6 +35,7 @@ export interface FileUploadHandlerEvent {
|
|||||||
templateUrl: 'person.edit.html',
|
templateUrl: 'person.edit.html',
|
||||||
selector: 'person-edit',
|
selector: 'person-edit',
|
||||||
imports:[ButtonModule,TableModule,ReactiveFormsModule,TooltipModule,
|
imports:[ButtonModule,TableModule,ReactiveFormsModule,TooltipModule,
|
||||||
|
AutoFocusModule,
|
||||||
SelectModule,CheckboxModule, InputTextModule,DatePickerModule],
|
SelectModule,CheckboxModule, InputTextModule,DatePickerModule],
|
||||||
styleUrls: ['person.edit.css'],
|
styleUrls: ['person.edit.css'],
|
||||||
providers: [DialogService]
|
providers: [DialogService]
|
||||||
@@ -39,6 +43,8 @@ providers: [DialogService]
|
|||||||
})
|
})
|
||||||
export class PersonEdit implements OnInit, OnDestroy {
|
export class PersonEdit implements OnInit, OnDestroy {
|
||||||
editRef: DynamicDialogRef | undefined;
|
editRef: DynamicDialogRef | undefined;
|
||||||
|
private sanitizer = inject(DomSanitizer);
|
||||||
|
imageDataUrl = signal<string>("");
|
||||||
returnUrl ='';
|
returnUrl ='';
|
||||||
loginUser ='';
|
loginUser ='';
|
||||||
hostsite ='';
|
hostsite ='';
|
||||||
@@ -49,7 +55,8 @@ export class PersonEdit implements OnInit, OnDestroy {
|
|||||||
motherList: Code[] =[];
|
motherList: Code[] =[];
|
||||||
sexList:Code[] =[];
|
sexList:Code[] =[];
|
||||||
familyList: Person[] =[];
|
familyList: Person[] =[];
|
||||||
file: File | null = null;
|
profileFile: File | null = null;
|
||||||
|
photoList: PersonPhotoDto[] = [];
|
||||||
fileName = '';
|
fileName = '';
|
||||||
isNew = false;
|
isNew = false;
|
||||||
validationPoints?: Code[];
|
validationPoints?: Code[];
|
||||||
@@ -126,15 +133,27 @@ getClassForRequire(prev:string,name:string){
|
|||||||
str += " ng-invalid ng-dirty";
|
str += " ng-invalid ng-dirty";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
dislayImage(): any {
|
||||||
|
if (this.profileFile)
|
||||||
|
{
|
||||||
|
return URL.createObjectURL(this.profileFile);
|
||||||
|
}
|
||||||
|
else if (this.imageDataUrl() != "")
|
||||||
|
{
|
||||||
|
return this.imageDataUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
onFileSelected(event: any) {
|
onFileSelected(event: any) {
|
||||||
|
|
||||||
const file: File = event.target.files[0];
|
const file: File = event.target.files[0];
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
this.file = file;
|
this.profileFile = file;
|
||||||
//this.messageService.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded!' });
|
//this.messageService.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded!' });
|
||||||
this.adminuserForm.patchValue({ image: this.file.name });
|
this.adminuserForm.patchValue({ image: this.profileFile.name });
|
||||||
this.fileName = file.name;
|
this.fileName = file.name;
|
||||||
this.subChanged$.next(false);
|
this.subChanged$.next(false);
|
||||||
}
|
}
|
||||||
@@ -165,6 +184,14 @@ deleteFile(): void {
|
|||||||
|
|
||||||
doDeleteFile(): void {
|
doDeleteFile(): void {
|
||||||
const fileName = this.adminuserForm.value.image;
|
const fileName = this.adminuserForm.value.image;
|
||||||
|
if (fileName)
|
||||||
|
{
|
||||||
|
this.doDeleteImage(fileName);
|
||||||
|
}
|
||||||
|
else if (this.profileFile)
|
||||||
|
this.profileFile = null;
|
||||||
|
}
|
||||||
|
doDeleteImage(fileName:string) : void {
|
||||||
const familyId = this.adminuserForm.value.id;
|
const familyId = this.adminuserForm.value.id;
|
||||||
const data = { fileName, familyId };
|
const data = { fileName, familyId };
|
||||||
const delete$ = this.personService.deleteUploadFile(data);
|
const delete$ = this.personService.deleteUploadFile(data);
|
||||||
@@ -187,8 +214,6 @@ doDeleteFile(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileToSave(file: File): FormData {
|
getFileToSave(file: File): FormData {
|
||||||
@@ -285,7 +310,6 @@ doViewImage(imageName:string): void {
|
|||||||
data: {
|
data: {
|
||||||
imageName,
|
imageName,
|
||||||
},
|
},
|
||||||
|
|
||||||
header: 'View Image',
|
header: 'View Image',
|
||||||
draggable: true,
|
draggable: true,
|
||||||
width: '70%',
|
width: '70%',
|
||||||
@@ -308,6 +332,10 @@ assignValue(item:Person): void {
|
|||||||
this.fileName = item.image!;
|
this.fileName = item.image!;
|
||||||
if (item.relationShips)
|
if (item.relationShips)
|
||||||
this.populatePartner(item.relationShips, item.id);
|
this.populatePartner(item.relationShips, item.id);
|
||||||
|
if (item.personPhotos)
|
||||||
|
{
|
||||||
|
this.photoList = item.personPhotos;
|
||||||
|
}
|
||||||
this.adminuserForm.patchValue({
|
this.adminuserForm.patchValue({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
email: item.email,
|
email: item.email,
|
||||||
@@ -328,12 +356,42 @@ assignValue(item:Person): void {
|
|||||||
dob: moment(dob).toDate()
|
dob: moment(dob).toDate()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (item.image && item.image.length > 0)
|
||||||
|
{
|
||||||
|
this.loadImage(item.image);
|
||||||
|
}
|
||||||
// disable use false//true for not disable.
|
// disable use false//true for not disable.
|
||||||
this.subChanged$.next(true);
|
this.subChanged$.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// convenience getter for easy access in form fields
|
// convenience getter for easy access in form fields
|
||||||
get f() { return this.adminuserForm.controls;}
|
get f() { return this.adminuserForm.controls;}
|
||||||
|
|
||||||
|
loadImage(fileName: string| null): void {
|
||||||
|
const download = this.personService.downloadFile(fileName!);
|
||||||
|
this.subscription.add(download.subscribe({
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.displayIamge64(x.data);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("error in download in api ", x.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: e => console.error("error in download image", e)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
displayIamge64(baseImage: string): void
|
||||||
|
{
|
||||||
|
const changeUrl = (this.sanitizer.bypassSecurityTrustResourceUrl(baseImage) as any).changingThisBreaksApplicationSecurity;
|
||||||
|
console.log('this is bypassSecurityTrustResourceUrl', changeUrl);
|
||||||
|
const fullDataUri = `data:image/png;base64,${changeUrl}`;
|
||||||
|
this.imageDataUrl.set(fullDataUri);
|
||||||
|
}
|
||||||
validate(adminuser:Person): boolean {
|
validate(adminuser:Person): boolean {
|
||||||
let result = true;
|
let result = true;
|
||||||
console.log("validate", adminuser);
|
console.log("validate", adminuser);
|
||||||
@@ -383,8 +441,6 @@ assignValue(item:Person): void {
|
|||||||
}
|
}
|
||||||
console.log("get partner for save in partner list ", vitem);
|
console.log("get partner for save in partner list ", vitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return rlist;
|
return rlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,10 +479,10 @@ assignValue(item:Person): void {
|
|||||||
let container:any = {
|
let container:any = {
|
||||||
person: item
|
person: item
|
||||||
};
|
};
|
||||||
if (this.file != null)
|
if (this.profileFile != null)
|
||||||
{
|
{
|
||||||
container.formData = await Utils.toBase64(this.file);
|
container.formData = await Utils.toBase64(this.profileFile);
|
||||||
container.fileName = this.file.name;
|
container.fileName = this.profileFile.name;
|
||||||
console.log('image as base64 ', container);
|
console.log('image as base64 ', container);
|
||||||
}
|
}
|
||||||
container.person.relationShips = this.getPartnerForSave();
|
container.person.relationShips = this.getPartnerForSave();
|
||||||
@@ -439,6 +495,12 @@ assignValue(item:Person): void {
|
|||||||
// this.messageService.add({severity:'success', summary: 'Save user', detail: item.firstName + " " + item.lastName });
|
// this.messageService.add({severity:'success', summary: 'Save user', detail: item.firstName + " " + item.lastName });
|
||||||
//this.router.navigate([this.returnUrl]);
|
//this.router.navigate([this.returnUrl]);
|
||||||
console.log("the person after save", item);
|
console.log("the person after save", item);
|
||||||
|
const list = this.getPhotoListforSave();
|
||||||
|
if (list.length > 0)
|
||||||
|
{
|
||||||
|
this.savePhotoList(list, item);
|
||||||
|
}
|
||||||
|
else
|
||||||
this.ref.close(item);
|
this.ref.close(item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -498,7 +560,9 @@ populatePartner(list: RelationShip[], personId: number): void {
|
|||||||
if (vlist.length > 0)
|
if (vlist.length > 0)
|
||||||
this.partners.set(vlist);
|
this.partners.set(vlist);
|
||||||
}
|
}
|
||||||
|
viewAttachment(): void {
|
||||||
|
this.showAttachment("Add family photo or other");
|
||||||
|
}
|
||||||
|
|
||||||
addPartner(): void {
|
addPartner(): void {
|
||||||
const title = "Partner";
|
const title = "Partner";
|
||||||
@@ -575,6 +639,113 @@ showPickPerson(title:string, callback:(id: Person) => void) :void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showAttachment(title:string): void {
|
||||||
|
const ref = this.dialogService.open(PhotoList, {
|
||||||
|
data: {
|
||||||
|
id: this._id,
|
||||||
|
personPhotos: this.photoList
|
||||||
|
},
|
||||||
|
header: title,
|
||||||
|
width: '80%',
|
||||||
|
draggable: true,
|
||||||
|
maximizable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
ref.onClose.subscribe((ritem: any) => {
|
||||||
|
const item = ritem.list;
|
||||||
|
const deleteIds = ritem.deleteIds;
|
||||||
|
if (item) {
|
||||||
|
console.log("after close " + title, item);
|
||||||
|
this.messageService.add({severity:'success', summary: title, detail: "photo attachment " + item.length});
|
||||||
|
//update the current list
|
||||||
|
// callback(item);
|
||||||
|
this.updatePhotoList(item);
|
||||||
|
}
|
||||||
|
if (deleteIds && deleteIds.length > 0)
|
||||||
|
{
|
||||||
|
let j = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < deleteIds.length; i++)
|
||||||
|
{
|
||||||
|
const id = deleteIds[i];
|
||||||
|
j = this.photoList.findIndex(x => x.id == id);
|
||||||
|
if (j > -1)
|
||||||
|
{
|
||||||
|
this.photoList.splice(j,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePhotoList(list: PersonPhotoDto[]): void {
|
||||||
|
for (let i = 0; i < list.length; i++)
|
||||||
|
{
|
||||||
|
const item = list[i];
|
||||||
|
const idx = this.photoList.findIndex(x => x.id == item.id);
|
||||||
|
if (idx && idx < 0)
|
||||||
|
this.photoList.push(item);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let eitem = this.photoList[idx];
|
||||||
|
eitem.photo = item.photo;
|
||||||
|
eitem.photoType = item.photoType;
|
||||||
|
eitem.file = item.file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("the photos after close", this.photoList);
|
||||||
|
this.subChanged$.next(false);//make save button to enable.
|
||||||
|
this.cdr.markForCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
getPhotoListforSave(): PersonPhotoDto[] {
|
||||||
|
let result: PersonPhotoDto[] =[];
|
||||||
|
for (let i = 0; i < this.photoList.length; i++)
|
||||||
|
{
|
||||||
|
if (this.photoList[i].id < 0)
|
||||||
|
{
|
||||||
|
result.push(this.photoList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
savePhotoList(list: PersonPhotoDto[], item:Person): void {
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
for (let i = 0; i < list.length; i++)
|
||||||
|
{
|
||||||
|
const file = list[i].file;
|
||||||
|
if (file)
|
||||||
|
formData.append("files", file, file.name);
|
||||||
|
}
|
||||||
|
formData.append('personId', this._id.toString());
|
||||||
|
|
||||||
|
const personPhoto$ = this.personService.savePersonPhotoList(formData);
|
||||||
|
this.subscription.add(personPhoto$.subscribe(
|
||||||
|
{
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1) {
|
||||||
|
//const filename = x.data;
|
||||||
|
//this.adminuserForm.patchValue({ image: filename });
|
||||||
|
this.ref.close(item);
|
||||||
|
//this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error save attach photos files', detail: 'Fail to photos file: ' + x.message });
|
||||||
|
},
|
||||||
|
error: e =>
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error attach photos file', detail: 'Fail to photos file: ' })
|
||||||
|
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cancel(e:Event):void {
|
cancel(e:Event):void {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.ref.close(null);
|
this.ref.close(null);
|
||||||
|
|||||||
@@ -89,4 +89,21 @@ export class PersonService {
|
|||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/DeleteUploadFile";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/DeleteUploadFile";
|
||||||
return this.http.post<ResultModel<number>>(baseUrl, data);
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
|
deletePersonPhotoFile(id: number): Observable<ResultModel<number>> {
|
||||||
|
const data ={id, fileName:''};
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DeletePersonPhoto";
|
||||||
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
|
}
|
||||||
|
savePersonPhotoList(data:FormData): Observable<ResultModel<number>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/SavePersonPhoto";
|
||||||
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
|
}
|
||||||
|
downloadPersonPhoto(id: number): Observable<ResultModel<string>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadPersonPhoto";
|
||||||
|
const data = {
|
||||||
|
id,
|
||||||
|
fileName: ''
|
||||||
|
};
|
||||||
|
return this.http.post<ResultModel<string>>(baseUrl, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,13 @@ static formatNode(item:Person): TreeNode
|
|||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
static getFileExtension(filename: string): string {
|
||||||
|
const lastDotIndex = filename.lastIndexOf('.');
|
||||||
|
if (lastDotIndex !== -1 && lastDotIndex < filename.length - 1) { // Ensure a dot exists and is not the last character
|
||||||
|
return filename.substring(lastDotIndex + 1);
|
||||||
|
}
|
||||||
|
return ''; // No extension found
|
||||||
|
}
|
||||||
static getChildForParentId(proName: MyProName , pid: number,childressNodes: Person[]): TreeNode[] {
|
static getChildForParentId(proName: MyProName , pid: number,childressNodes: Person[]): TreeNode[] {
|
||||||
let result: TreeNode[] =[];
|
let result: TreeNode[] =[];
|
||||||
let tree_node_child: TreeNode[];
|
let tree_node_child: TreeNode[];
|
||||||
|
|||||||
Reference in New Issue
Block a user