Add DrillingProgramController

This commit is contained in:
Фролов 2021-08-29 17:25:16 +05:00
parent 002da70471
commit 14cf99a1dd
14 changed files with 343 additions and 159 deletions

View File

@ -5,8 +5,10 @@ namespace AsbCloudApp.Data
public class FileInfoDto public class FileInfoDto
{ {
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public int IdWell { get; set; }
public int IdCategory { get; set; } public int IdCategory { get; set; }
public int IdAuthor { get; set; }
public string Name { get; set; }
public DateTime UploadDate { get; set; } public DateTime UploadDate { get; set; }
public string AuthorName { get; set; } public string AuthorName { get; set; }
public int CompanyId { get; set; } public int CompanyId { get; set; }

View File

@ -0,0 +1,11 @@
using AsbCloudApp.Data;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services
{
public interface IDrillingProgramService
{
Task<FileInfoDto> GetAsync(int idWell, CancellationToken token = default);
}
}

View File

@ -10,20 +10,20 @@ namespace AsbCloudApp.Services
public interface IFileService public interface IFileService
{ {
string RootPath { get; } string RootPath { get; }
IDictionary<string, int> SaveFileInfos(int idWell, int idUser,
IEnumerable<FileInfoDto> filesInfo);
Task SaveFile(int idWell, int idCategory, int fileId, Task<FileInfoDto> SaveAsync(int idWell, int idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token = default);
string fileExtension, Stream fileStream);
Task<PaginationContainer<FileInfoDto>> GetFilesInfoAsync(int idWell, Task<PaginationContainer<FileInfoDto>> GetInfosAsync(int idWell,
int idCategory, IEnumerable<int> companies, DateTime begin, DateTime end, int idCategory, IEnumerable<int> companies, DateTime begin, DateTime end,
int skip, int take, CancellationToken token = default); int skip, int take, CancellationToken token = default);
Task<FileInfoDto> GetFileInfoAsync(int fileId, Task<FileInfoDto> GetInfoAsync(int fileId,
CancellationToken token); CancellationToken token);
Task<int> DeleteFileAsync(int idFile, Task<int> MarkAsDeletedAsync(int idFile,
CancellationToken token = default); CancellationToken token = default);
Task<IEnumerable<FileInfoDto>> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token = default);
Task<int> DeletedAsync(int id, CancellationToken token);
string GetFileName(FileInfoDto fileInfo);
} }
} }

View File

@ -13,5 +13,6 @@ namespace AsbCloudApp.Services
Task<IEnumerable<WellOperationDto>> GetOperationsAsync(int idWell, CancellationToken token); Task<IEnumerable<WellOperationDto>> GetOperationsAsync(int idWell, CancellationToken token);
Task<string> GetWellCaptionByIdAsync(int idWell, CancellationToken token); Task<string> GetWellCaptionByIdAsync(int idWell, CancellationToken token);
Task<IEnumerable<CompanyDto>> GetCompaniesAsync(int idWell, CancellationToken token); Task<IEnumerable<CompanyDto>> GetCompaniesAsync(int idWell, CancellationToken token);
Task<WellDto> GetAsync(int idWell, CancellationToken token);
} }
} }

View File

@ -285,7 +285,8 @@ namespace AsbCloudDb.Model
new FileCategory {Id = 9, Name = "Последний замер бурового раствора ФАКТ", ShortName = "fluidFactLastData"}, new FileCategory {Id = 9, Name = "Последний замер бурового раствора ФАКТ", ShortName = "fluidFactLastData"},
new FileCategory {Id = 10, Name = "Последние данные Шламограммы", ShortName = "mudLastData"}, new FileCategory {Id = 10, Name = "Последние данные Шламограммы", ShortName = "mudLastData"},
new FileCategory {Id = 11, Name = "Последние данные ННБ", ShortName = "nnbLastData"}, new FileCategory {Id = 11, Name = "Последние данные ННБ", ShortName = "nnbLastData"},
new FileCategory {Id = 12, Name = "Рапорт", ShortName = "report"} new FileCategory {Id = 12, Name = "Рапорт", ShortName = "report"},
new FileCategory {Id = 13, Name = "Программа бурения", ShortName = "ПБ"},
}); });
}); });

View File

@ -12,6 +12,7 @@
<PackageReference Include="itext7" Version="7.1.15" /> <PackageReference Include="itext7" Version="7.1.15" />
<PackageReference Include="Mapster" Version="7.2.0" /> <PackageReference Include="Mapster" Version="7.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="NPOI" Version="2.5.4" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.10.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.10.0" />
</ItemGroup> </ItemGroup>

View File

@ -39,6 +39,7 @@ namespace AsbCloudInfrastructure
services.AddTransient<IWellOperationService, WellOperationService>(); services.AddTransient<IWellOperationService, WellOperationService>();
services.AddTransient<IWellOperationsStatService, WellOperationsStatService>(); services.AddTransient<IWellOperationsStatService, WellOperationsStatService>();
services.AddTransient<IMeasureService, MeasureService>(); services.AddTransient<IMeasureService, MeasureService>();
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
return services; return services;
} }

View File

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
namespace AsbCloudInfrastructure.Services
{
public class DrillingProgramService : IDrillingProgramService
{
private readonly IFileService fileService;
private readonly WellService wellService;
private const int idFileCategoryPlan = 13;
public DrillingProgramService(IFileService fileService, WellService wellService)
{
this.fileService = fileService;
this.wellService = wellService;
}
public async Task<FileInfoDto> GetAsync(int idWell, CancellationToken token = default)
{
var filesInfos = await fileService.GetInfosByCategoryAsync(idWell, idFileCategoryPlan, token)
.ConfigureAwait(false);
var well = await wellService.GetAsync(idWell, token)
.ConfigureAwait(false);
var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx";
var matchFile = filesInfos.FirstOrDefault(f=>f.Name == resultFileName);
if (matchFile is not null) {
if (filesInfos.All(f => f.UploadDate <= matchFile.UploadDate))
return matchFile;
else
await fileService.DeletedAsync(matchFile.Id, token);
}
var fileNames = filesInfos
.Where(f => f.Name != resultFileName)
.Select(f => fileService.GetFileName(f));
var stream = new MemoryStream(1024 * 1024);
UniteExcelFiles(fileNames, stream);
stream.Seek(0, SeekOrigin.Begin);
return await fileService.SaveAsync(idWell, 0, idFileCategoryPlan, resultFileName, stream, token)
.ConfigureAwait(false);
}
private static void UniteExcelFiles(IEnumerable<string> excelFilesNames, Stream stream)
{
IWorkbook product = new XSSFWorkbook();
foreach (var excelFileName in excelFilesNames)
{
IWorkbook book = new XSSFWorkbook(new FileStream(excelFileName, FileMode.Open));
for (int i = 0; i < book.NumberOfSheets; i++)
{
ISheet sheet = book.GetSheetAt(i);
try
{
sheet.CopyTo(product, sheet.SheetName, true, true);
}
catch
{
//what can't be done - can't be done. ignore it.
}
}
}
product.Write(stream);
}
}
}

View File

@ -23,35 +23,25 @@ namespace AsbCloudInfrastructure.Services
this.db = db; this.db = db;
} }
public IDictionary<string, int> SaveFileInfos(int idWell, int idUser, public async Task<FileInfoDto> SaveAsync(int idWell, int idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token = default)
IEnumerable<FileInfoDto> filesInfo)
{ {
var fileIdsToNames = new Dictionary<string, int>(); //save info to db
var fileInfo = new AsbCloudDb.Model.FileInfo()
foreach (var fileInfo in filesInfo)
{ {
var file = new AsbCloudDb.Model.FileInfo()
{
Name = fileInfo.Name,
IdWell = idWell, IdWell = idWell,
IdCategory = fileInfo.IdCategory, IdAuthor = idUser,
UploadDate = fileInfo.UploadDate, IdCategory = idCategory,
IdAuthor = idUser Name = Path.GetFileName(fileFullName),
UploadDate = DateTime.Now,
IsDeleted = false,
}; };
db.Files.Add(file); var entry = db.Files.Add(fileInfo);
db.SaveChanges(); db.SaveChanges();
fileIdsToNames.Add(file.Name, file.Id); var fileId = entry.Entity.Id;
} //save stream to disk
return fileIdsToNames;
}
public async Task SaveFile(int idWell, int idCategory, int fileId,
string fileExtension, Stream fileStream)
{
var relativePath = Path.Combine(RootPath, $"{idWell}", var relativePath = Path.Combine(RootPath, $"{idWell}",
$"{idCategory}", $"{fileId}" + $"{fileExtension}"); $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}");
Directory.CreateDirectory(Path.GetDirectoryName(relativePath)); Directory.CreateDirectory(Path.GetDirectoryName(relativePath));
@ -59,9 +49,30 @@ namespace AsbCloudInfrastructure.Services
{ {
await fileStream.CopyToAsync(newfileStream); await fileStream.CopyToAsync(newfileStream);
} }
var dto = entry.Entity.Adapt<FileInfoDto>();
return dto;
} }
public async Task<PaginationContainer<FileInfoDto>> GetFilesInfoAsync(int idWell, public async Task<IEnumerable<FileInfoDto>> GetInfosByCategoryAsync(int idWell,
int idCategory, CancellationToken token = default)
{
var entities = await db.Files
.Include(f => f.Author)
.Where(e => e.IdWell == idWell && e.IdCategory == idCategory)
.AsNoTracking()
.ToListAsync(token)
.ConfigureAwait(false);
var dtos = entities.Adapt<FileInfoDto, AsbCloudDb.Model.FileInfo>((d,s) => {
d.AuthorName = s.Author?.Name;
d.CompanyId = s.Author?.IdCompany ?? 0;
});
return dtos;
}
public async Task<PaginationContainer<FileInfoDto>> GetInfosAsync(int idWell,
int idCategory, IEnumerable<int> companies = default, DateTime begin = default, int idCategory, IEnumerable<int> companies = default, DateTime begin = default,
DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default)
{ {
@ -115,7 +126,7 @@ namespace AsbCloudInfrastructure.Services
return result; return result;
} }
public async Task<FileInfoDto> GetFileInfoAsync(int fileId, public async Task<FileInfoDto> GetInfoAsync(int fileId,
CancellationToken token = default) CancellationToken token = default)
{ {
var entity = await db.Files var entity = await db.Files
@ -132,17 +143,42 @@ namespace AsbCloudInfrastructure.Services
return dto; return dto;
} }
public async Task<int> DeleteFileAsync(int idFile, public async Task<int> MarkAsDeletedAsync(int idFile,
CancellationToken token = default) CancellationToken token = default)
{ {
var fileInfo = db.Files.FirstOrDefault(f => f.Id == idFile); var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false);
if (fileInfo is null) if (fileInfo is null)
return 0; return 0;
fileInfo.IsDeleted = true; fileInfo.IsDeleted = true;
return await db.SaveChangesAsync(token); return await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public async Task<int> DeletedAsync(int idFile, CancellationToken token)
{
var fileInfo = await db.Files
.FirstOrDefaultAsync(f => f.Id == idFile, token)
.ConfigureAwait(false);
if (fileInfo is null)
return 0;
var fileName = GetFileName(fileInfo.Adapt<FileInfoDto>());
if (File.Exists(fileName))
File.Delete(fileName);
db.Files.Remove(fileInfo);
return await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public string GetFileName(FileInfoDto fileInfo)
{
var fileName = Path.Combine(fileInfo.Id.ToString(), Path.GetExtension(fileInfo.Name));
fileName = Path.Combine(RootPath, fileInfo.IdWell.ToString(), fileInfo.IdCategory.ToString(), fileName);
fileName = Path.GetFullPath(fileName);
return fileName;
} }
} }
} }

View File

@ -77,6 +77,19 @@ namespace AsbCloudInfrastructure.Services
return wellDto; return wellDto;
} }
public async Task<WellDto> GetAsync(int idWell, CancellationToken token)
{
var entity = await db.Wells
.Include(w=>w.Cluster)
.ThenInclude(c=>c.Deposit)
.FirstOrDefaultAsync(w => w.Id == idWell, token)
.ConfigureAwait(false);
var dto = entity.Adapt<WellDto>();
dto.Cluster = entity.Cluster?.Caption;
dto.Deposit = entity.Cluster?.Deposit?.Caption;
return dto;
}
public async Task<string> GetWellCaptionByIdAsync(int idWell, CancellationToken token) public async Task<string> GetWellCaptionByIdAsync(int idWell, CancellationToken token)
{ {
var entity = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false); var entity = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false);

View File

@ -0,0 +1,34 @@
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers
{
[Route("api/well/{idWell}/files")]
[ApiController]
[Authorize]
public class DrillingProgramController : ControllerBase
{
private readonly IDrillingProgramService drillingProgramService;
private readonly IFileService fileService;
public DrillingProgramController(IDrillingProgramService drillingProgramService, IFileService fileService)
{
this.drillingProgramService = drillingProgramService;
this.fileService = fileService;
}
[HttpGet]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetAsync(int idWell, CancellationToken token = default)
{
var fileInfo = await drillingProgramService.GetAsync(idWell, token)
.ConfigureAwait(false);
var relativePath = fileService.GetFileName(fileInfo);
return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name);
}
}
}

View File

@ -56,20 +56,11 @@ namespace AsbCloudWebApi.Controllers
UploadDate = DateTime.Now UploadDate = DateTime.Now
}); });
var fileNamesAndIds = fileService.SaveFileInfos(idWell, (int)idUser,
fileInfoCollection);
foreach (var file in files) foreach (var file in files)
{ {
var fileExtension = Path.GetExtension(file.FileName);
var fileId = fileNamesAndIds[file.FileName];
var fileStream = file.OpenReadStream(); var fileStream = file.OpenReadStream();
await fileService.SaveAsync(idWell, idUser??0, idCategory, file.FileName,
await fileService.SaveFile(idWell, idCategory, fileId, fileStream);
fileExtension, fileStream);
} }
return Ok(); return Ok();
@ -100,7 +91,7 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var filesInfo = await fileService.GetFilesInfoAsync(idWell, idCategory, var filesInfo = await fileService.GetInfosAsync(idWell, idCategory,
companies, begin, end, skip, take, token).ConfigureAwait(false); companies, begin, end, skip, take, token).ConfigureAwait(false);
if (filesInfo is null || !filesInfo.Items.Any()) if (filesInfo is null || !filesInfo.Items.Any())
@ -133,14 +124,13 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var fileInfo = await fileService.GetFileInfoAsync(fileId, token); var fileInfo = await fileService.GetInfoAsync(fileId, token);
if (fileInfo is null) if (fileInfo is null)
throw new FileNotFoundException(); throw new FileNotFoundException();
// TODO: словарь content typoв // TODO: словарь content typoв
var relativePath = Path.Combine(fileService.RootPath, $"{idWell}", $"{fileInfo.IdCategory}", var relativePath = fileService.GetFileName(fileInfo);
$"{fileInfo.Id}" + Path.GetExtension($"{fileInfo.Name}"));
return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name);
} }
catch (FileNotFoundException ex) catch (FileNotFoundException ex)
@ -167,7 +157,7 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var result = await fileService.DeleteFileAsync(idFile, token); var result = await fileService.MarkAsDeletedAsync(idFile, token);
return Ok(result); return Ok(result);
} }

View File

@ -7,6 +7,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" /> <PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="DocumentFormat.OpenXml" Version="2.13.1" />
<PackageReference Include="Mapster" Version="7.2.0" /> <PackageReference Include="Mapster" Version="7.2.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />

View File

@ -2,6 +2,9 @@
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.Cache;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
//using AsbSaubReport; //using AsbSaubReport;
//using AutoMapper; //using AutoMapper;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -15,29 +18,38 @@ namespace ConsoleApp1
static void Main(/*string[] args*/) static void Main(/*string[] args*/)
{ {
var options = new DbContextOptionsBuilder<AsbCloudDbContext>() //var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") // .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options; // .Options;
var context = new AsbCloudDbContext(options); //var context = new AsbCloudDbContext(options);
var mservice = new MeasureService(context, new CacheDb()); var fileNames = new string[] { @"d:\temp\1\book1.xlsx", @"d:\temp\1\book2.xlsx" };
var r = mservice.GetAllLastAsync(1, default).Result;
//var idWell = 1; using var spreadsheetDocument = SpreadsheetDocument.Create(@"d:\temp\1\b.xlsx", SpreadsheetDocumentType.Workbook);
//var dataSource = new ReportDataSourcePgCloud(context, idWell); // Add a WorkbookPart and Workbook objects.
//var generator = new PdfGenerator(dataSource) WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
//{ workbookpart.Workbook = new Workbook();
// ReportDirectory = $"{idWell}",
// Begin = DateTime.Now.AddYears(-30),
// End = DateTime.Now.AddYears(30),
// Step = TimeSpan.FromDays(1),
// WithCharts = true,
// WithEvents = true
//};
//generator.OnProgress += Generator_OnProgress; // Add a WorksheetPart to the WorkbookPart.
//var s = generator.GetPagesCount(); WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
//var fileName = generator.Make(); worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheetNameISHere!"
};
sheets.Append(sheet);
spreadsheetDocument.Save();
spreadsheetDocument.Close();
Console.WriteLine("Done. Press any key to quit."); Console.WriteLine("Done. Press any key to quit.");
Console.ReadKey(); Console.ReadKey();