add in import person and logic
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
using FamilyTreeAPI.Entities;
|
||||||
|
using FamilyTreeAPI.Repository;
|
||||||
|
|
||||||
|
namespace FamilyTreeAPI.Controllers;
|
||||||
|
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class FileUploadController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IWebHostEnvironment _hostingEnvironment;
|
||||||
|
private readonly ImportPersonRepository _importPersonRepository;
|
||||||
|
public FileUploadController(IWebHostEnvironment hostingEnvironment, ImportPersonRepository importPersonRepository)
|
||||||
|
{
|
||||||
|
_hostingEnvironment = hostingEnvironment;
|
||||||
|
_importPersonRepository = importPersonRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("UploadFile")]
|
||||||
|
public async Task<IActionResult> UploadFile(IFormFile file)
|
||||||
|
{
|
||||||
|
List<CodeDto<string>> output = new ();
|
||||||
|
if (file == null || file.Length == 0)
|
||||||
|
{
|
||||||
|
return BadRequest("No file uploaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Define the upload directory
|
||||||
|
// var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
|
||||||
|
var uploadsFolder = Path.Combine(_hostingEnvironment.ContentRootPath, "uploads");
|
||||||
|
if (!Directory.Exists(uploadsFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(uploadsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a unique file name to avoid overwriting
|
||||||
|
var uniqueFileName = Path.GetFileNameWithoutExtension(file.FileName)
|
||||||
|
+ "_" + System.Guid.NewGuid().ToString()
|
||||||
|
+ Path.GetExtension(file.FileName);
|
||||||
|
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
|
||||||
|
|
||||||
|
// Save the file to the server
|
||||||
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
|
{
|
||||||
|
// await file.CopyToAsync(stream);
|
||||||
|
await file.CopyToAsync(stream);
|
||||||
|
output = await _importPersonRepository.ImportPerson(stream, "Sheet1");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//return Ok(new { FileName = uniqueFileName, FilePath = filePath });
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,23 @@
|
|||||||
namespace FamilyTreeAPI.Entities;
|
namespace FamilyTreeAPI.Entities;
|
||||||
|
|
||||||
|
public class CodeDto<T>
|
||||||
|
{
|
||||||
|
public T Code { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//using to store id from file then after insert now the real id from db
|
||||||
|
// the put that in and update the db
|
||||||
|
public class MappingFatherMother
|
||||||
|
{
|
||||||
|
public int TId { get; set; }
|
||||||
|
public int IId { get; set; }
|
||||||
|
public int TFatherId { get; set; }
|
||||||
|
public int TMotherId { get; set; }
|
||||||
|
public int IFatherId { get; set; }
|
||||||
|
public int IMotherId { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
public class LookupDto
|
public class LookupDto
|
||||||
{
|
{
|
||||||
public int Id { get; set; } = 0;
|
public int Id { get; set; } = 0;
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
1)
|
||||||
|
ubuntu
|
||||||
|
$) sudo bash
|
||||||
|
$) apt-get update
|
||||||
|
$) apt-get install dotnet-sdk-8.0
|
||||||
|
$) apt-get install dotnet-runtime-8.0
|
||||||
|
$) apt-get install aspnet-core-runtime-8.0
|
||||||
|
$) dotnet --info
|
||||||
|
$) apt-get install nginx
|
||||||
|
|
||||||
|
Copy the Files to the Linux Server
|
||||||
|
Next, we need to copy the deployment files to the Ubuntu server. Before we move the files,
|
||||||
|
let’s create the destination folder on the server and set the permissions
|
||||||
|
so that we can add files to it:
|
||||||
|
|
||||||
|
$) cd /var/www
|
||||||
|
$) sudo mkdir app
|
||||||
|
$) sudo chmod 777 app
|
||||||
|
|
||||||
|
Run the App on a Kestrel Web Server
|
||||||
|
In a terminal, navigate to the deployment path and run the app in Kestrel:
|
||||||
|
cd /var/www/app
|
||||||
|
sudo dotnet DeployingToLinuxWithNginx.dll
|
||||||
|
|
||||||
|
//edit nginx config file
|
||||||
|
$ sudo nano /etc/nginx/sites-avaible/default
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection keep-alive;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sudo nginx -t
|
||||||
|
sudo nginx -s reload
|
||||||
|
|
||||||
|
To create the service, we first need to create the configurations in a systemd unit file.
|
||||||
|
The unit file contains information regarding the unit, which is a service in this case.
|
||||||
|
For services, it should have the .service extension and contain some
|
||||||
|
information about the service. These files are required to be in the
|
||||||
|
/etc/systemd/system directory.
|
||||||
|
|
||||||
|
Let’s use “nano” to create the unit file and name it kestrel-app.service:
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=ASP.NET Core Web App running on Ubuntu
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/var/www/app
|
||||||
|
ExecStart=/usr/bin/dotnet /var/www/app/DeployingToLinuxWithNginx.dll
|
||||||
|
Restart=always
|
||||||
|
# Restart service after 10 seconds if the dotnet service crashes:
|
||||||
|
RestartSec=10
|
||||||
|
KillSignal=SIGINT
|
||||||
|
SyslogIdentifier=dotnet-web-app
|
||||||
|
# This user should exist on the server and have ownership of the deployment directory
|
||||||
|
User=www-data
|
||||||
|
Environment=ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
After adding the content, save it. Then let’s enable and start the service:
|
||||||
|
sudo systemctl enable kestrel-app.service
|
||||||
|
sudo systemctl start kestrel-app.service
|
||||||
@@ -48,7 +48,7 @@ services.AddAuthentication(x =>
|
|||||||
});
|
});
|
||||||
services.AddHttpContextAccessor();
|
services.AddHttpContextAccessor();
|
||||||
services.AddScoped<IJwtUtils, JwtUtils>();
|
services.AddScoped<IJwtUtils, JwtUtils>();
|
||||||
|
services.AddScoped<ImportPersonRepository>();
|
||||||
services.AddDbContext<FamilyTreeDBContext>(options =>
|
services.AddDbContext<FamilyTreeDBContext>(options =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using FamilyTreeAPI.Entities;
|
||||||
|
using FamilyTreeAPI.Interface;
|
||||||
|
using FamilyTreeAPI.Models;
|
||||||
|
using SpreadsheetLight;
|
||||||
|
|
||||||
|
namespace FamilyTreeAPI.Repository;
|
||||||
|
|
||||||
|
public class ImportPersonRepository
|
||||||
|
{
|
||||||
|
enum enumIdx
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
FirstName,
|
||||||
|
LastName,
|
||||||
|
Email,
|
||||||
|
Phone,
|
||||||
|
Image,
|
||||||
|
Sex,
|
||||||
|
Address,
|
||||||
|
Alive,
|
||||||
|
Dob,
|
||||||
|
FatherId,
|
||||||
|
MotherId,
|
||||||
|
|
||||||
|
}
|
||||||
|
private FamilyTreeDBContext _context;
|
||||||
|
private IConfiguration _config;
|
||||||
|
private IHttpContextAccessor _httpContext;
|
||||||
|
private IRelationShipd _relationship;
|
||||||
|
public ImportPersonRepository(IConfiguration config, FamilyTreeDBContext context,
|
||||||
|
IRelationShipd relationship,
|
||||||
|
IHttpContextAccessor httpContext)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_relationship = relationship;
|
||||||
|
_config = config;
|
||||||
|
_httpContext = httpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<CodeDto<string>>> ImportPerson(FileStream fileStream, string sheetName)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
List<CodeDto<string>> output = new();
|
||||||
|
Dictionary<int,MappingFatherMother> updateperson = new();
|
||||||
|
CodeDto<string> colums;
|
||||||
|
List<int> ids = new();
|
||||||
|
Person person;
|
||||||
|
Person? uperson;
|
||||||
|
MappingFatherMother mitem,faitem,moitem;
|
||||||
|
int fid, mid;
|
||||||
|
MemoryStream msFirstPass = new MemoryStream();
|
||||||
|
SLDocument sl = new SLDocument(fileStream, sheetName);
|
||||||
|
// There is no way that I can see to get the Rows
|
||||||
|
SLWorksheetStatistics stats = sl.GetWorksheetStatistics();
|
||||||
|
for (int row = 1; row <= stats.NumberOfRows; row++)
|
||||||
|
{
|
||||||
|
person = new Person();
|
||||||
|
mitem = new();
|
||||||
|
id = sl.GetCellValueAsInt32(row, (int) enumIdx.Id);
|
||||||
|
mitem.IId = id;
|
||||||
|
person.FirstName = sl.GetCellValueAsString(row, (int) enumIdx.FirstName);
|
||||||
|
person.LastName = sl.GetCellValueAsString(row, (int) enumIdx.LastName);
|
||||||
|
person.Email = sl.GetCellValueAsString(row, (int) enumIdx.Email);
|
||||||
|
person.Phone = sl.GetCellValueAsString(row, (int) enumIdx.Phone);
|
||||||
|
person.Image = sl.GetCellValueAsString(row, (int) enumIdx.Image);
|
||||||
|
person.Alive = sl.GetCellValueAsBoolean(row, (int) enumIdx.Alive);
|
||||||
|
person.dob = sl.GetCellValueAsDateTime(row, (int) enumIdx.Dob);
|
||||||
|
mitem.IFatherId = sl.GetCellValueAsInt32(row, (int) enumIdx.FatherId);
|
||||||
|
mitem.IMotherId = sl.GetCellValueAsInt32(row, (int) enumIdx.MotherId);
|
||||||
|
_context.Persons.Add(person);
|
||||||
|
_context.SaveChanges();
|
||||||
|
mitem.TId = person.Id;
|
||||||
|
ids.Add(id);
|
||||||
|
updateperson.Add(mitem.IId, mitem);
|
||||||
|
colums = new();
|
||||||
|
colums.Code = $"{mitem.IId} {mitem.IFatherId} {mitem.IMotherId}";
|
||||||
|
colums.Description = $"{mitem.TId} {mitem.TFatherId} {mitem.TMotherId}";
|
||||||
|
output.Add(colums);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ids.Count; i++)
|
||||||
|
{
|
||||||
|
id = ids[i];
|
||||||
|
mitem = updateperson[id];
|
||||||
|
fid = mitem.IFatherId;
|
||||||
|
if (updateperson.ContainsKey(fid))
|
||||||
|
{
|
||||||
|
faitem = updateperson[fid];
|
||||||
|
mitem.TFatherId = faitem.TId;
|
||||||
|
}
|
||||||
|
mid = mitem.IMotherId;
|
||||||
|
if (updateperson.ContainsKey(mid))
|
||||||
|
{
|
||||||
|
moitem = updateperson[mid];
|
||||||
|
mitem.TMotherId = moitem.TId;
|
||||||
|
}
|
||||||
|
|
||||||
|
uperson = await _context.Persons.FindAsync(mitem.TId);
|
||||||
|
if (uperson == null) continue;
|
||||||
|
uperson.FatherId = mitem.TFatherId;
|
||||||
|
uperson.MotherId = mitem.TMotherId;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Generated
-10378
File diff suppressed because it is too large
Load Diff
@@ -3,12 +3,14 @@ import { Login } from './login';
|
|||||||
import { StaffComponent, StaffEditComponent } from './staff';
|
import { StaffComponent, StaffEditComponent } from './staff';
|
||||||
import { AuthGuard } from './route-guard';
|
import { AuthGuard } from './route-guard';
|
||||||
import { FamilyTree, FamilyList} from './person';
|
import { FamilyTree, FamilyList} from './person';
|
||||||
|
import { ImportCom } from './import.com/import.com';
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
||||||
// { path: 'approval', component: ApprovalComponent,canActivate: [AuthGuard], data: { roleAllowed: '1,2,3' }},},
|
// { path: 'approval', component: ApprovalComponent,canActivate: [AuthGuard], data: { roleAllowed: '1,2,3' }},},
|
||||||
{ path: 'login', component: Login},
|
{ path: 'login', component: Login},
|
||||||
{ path: 'staff', component: StaffComponent},
|
{ path: 'staff', component: StaffComponent},
|
||||||
{ path: 'person', component: FamilyList},
|
{ path: 'person', component: FamilyList},
|
||||||
|
{ path: 'import', component: ImportCom},
|
||||||
{ path: 'familytree', component: FamilyTree},
|
{ path: 'familytree', component: FamilyTree},
|
||||||
{ path: 'staff/:id', component: StaffEditComponent},
|
{ path: 'staff/:id', component: StaffEditComponent},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user