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

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

View File

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

View File

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

View File

@ -2,49 +2,21 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Services.Parser; using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.ProcessMapPlanTemplates;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser; namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanDrillingDto> public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanDrillingDto>
{ {
private readonly IEnumerable<WellSectionTypeDto> sections;
public ProcessMapPlanDrillingParser(IWellOperationRepository wellOperationRepository) public ProcessMapPlanDrillingParser(IWellOperationRepository wellOperationRepository)
: base(wellOperationRepository)
{ {
sections = wellOperationRepository.GetSectionTypes();
} }
protected override string SheetName => "План";
protected override string TemplateFileName => "ProcessMapPlanDrillingTemplate.xlsx";
private const int ColumnSection = 1; protected override ITemplateParameters TemplateParameters => new ProcessMapPlanDrillingTemplate();
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 ProcessMapPlanDrillingDto BuildDto(IDictionary<string, object?> row, int rowNumber) protected override ProcessMapPlanDrillingDto BuildDto(IDictionary<string, object?> row, int rowNumber)
{ {
@ -55,7 +27,10 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanD
if (section is null) 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); throw new FileFormatException(message);
} }
@ -64,7 +39,10 @@ public class ProcessMapPlanDrillingParser : ProcessMapPlanParser<ProcessMapPlanD
if (idMode is null) 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); throw new FileFormatException(message);
} }

View File

@ -1,16 +1,23 @@
using System.Collections.Generic;
using System.IO; using System.IO;
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests.ParserOptions; using AsbCloudApp.Requests.ParserOptions;
using AsbCloudInfrastructure.Services.Parser; using AsbCloudInfrastructure.Services.ExcelServices;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser; namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public abstract class ProcessMapPlanParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest> public abstract class ProcessMapPlanParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest>
where TDto : ProcessMapPlanBaseDto 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) public override ParserResultDto<TDto> Parse(Stream file, WellRelatedParserRequest options)
{ {
var result = base.Parse(file, options); var result = base.Parse(file, options);

View File

@ -2,42 +2,21 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudInfrastructure.Services.Parser; using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.ExcelServices.Templates.ProcessMapPlanTemplates;
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser; namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamDto> public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamDto>
{ {
private readonly IEnumerable<WellSectionTypeDto> sections;
public ProcessMapPlanReamParser(IWellOperationRepository wellOperationRepository) 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 ITemplateParameters TemplateParameters => new ProcessMapPlanReamTemplate();
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 ProcessMapPlanReamDto BuildDto(IDictionary<string, object?> row, int rowNumber) protected override ProcessMapPlanReamDto BuildDto(IDictionary<string, object?> row, int rowNumber)
{ {
@ -48,7 +27,9 @@ public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamD
if (section is null) 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); throw new FileFormatException(message);
} }

View File

@ -1,22 +1,10 @@
using System.Collections.Generic; using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Data.Trajectory; using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.Parser; using AsbCloudInfrastructure.Services.ExcelServices.Templates.TrajectoryTemplates;
namespace AsbCloudInfrastructure.Services.Trajectory.Parser; namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
public class TrajectoryFactManualParser : TrajectoryParser<TrajectoryGeoFactDto> public class TrajectoryFactManualParser : TrajectoryParser<TrajectoryGeoFactDto>
{ {
protected override string SheetName => "Фактическая траектория"; protected override ITemplateParameters TemplateParameters => new TrajectoryFactManualTemplate();
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)) }
};
} }

View File

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

View File

@ -1,23 +1,10 @@
using System.Collections.Generic; using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Data.Trajectory; using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using AsbCloudInfrastructure.Services.Parser; using AsbCloudInfrastructure.Services.ExcelServices.Templates.TrajectoryTemplates;
namespace AsbCloudInfrastructure.Services.Trajectory.Parser; namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
public class TrajectoryPlanParser : TrajectoryParser<TrajectoryGeoPlanDto> public class TrajectoryPlanParser : TrajectoryParser<TrajectoryGeoPlanDto>
{ {
protected override string SheetName => "Плановая траектория"; protected override ITemplateParameters TemplateParameters => new TrajectoryPlanTemplate();
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)) }
};
} }

View File

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