forked from ddrilling/AsbCloudServer
#7987467 +
This commit is contained in:
parent
90ee5d10d1
commit
bfc9376733
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
/// <summary>
|
62
AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs
Normal file
62
AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
/// <summary>
|
||||
/// Модель РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу, м
|
||||
/// </summary>
|
||||
public double Depth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата/ время
|
||||
/// </summary>
|
||||
public DateTimeOffset Date { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Т мех бурения, ч
|
||||
/// </summary>
|
||||
public double MechDrillingTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Слайд
|
||||
/// </summary>
|
||||
public ProcessMapReportRowDto Slide { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Ротор
|
||||
/// </summary>
|
||||
public ProcessMapReportRowDto Rotor { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// название секции скважины
|
||||
/// </summary>
|
||||
public string? WellSectionTypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название секции скважины
|
||||
/// </summary>
|
||||
public int? IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Категория
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор категории
|
||||
/// </summary>
|
||||
public int? IdCategory { get; set; }
|
||||
}
|
||||
#nullable disable
|
||||
}
|
41
AsbCloudApp/Data/ProcessMap/ProcessMapReportParamsDto.cs
Normal file
41
AsbCloudApp/Data/ProcessMap/ProcessMapReportParamsDto.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
/// <summary>
|
||||
/// Параметры РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportParamsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Уставка план
|
||||
/// </summary>
|
||||
public double SetPointPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка факт
|
||||
/// </summary>
|
||||
public double? SetPointFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Факт
|
||||
/// </summary>
|
||||
public double? Fact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение
|
||||
/// </summary>
|
||||
public double? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Процент бурения по уставке ,%
|
||||
/// </summary>
|
||||
public double? PercDrillingSetPoint { get; set; }
|
||||
}
|
||||
#nullable disable
|
||||
}
|
51
AsbCloudApp/Data/ProcessMap/ProcessMapReportRowDto.cs
Normal file
51
AsbCloudApp/Data/ProcessMap/ProcessMapReportRowDto.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
/// <summary>
|
||||
/// Строки РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportRowDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Перепад давления, атм
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto PressureDrop { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Нагрузка, т
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto Load { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Момент на ВСП, кНхМ
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto TopDriveTorque { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение скорости, м/ч
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto SpeedLimit { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Процент использования системы АПД, %
|
||||
/// </summary>
|
||||
public double PercentageADFSystemUsage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая механическая скорость, м/ч
|
||||
/// </summary>
|
||||
public double ActualMechanicalSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Проходка, м
|
||||
/// </summary>
|
||||
public double? SectionPenetration { get; set; }
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
24
AsbCloudApp/Services/IProcessMapService.cs
Normal file
24
AsbCloudApp/Services/IProcessMapService.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
#nullable enable
|
||||
/// <summary>
|
||||
/// Сервис формирования РТК
|
||||
/// </summary>
|
||||
public interface IProcessMapService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение моделей РТК
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token);
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -121,5 +121,13 @@ namespace AsbCloudApp.Services
|
||||
/// <param name="idWell"></param>
|
||||
/// <returns></returns>
|
||||
DateTimeOffset? FirstOperationDate(int idWell);
|
||||
|
||||
/// <summary>
|
||||
/// Получение операций по идентификатору скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WellOperationDto>> GetOperationsByIdWellAsync(int idWell, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
|
@ -136,6 +136,7 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
||||
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
||||
services.AddTransient<IProcessMapReportService, ProcessMapReportService>();
|
||||
services.AddTransient<IProcessMapService, ProcessMapService>();
|
||||
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
|
@ -0,0 +1 @@
|
||||
,ASB/andas,asb,19.12.2022 11:39,file:///C:/Users/andas/AppData/Roaming/LibreOffice/4;
|
@ -1,6 +1,7 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.DailyReport;
|
||||
using ClosedXML.Excel;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -10,25 +11,35 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
public class ProcessMapReportService : IProcessMapReportService
|
||||
{
|
||||
private readonly IAsbCloudDbContext context;
|
||||
private readonly IProcessMapRepository processMapRepository;
|
||||
private readonly IProcessMapService processMapService;
|
||||
|
||||
public ProcessMapReportService(IAsbCloudDbContext context, IProcessMapRepository processMapRepository)
|
||||
public ProcessMapReportService(IAsbCloudDbContext context, IProcessMapRepository processMapRepository, IProcessMapService processMapService)
|
||||
{
|
||||
this.context = context;
|
||||
this.processMapRepository = processMapRepository;
|
||||
this.processMapService = processMapService;
|
||||
}
|
||||
|
||||
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var dtos = (await processMapRepository.GetByIdWellAsync(idWell, token))
|
||||
.GroupBy(x => x.IdWellSectionType);
|
||||
var stream = GetExcelTemplateStream();
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
|
||||
FillProcessMapToWorkbook(workbook, dtos);
|
||||
var data = processMapService.GetProcessMapAsync(idWell, token);
|
||||
|
||||
//var dtos = await processMapRepository.GetByIdWellAsync(idWell, token).ConfigureAwait(false);
|
||||
//if (dtos is not null)
|
||||
//{
|
||||
// var processMapReportDto = await processMapService.GetProcessMapAsync(dtos, token).ConfigureAwait(false);
|
||||
// FillProcessMapToWorkbook(workbook, processMapReportDto);
|
||||
//}
|
||||
|
||||
FillProcessMapToWorkbook(workbook, new List<ProcessMapReportDto>());
|
||||
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||
@ -36,20 +47,44 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<IGrouping<int, ProcessMapDto>> dto)
|
||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> dto)
|
||||
{
|
||||
var rowsCount = 4;
|
||||
var columnCount = 2;
|
||||
var countMerge = 27;
|
||||
|
||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
||||
if (sheet is null)
|
||||
return;
|
||||
|
||||
|
||||
sheet.Row(rowsCount).Cell(columnCount).Value = "saddadasdasdasds";
|
||||
sheet.Range(rowsCount, columnCount, rowsCount, countMerge).Row(1).Merge();
|
||||
SetBorder(sheet.Row(rowsCount).Cell(columnCount).Style);
|
||||
|
||||
rowsCount++;
|
||||
sheet.Row(rowsCount).Cell(columnCount).Value = 2;
|
||||
sheet.Row(rowsCount).Cell(columnCount).Value = 3;
|
||||
columnCount++;
|
||||
sheet.Row(rowsCount).Cell(columnCount).Value = 4;
|
||||
}
|
||||
|
||||
private Stream GetExcelTemplateStream()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
||||
return stream;
|
||||
return stream!;
|
||||
}
|
||||
|
||||
private static IXLStyle SetBorder(IXLStyle style)
|
||||
{
|
||||
style.Border.RightBorder = XLBorderStyleValues.Medium;
|
||||
style.Border.LeftBorder = XLBorderStyleValues.Medium;
|
||||
style.Border.TopBorder = XLBorderStyleValues.Medium;
|
||||
style.Border.BottomBorder = XLBorderStyleValues.Medium;
|
||||
style.Border.InsideBorder = XLBorderStyleValues.Medium;
|
||||
return style;
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
}
|
159
AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs
Normal file
159
AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs
Normal file
@ -0,0 +1,159 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using DocumentFormat.OpenXml.Bibliography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
{
|
||||
#nullable enable
|
||||
public class ProcessMapService : IProcessMapService
|
||||
{
|
||||
private readonly IWellOperationService wellOperationService;
|
||||
private readonly IProcessMapRepository processMapRepository;
|
||||
|
||||
public ProcessMapService(IWellOperationService wellOperationService,
|
||||
IProcessMapRepository processMapRepository)
|
||||
{
|
||||
this.wellOperationService = wellOperationService;
|
||||
this.processMapRepository = processMapRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var categoryIds = new int[] { WellOperationCategory.IdSlide, WellOperationCategory.IdRotor };
|
||||
var allOperations = (await wellOperationService.GetOperationsByIdWellAsync(idWell, token).ConfigureAwait(false))
|
||||
.Where(x => categoryIds.Contains(x.IdCategory))
|
||||
.Where(x => x.IdType == 1)
|
||||
.OrderBy(x => x.IdWellSectionType)
|
||||
.ThenBy(x => x.DateStart)
|
||||
.ToList();
|
||||
var processMapDtos = await processMapRepository.GetByIdWellAsync(idWell, token).ConfigureAwait(false);
|
||||
|
||||
var result = allOperations
|
||||
.GroupBy(x => x.IdWellSectionType)
|
||||
.SelectMany(x => handleSections(allOperations, processMapDtos!, x))
|
||||
.ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<ProcessMapReportDto> handleSections(IEnumerable<WellOperationDto> allWellOperation, IEnumerable<ProcessMapDto> processMap, IEnumerable<WellOperationDto> wellOperation)
|
||||
{
|
||||
var result = new List<ProcessMapReportDto>();
|
||||
var minDepth = wellOperation.Min(o => o.DepthStart);
|
||||
var maxDepth = wellOperation.Max(o => o.DepthEnd);
|
||||
|
||||
for (var depth = minDepth; depth <= maxDepth; depth += 100)
|
||||
{
|
||||
var currentDepth = result.Count() > 0 ? depth + (100 - depth % 100) : depth;
|
||||
var operation = allWellOperation.First(x => x.DepthEnd >= currentDepth);
|
||||
var minDate = operation.DateStart;
|
||||
var maxDate = operation.DateStart.AddHours(operation.DurationHours);
|
||||
var currentDate = GetDate(currentDepth, minDepth, maxDepth, minDate, maxDate);
|
||||
var currentHours = GetHourse(currentDepth, minDepth, maxDepth, operation.DurationHours);
|
||||
var processMapData = processMap.FirstOrDefault(x => x.IdWellSectionType == operation.IdWellSectionType);
|
||||
|
||||
var dto = GetRecord(currentDepth, currentDate, currentHours, operation, processMap);
|
||||
|
||||
if (operation.DepthStart < currentDepth)
|
||||
{
|
||||
var prevOperation = allWellOperation.FirstOrDefault(x => x.DepthEnd == operation.DepthStart);
|
||||
if (prevOperation is not null)
|
||||
{
|
||||
var prevDepth = currentDepth - prevOperation.DepthEnd;
|
||||
var prevMinDate = prevOperation.DateStart;
|
||||
var prevMaxDate = operation.DateStart.AddHours(operation.DurationHours);
|
||||
var prevDate = GetDate(prevDepth, prevOperation.DepthStart, prevOperation.DepthEnd, minDate, maxDate);
|
||||
var prevHours = GetHourse(currentDepth, prevOperation.DepthStart, prevOperation.DepthEnd, prevOperation.DurationHours);
|
||||
|
||||
if (dto.IdCategory != prevOperation.IdCategory)
|
||||
FillRecordRow(prevDepth, prevHours, dto, prevOperation.IdCategory, processMap);
|
||||
|
||||
dto.MechDrillingTime = currentHours + prevHours;
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(dto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ProcessMapReportDto GetRecord(double depth, DateTimeOffset sate, double hours, WellOperationDto operation, IEnumerable<ProcessMapDto> processMap)
|
||||
{
|
||||
var dto = new ProcessMapReportDto
|
||||
{
|
||||
IdWell = operation.IdWell,
|
||||
Depth = depth,
|
||||
Date = sate,
|
||||
MechDrillingTime = hours,
|
||||
Category = operation.IdCategory == WellOperationCategory.IdSlide ? "Слайд" : "Ротор",
|
||||
IdCategory = operation.IdCategory,
|
||||
IdWellSectionType = operation.IdWellSectionType,
|
||||
WellSectionTypeName = operation.WellSectionTypeName
|
||||
};
|
||||
FillRecordRow(depth, hours, dto, operation.IdCategory, processMap);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static void FillRecordRow(double depth, double hours, ProcessMapReportDto dto, int idCategory, IEnumerable<ProcessMapDto> processMap)
|
||||
{
|
||||
var row = new ProcessMapReportRowDto {
|
||||
SectionPenetration = depth,
|
||||
ActualMechanicalSpeed = depth / hours,
|
||||
PercentageADFSystemUsage = dto.Depth / depth * 100
|
||||
};
|
||||
|
||||
var processMapData = processMap.FirstOrDefault(x => x.IdWell == dto.IdWell && x.IdWellSectionType == dto.IdWellSectionType);
|
||||
if (processMapData is not null)
|
||||
{
|
||||
row.PressureDrop = new ProcessMapReportParamsDto
|
||||
{
|
||||
SetPointPlan = processMapData.Pressure.Plan
|
||||
};
|
||||
row.Load = new ProcessMapReportParamsDto
|
||||
{
|
||||
SetPointPlan = processMapData.AxialLoad.Plan
|
||||
};
|
||||
row.TopDriveTorque = new ProcessMapReportParamsDto
|
||||
{
|
||||
SetPointPlan = processMapData.TopDriveTorque.Plan
|
||||
};
|
||||
row.SpeedLimit = new ProcessMapReportParamsDto
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
if (idCategory == WellOperationCategory.IdSlide)
|
||||
dto.Slide = row;
|
||||
else
|
||||
dto.Rotor = row;
|
||||
}
|
||||
|
||||
private static DateTimeOffset GetDate(double depth, double deptStart, double deptEnd, DateTimeOffset dateStart, DateTimeOffset dateEnd)
|
||||
{
|
||||
var a = depth - deptStart;
|
||||
var b = deptEnd - deptStart;
|
||||
var c = dateEnd - dateStart;
|
||||
var result = dateStart + (a / b) * c;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static double GetHourse(double depth, double deptStart, double deptEnd, double hourse)
|
||||
{
|
||||
var a = depth - deptStart;
|
||||
var b = deptEnd - deptStart;
|
||||
var result = 0 + (a / b) * hourse;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -139,6 +139,43 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellOperationDto>> GetOperationsByIdWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
var query = BuildQuery(idWell);
|
||||
var dateStart = query.Min(o => o.DateStart);
|
||||
|
||||
query = query
|
||||
.OrderBy(e => e.DateStart)
|
||||
.ThenBy(e => e.DepthEnd)
|
||||
.ThenBy(e => e.Id);
|
||||
|
||||
var entities = await query.AsNoTracking()
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var nptHours = 0d;
|
||||
var result = new List<WellOperationDto>();
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var dto = entity.Adapt<WellOperationDto>();
|
||||
dto.Day = (entity.DateStart - dateStart).TotalDays;
|
||||
dto.WellSectionTypeName = entity.WellSectionType.Caption;
|
||||
dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours);
|
||||
dto.CategoryName = entity.OperationCategory.Name;
|
||||
if (entity.IdType == idOperationTypeFact)
|
||||
{
|
||||
if (WellOperationCategory.NonProductiveTimeSubIds.Contains(entity.IdCategory))
|
||||
nptHours += entity.DurationHours;
|
||||
dto.NptHours = nptHours;
|
||||
}
|
||||
result.Add(dto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(
|
||||
int idWell,
|
||||
int? operationType = default,
|
||||
|
@ -1,4 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using FluentValidation;
|
||||
|
||||
namespace AsbCloudInfrastructure.Validators
|
||||
|
@ -1,4 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
Loading…
Reference in New Issue
Block a user