Рефакторинг парсеров

This commit is contained in:
Степанов Дмитрий 2024-03-14 08:03:57 +03:00
parent af2d180d99
commit a08c9c0d8b
10 changed files with 54 additions and 125 deletions

View File

@ -9,7 +9,7 @@ namespace AsbCloudApp.Services;
/// </summary>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TOptions"></typeparam>
public interface IParserService<TDto, in TOptions> : IParserService
public interface IParserService<TDto, in TOptions>
where TDto : class, IId
where TOptions : IParserOptionsRequest
{
@ -26,11 +26,4 @@ public interface IParserService<TDto, in TOptions> : IParserService
/// </summary>
/// <returns></returns>
Stream GetTemplateFile();
}
/// <summary>
/// Сервис парсинга(интерфейс маркер)
/// </summary>
public interface IParserService
{
}

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO;
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.Parser;
namespace AsbCloudInfrastructure.Services.ExcelServices;
public class Cell
{

View File

@ -7,39 +7,34 @@ using System.Reflection;
using AsbCloudApp.Data;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using ClosedXML.Excel;
using Mapster;
namespace AsbCloudInfrastructure.Services.Parser;
namespace AsbCloudInfrastructure.Services.ExcelServices;
public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto, TOptions>
where TDto : class, IValidatableObject, IId
where TOptions : IParserOptionsRequest
{
protected abstract string SheetName { get; }
protected abstract ITemplateParameters TemplateParameters { get; }
protected virtual int HeaderRowsCount => 0;
protected abstract string TemplateFileName { get; }
protected abstract IDictionary<string, Cell> Cells { get; }
public virtual ParserResultDto<TDto> Parse(Stream file, TOptions options)
{
using var workbook = new XLWorkbook(file);
var sheet = workbook.GetWorksheet(SheetName);
var sheet = workbook.GetWorksheet(TemplateParameters.SheetName);
var dtos = ParseExcelSheet(sheet);
return dtos;
}
public virtual Stream GetTemplateFile() =>
Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateFileName)
?? throw new ArgumentNullException($"Файл '{TemplateFileName}' не найден");
Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateParameters.FileName)
?? throw new ArgumentNullException($"Файл '{TemplateParameters.FileName}' не найден");
protected virtual IDictionary<string, object?> ParseRow(IXLRow xlRow)
{
var cells = Cells.ToDictionary(x => x.Key, x =>
var cells = TemplateParameters.Cells.ToDictionary(x => x.Key, x =>
{
var columnNumber = x.Value.ColumnNumber;
var xlCell = xlRow.Cell(columnNumber);
@ -72,7 +67,7 @@ public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto,
return validDto;
}
var columnsDict = Cells.ToDictionary(x => x.Key, x => x.Value.ColumnNumber);
var columnsDict = TemplateParameters.Cells.ToDictionary(x => x.Key, x => x.Value.ColumnNumber);
var invalidDto = new ValidationResultDto<TDto>
{
@ -84,7 +79,10 @@ public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto,
{
var columnNumber = columnsDict[m];
var errorMessage = v.ErrorMessage;
var warningMessage = string.Format(XLExtentions.ProblemDetailsTemplate, SheetName, rowNumber, columnNumber,
var warningMessage = string.Format(XLExtentions.ProblemDetailsTemplate,
TemplateParameters.SheetName,
rowNumber,
columnNumber,
errorMessage);
var warning = new ValidationResult(warningMessage, new[] { m });
return warning;
@ -96,7 +94,7 @@ public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto,
protected virtual ParserResultDto<TDto> ParseExcelSheet(IXLWorksheet sheet)
{
var count = sheet.RowsUsed().Count() - HeaderRowsCount;
var count = sheet.RowsUsed().Count() - TemplateParameters.HeaderRowsCount;
if (count <= 0)
return new ParserResultDto<TDto>();
@ -105,7 +103,7 @@ public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto,
for (var i = 0; i < count; i++)
{
var xlRow = sheet.Row(1 + i + HeaderRowsCount);
var xlRow = sheet.Row(1 + i + TemplateParameters.HeaderRowsCount);
var rowNumber = xlRow.RowNumber();
try

View File

@ -2,49 +2,21 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.ProcessMapPlanTemplates;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanDrillingDto>
{
private readonly IEnumerable<WellSectionTypeDto> sections;
public ProcessMapPlanDrillingParser(IWellOperationRepository wellOperationRepository)
: base(wellOperationRepository)
{
sections = wellOperationRepository.GetSectionTypes();
}
protected override string SheetName => "План";
protected override string TemplateFileName => "ProcessMapPlanDrillingTemplate.xlsx";
private const int ColumnSection = 1;
private const int ColumnMode = 2;
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
{
{ nameof(ProcessMapPlanDrillingDto.Section), new Cell(ColumnSection, typeof(string)) },
{ nameof(ProcessMapPlanDrillingDto.Mode), new Cell(ColumnMode, typeof(string)) },
{ nameof(ProcessMapPlanDrillingDto.DepthStart), new Cell(3, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.DepthEnd), new Cell(4, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.DeltaPressurePlan), new Cell(5, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.DeltaPressureLimitMax), new Cell(6, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.AxialLoadPlan), new Cell(7, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.AxialLoadLimitMax), new Cell(8, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.TopDriveTorquePlan), new Cell(9, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.TopDriveTorqueLimitMax), new Cell(10, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.TopDriveSpeedPlan), new Cell(11, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.TopDriveSpeedLimitMax), new Cell(12, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.FlowPlan), new Cell(13, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.FlowLimitMax), new Cell(14, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.RopPlan), new Cell(15, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.UsageSaub), new Cell(16, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.UsageSpin), new Cell(17, typeof(double)) },
{ nameof(ProcessMapPlanDrillingDto.Comment), new Cell(18, typeof(string)) }
};
protected override ITemplateParameters TemplateParameters => new ProcessMapPlanDrillingTemplate();
protected override ProcessMapPlanDrillingDto BuildDto(IDictionary<string, object?> row, int rowNumber)
{
@ -55,7 +27,10 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanD
if (section is null)
{
var message = string.Format(XLExtentions.ProblemDetailsTemplate, SheetName, rowNumber, ColumnSection,
var message = string.Format(XLExtentions.ProblemDetailsTemplate,
TemplateParameters.SheetName,
rowNumber,
TemplateParameters.Cells[nameof(ProcessMapPlanDrillingDto.Section)],
"Указана некорректная секция");
throw new FileFormatException(message);
}
@ -64,7 +39,10 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanD
if (idMode is null)
{
var message = string.Format(XLExtentions.ProblemDetailsTemplate, SheetName, rowNumber, ColumnSection,
var message = string.Format(XLExtentions.ProblemDetailsTemplate,
TemplateParameters.SheetName,
rowNumber,
TemplateParameters.Cells[nameof(ProcessMapPlanDrillingDto.Mode)],
"Указан некорректный режим бурения");
throw new FileFormatException(message);
}

View File

@ -1,16 +1,23 @@
using System.Collections.Generic;
using System.IO;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.ExcelServices;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public abstract class ProcessMapPlanParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest>
where TDto : ProcessMapPlanBaseDto
{
protected override int HeaderRowsCount => 2;
protected readonly IEnumerable<WellSectionTypeDto> sections;
protected ProcessMapPlanParser(IWellOperationRepository wellOperationRepository)
{
sections = wellOperationRepository.GetSectionTypes();
}
public override ParserResultDto<TDto> Parse(Stream file, WellRelatedParserRequest options)
{
var result = base.Parse(file, options);

View File

@ -2,42 +2,21 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.ProcessMapPlanTemplates;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamDto>
{
private readonly IEnumerable<WellSectionTypeDto> sections;
public ProcessMapPlanReamParser(IWellOperationRepository wellOperationRepository)
: base(wellOperationRepository)
{
sections = wellOperationRepository.GetSectionTypes();
}
protected override string SheetName => "План";
protected override string TemplateFileName => "ProcessMapPlanReamTemplate.xlsx";
private const int ColumnSection = 1;
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
{
{ nameof(ProcessMapPlanReamDto.Section), new Cell(ColumnSection, typeof(string)) },
{ nameof(ProcessMapPlanReamDto.DepthStart), new Cell(2, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.DepthEnd), new Cell(3, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.Repeats), new Cell(4, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SpinUpward), new Cell(5, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SpinUpward), new Cell(6, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SpeedDownward), new Cell(7, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SpeedUpward), new Cell(8, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SetpointDrag), new Cell(9, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.SetpointTight), new Cell(10, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.Pressure), new Cell(11, typeof(double)) },
{ nameof(ProcessMapPlanReamDto.Torque), new Cell(12, typeof(double)) },
};
protected override ITemplateParameters TemplateParameters => new ProcessMapPlanReamTemplate();
protected override ProcessMapPlanReamDto BuildDto(IDictionary<string, object?> row, int rowNumber)
{
@ -48,7 +27,9 @@ public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamD
if (section is null)
{
var message = string.Format(XLExtentions.ProblemDetailsTemplate, SheetName, rowNumber, ColumnSection,
var message = string.Format(XLExtentions.ProblemDetailsTemplate,
TemplateParameters.SheetName, rowNumber,
TemplateParameters.Cells[nameof(ProcessMapPlanReamDto.Section)],
"Указана некорректная секция");
throw new FileFormatException(message);
}

View File

@ -1,22 +1,10 @@
using System.Collections.Generic;
using AsbCloudApp.Data.Trajectory;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudApp.Data.Trajectory;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.TrajectoryTemplates;
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
public class TrajectoryFactManualParser : TrajectoryParser<TrajectoryGeoFactDto>
{
protected override string SheetName => "Фактическая траектория";
protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx";
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
{
{ nameof(TrajectoryGeoFactDto.WellboreDepth), new Cell(1, typeof(double)) },
{ nameof(TrajectoryGeoFactDto.ZenithAngle), new Cell(2, typeof(double)) },
{ nameof(TrajectoryGeoFactDto.AzimuthGeo), new Cell(3, typeof(double)) },
{ nameof(TrajectoryGeoFactDto.AzimuthMagnetic), new Cell(4, typeof(double)) },
{ nameof(TrajectoryGeoFactDto.VerticalDepth), new Cell(5, typeof(double)) },
{ nameof(TrajectoryGeoFactDto.Comment), new Cell(6, typeof(string)) }
};
protected override ITemplateParameters TemplateParameters => new TrajectoryFactManualTemplate();
}

View File

@ -2,15 +2,13 @@ using System.IO;
using AsbCloudApp.Data;
using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.ExcelServices;
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
public abstract class TrajectoryParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest>
where TDto : TrajectoryGeoDto
{
protected override int HeaderRowsCount => 2;
public override ParserResultDto<TDto> Parse(Stream file, WellRelatedParserRequest options)
{
var result = base.Parse(file, options);

View File

@ -1,23 +1,10 @@
using System.Collections.Generic;
using AsbCloudApp.Data.Trajectory;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudApp.Data.Trajectory;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.TrajectoryTemplates;
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
public class TrajectoryPlanParser : TrajectoryParser<TrajectoryGeoPlanDto>
{
protected override string SheetName => "Плановая траектория";
protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx";
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
{
{ nameof(TrajectoryGeoPlanDto.WellboreDepth), new Cell(1, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.ZenithAngle), new Cell(2, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.AzimuthGeo), new Cell(3, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.AzimuthMagnetic), new Cell(4, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.VerticalDepth), new Cell(5, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.Radius), new Cell(6, typeof(double)) },
{ nameof(TrajectoryGeoPlanDto.Comment), new Cell(7, typeof(string)) }
};
protected override ITemplateParameters TemplateParameters => new TrajectoryPlanTemplate();
}

View File

@ -1,7 +1,6 @@
using System.Linq;
using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.Trajectory.Parser;
using Xunit;