Расширение функциональности

1. Расширены репозитории: траектории, расписания
2. Расширил DTO, сервис РТК отчёт
3. Поправлен класс с методами расширения для формирования excel. В дальнейшем требуется удалить из него все неиспользуемые методы расширения
This commit is contained in:
Степанов Дмитрий 2023-11-03 18:55:49 +05:00
parent 6dbed6c457
commit 6b0db1adbc
9 changed files with 157 additions and 83 deletions

View File

@ -12,6 +12,14 @@ public class ProcessMapReportWellDrillingDto
/// </summary> /// </summary>
public int IdWell { get; set; } public int IdWell { get; set; }
/// <summary>
/// Режим работы
/// 0 - ручной
/// 1 - ротор
/// 2 - слайд
/// </summary>
public int? IdMode { get; set; }
/// <summary> /// <summary>
/// Id секции скважины /// Id секции скважины
/// </summary> /// </summary>
@ -91,8 +99,13 @@ public class ProcessMapReportWellDrillingDto
/// </summary> /// </summary>
public double UsageFact { get; set; } public double UsageFact { get; set; }
/// <summary>
/// Плановая механическая скорость, м/ч
/// </summary>
public double? RopPlan { get; set; }
/// <summary> /// <summary>
/// Фактическая механическая скорость, м/ч /// Фактическая механическая скорость, м/ч
/// </summary> /// </summary>
public double? Rop { get; set; } public double? RopFact { get; set; }
} }

View File

@ -1,8 +1,8 @@
using AsbCloudApp.Data; using System.Collections.Generic;
using AsbCloudApp.Data.WITS;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Requests;
namespace AsbCloudApp.Repositories namespace AsbCloudApp.Repositories
{ {
@ -12,5 +12,12 @@ namespace AsbCloudApp.Repositories
/// <returns></returns> /// <returns></returns>
public interface ITrajectoryFactRepository : ITrajectoryRepository<TrajectoryGeoFactDto> public interface ITrajectoryFactRepository : ITrajectoryRepository<TrajectoryGeoFactDto>
{ {
/// <summary>
/// Получить траектории скважины
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token);
} }
} }

View File

@ -0,0 +1,24 @@
using System;
namespace AsbCloudApp.Requests;
/// <summary>
/// Запрос для получения фактической траектории
/// </summary>
public class TrajectoryGeoFactRequest : RequestBase
{
/// <summary>
/// Идентификатор скважины
/// </summary>
public int IdWell { get; set; }
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTime? GeDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTime? LtDate { get; set; }
}

View File

@ -1,5 +1,6 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using System; using System;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,6 +11,15 @@ namespace AsbCloudApp.Services
/// </summary> /// </summary>
public interface IScheduleRepository : IRepositoryWellRelated<ScheduleDto> public interface IScheduleRepository : IRepositoryWellRelated<ScheduleDto>
{ {
/// <summary>
/// Получить расписание смен
/// </summary>
/// <param name="idWell"></param>
/// <param name="workTime"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTime workTime, CancellationToken token);
/// <summary> /// <summary>
/// получить бурильщика по idWell и времени /// получить бурильщика по idWell и времени
/// </summary> /// </summary>

View File

@ -1,17 +1,19 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Mapster;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
public class ScheduleRepository : CrudWellRelatedRepositoryBase<ScheduleDto, Schedule>, IScheduleRepository public class ScheduleRepository : CrudWellRelatedRepositoryBase<ScheduleDto, Schedule>,
IScheduleRepository
{ {
private readonly IWellService wellService; private readonly IWellService wellService;
@ -21,21 +23,26 @@ namespace AsbCloudInfrastructure.Repository
this.wellService = wellService; this.wellService = wellService;
} }
public async Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTime workTime, CancellationToken token)
{
var entities = await BuildQuery(idWell, workTime)
.AsNoTracking()
.ToArrayAsync(token);
return entities.Select(Convert);
}
public async Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token) public async Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
{ {
var hoursOffset = wellService.GetTimezone(idWell).Hours; var entities = await BuildQuery(idWell, workTime)
var date = workTime.ToUtcDateTimeOffset(hoursOffset); .AsNoTracking()
.ToArrayAsync(token);
var entities = await GetQuery()
.Where(s => s.IdWell == idWell
&& s.DrillStart <= date
&& s.DrillEnd >= date)
.ToListAsync(token);
if (!entities.Any()) if (!entities.Any())
return null; return null;
var remoteDate = date.ToRemoteDateTime(hoursOffset); var hoursOffset = wellService.GetTimezone(idWell).Hours;
var remoteDate = workTime.ToUtcDateTimeOffset(hoursOffset).ToRemoteDateTime(hoursOffset);
var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second); var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second);
var entity = entities.FirstOrDefault(s => var entity = entities.FirstOrDefault(s =>
@ -46,6 +53,15 @@ namespace AsbCloudInfrastructure.Repository
return entity?.Driller.Adapt<DrillerDto>(); return entity?.Driller.Adapt<DrillerDto>();
} }
private IQueryable<Schedule> BuildQuery(int idWell, DateTime workTime)
{
var hoursOffset = wellService.GetTimezone(idWell).Hours;
return GetQuery().Where(s => s.IdWell == idWell
&& s.DrillStart <= workTime.ToUtcDateTimeOffset(hoursOffset)
&& s.DrillEnd >= workTime.ToUtcDateTimeOffset(hoursOffset));
}
protected override Schedule Convert(ScheduleDto dto) protected override Schedule Convert(ScheduleDto dto)
{ {
var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours; var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours;

View File

@ -1,53 +1,65 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb.Model;
using AsbCloudDb.Model.WITS;
using Microsoft.EntityFrameworkCore;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository;
public class TrajectoryFactRepository : ITrajectoryFactRepository
{ {
internal class TrajectoryFactRepository : ITrajectoryFactRepository private readonly IAsbCloudDbContext dbContext;
public TrajectoryFactRepository(IAsbCloudDbContext dbContext)
{ {
private readonly IAsbCloudDbContext db; this.dbContext = dbContext;
private readonly IWellService wellService;
public TrajectoryFactRepository(IAsbCloudDbContext db, IWellService wellService)
{
this.db = db;
this.wellService = wellService;
} }
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token) public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token) =>
(await BuildQuery(request)
.Where(coord => coord.Deptsvym.HasValue &&
coord.Svyinc.HasValue &&
coord.Svyazc.HasValue)
.AsNoTracking()
.ToArrayAsync(token))
.Select(r => new TrajectoryGeoFactDto
{ {
var well = await wellService.GetOrDefaultAsync(idWell, IdWell = request.IdWell,
token); AzimuthMagnetic = r.Svymtf,
VerticalDepth = r.Deptsvyv,
WellboreDepth = r.Deptsvym!.Value,
ZenithAngle = r.Svyinc!.Value,
AzimuthGeo = r.Svyazc!.Value
});
public Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token) =>
GetAsync(new TrajectoryGeoFactRequest
{
IdWell = idWell
}, token);
private IQueryable<Record7> BuildQuery(TrajectoryGeoFactRequest request)
{
var well = dbContext.Wells.SingleOrDefault(w => w.Id == request.IdWell);
if (well is null) if (well is null)
return Enumerable.Empty<TrajectoryGeoFactDto>(); throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell));
var entities = await db.Record7 var query = dbContext.Record7.Where(r => r.IdTelemetry == well.IdTelemetry)
.AsNoTracking() .Where(x => x.IdTelemetry == well.IdTelemetry);
.Where(x => x.IdTelemetry == well.IdTelemetry)
.Where(coord => coord.Deptsvym != null && coord.Svyinc != null && coord.Svyazc != null)
.OrderBy(e => e.Deptsvym)
.ToArrayAsync(token);
var result = entities if (request.GeDate.HasValue)
.Select(coord => new TrajectoryGeoFactDto query = query.Where(r => r.DateTime >= request.GeDate.Value);
{
IdWell = idWell,
AzimuthMagnetic = coord.Svymtf,
VerticalDepth = coord.Deptsvyv,
WellboreDepth = coord.Deptsvym!.Value,
ZenithAngle = coord.Svyinc!.Value,
AzimuthGeo = coord.Svyazc!.Value
})
.ToArray();
return result; if (request.LtDate.HasValue)
} query = query.Where(r => r.DateTime <= request.LtDate.Value);
return query.OrderBy(e => e.Deptsvym);
} }
} }

View File

@ -149,7 +149,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
.SetVal(modeData.UsageFact); .SetVal(modeData.UsageFact);
sheet.Cell(row, columnRop) sheet.Cell(row, columnRop)
.SetVal(modeData.Rop); .SetVal(modeData.RopFact);
return row + 1; return row + 1;
} }

View File

@ -171,6 +171,7 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling
var result = new ProcessMapReportWellDrillingDto var result = new ProcessMapReportWellDrillingDto
{ {
IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell, IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell,
IdMode = processMapByMode?.IdMode,
IdWellSectionType = idWellSectionType, IdWellSectionType = idWellSectionType,
WellSectionTypeName = sectionTypes[idWellSectionType], WellSectionTypeName = sectionTypes[idWellSectionType],
@ -188,7 +189,9 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan), TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan), SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
Rop = telemetryStat.Rop, RopPlan = processMapByMode?.RopPlan,
RopFact = telemetryStat.Rop,
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan, UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
UsageFact = telemetryStat.UsageSaub, UsageFact = telemetryStat.UsageSaub,
}; };

View File

@ -186,17 +186,6 @@ internal static class XLExtentions
return style; return style;
} }
/// <summary>
/// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress.
/// </summary>
/// <param name="sheet"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
internal static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end)
=> sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber);
internal static T? GetCellValue<T>(this IXLCell cell) internal static T? GetCellValue<T>(this IXLCell cell)
{ {
try try