forked from ddrilling/AsbCloudServer
Add TelemetryDataSaubController.GetZippedCsv(..)
This commit is contained in:
parent
cff9fe3fe7
commit
db1bd49d60
@ -19,6 +19,11 @@ namespace AsbCloudApp.Data
|
||||
/// информация о бурении, панели оператора и контроллерах
|
||||
/// </summary>
|
||||
public TelemetryInfoDto? Info { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Смещение часового пояса от UTC
|
||||
/// </summary>
|
||||
public SimpleTimezoneDto? TimeZone { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,5 +1,7 @@
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -20,5 +22,15 @@ namespace AsbCloudApp.Services
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TelemetryDataSaubStatDto>> GetTelemetryDataStatAsync(int idTelemetry, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить упакованый csv файл
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="beginDate"></param>
|
||||
/// <param name="endDate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<Stream> GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate, CancellationToken token);
|
||||
}
|
||||
}
|
85
AsbCloudInfrastructure/Services/SAUB/CsvSerializer.cs
Normal file
85
AsbCloudInfrastructure/Services/SAUB/CsvSerializer.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace System.Text.Csv
|
||||
{
|
||||
#nullable enable
|
||||
public class CsvSerializer<T>
|
||||
{
|
||||
private readonly PropertyInfo[] props;
|
||||
private readonly static Regex numbers = new Regex(@"^[0-9\-\+\.]+$");
|
||||
|
||||
public string Separator { get; set; } = ";";
|
||||
public string NewLine { get; set; } = "\r\n";
|
||||
public string Quot { get; set; } = "\"";
|
||||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
public string FloatingPointFormat { get; set; } = "#0.000#";
|
||||
public string DateTimeFormat { get; set; } = "yyyy-MM-dd HH:mm:ss";
|
||||
public string objDateTimeOffsetFormat { get; set; } = "yyyy-MM-dd HH:mm:ss zzz";
|
||||
public string TimeOnlyFormat { get; set; } = "HH:mm:ss";
|
||||
public string DateOnlyFormat { get; set; } = "yyyy-MM-dd";
|
||||
|
||||
public CsvSerializer()
|
||||
{
|
||||
props = typeof(T).GetProperties();
|
||||
}
|
||||
|
||||
public void Serialize(IEnumerable<T> data, Stream toStream)
|
||||
{
|
||||
if (!data.Any())
|
||||
return;
|
||||
|
||||
if(!props.Any())
|
||||
return;
|
||||
|
||||
void HandleRow(IEnumerable<object?> rowData)
|
||||
{
|
||||
var row = string.Join(Separator, rowData);
|
||||
var bytes = Encoding.GetBytes(row + NewLine);
|
||||
toStream.Write(bytes);
|
||||
}
|
||||
|
||||
|
||||
HandleRow(props.Select(p => p.Name));
|
||||
|
||||
foreach ( var item in data)
|
||||
HandleRow(props.Select(p => CsvSerializer<T>.Escape(Fromat(p.GetValue(item)))));
|
||||
}
|
||||
|
||||
private string Fromat(object? obj)
|
||||
{
|
||||
if (obj is double objDouble)
|
||||
return objDouble.ToString(FloatingPointFormat);
|
||||
|
||||
if (obj is float objfloat)
|
||||
return objfloat.ToString(FloatingPointFormat);
|
||||
|
||||
if (obj is DateTime objDateTime)
|
||||
return objDateTime.ToString(DateTimeFormat);
|
||||
|
||||
if (obj is DateTimeOffset objDateTimeOffset)
|
||||
return objDateTimeOffset.ToString(objDateTimeOffsetFormat);
|
||||
|
||||
if (obj is DateOnly objDateOnly)
|
||||
return objDateOnly.ToString(DateOnlyFormat);
|
||||
|
||||
if (obj is TimeOnly objTimeOnly)
|
||||
return objTimeOnly.ToString(TimeOnlyFormat);
|
||||
|
||||
return obj?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
private static string Escape(string inString)
|
||||
{
|
||||
if (numbers.IsMatch(inString))
|
||||
return inString;
|
||||
|
||||
return $"\"{inString}\"";
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
@ -6,7 +8,10 @@ using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Csv;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -99,10 +104,40 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
return dto;
|
||||
}
|
||||
|
||||
public Stream GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate)
|
||||
public async Task<Stream> GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate, CancellationToken token)
|
||||
{
|
||||
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
|
||||
return null;
|
||||
double intervalSec = (endDate - beginDate).TotalSeconds;
|
||||
if (intervalSec > 60*60*24*3)
|
||||
throw new ArgumentInvalidException("Слишком большой диапазон", nameof(endDate));
|
||||
|
||||
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell)
|
||||
?? throw new ArgumentInvalidException($"Скважина id:{idWell} не содержит телеметрии", nameof(idWell));
|
||||
|
||||
var approxPointsCount = intervalSec switch
|
||||
{
|
||||
< 2048 => 2048,
|
||||
< 8_192 => 4_096,
|
||||
< 131_072 => 16_384,
|
||||
_ => 32_768
|
||||
};
|
||||
|
||||
var data = await GetOrDefaultAsync(idWell, beginDate, intervalSec, approxPointsCount, token );
|
||||
|
||||
var fileName = $"DataSaub idWell{idWell}";
|
||||
if (telemetry.Info is not null)
|
||||
fileName += $" {telemetry.Info?.Cluster}, {telemetry.Info?.Well}";
|
||||
fileName += $" {beginDate:yyyy-MM-DDTHH-mm} - {endDate:yyyy-MM-DDTHH-mm}.csv";
|
||||
|
||||
var outStream = new MemoryStream();
|
||||
using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
|
||||
{
|
||||
var entryFile = archive.CreateEntry(fileName, CompressionLevel.Optimal);
|
||||
using var entryStream = entryFile.Open();
|
||||
var serializer = new CsvSerializer<TelemetryDataSaubDto>();
|
||||
serializer.Serialize(data, entryStream);
|
||||
}
|
||||
outStream.Seek(0, SeekOrigin.Begin);
|
||||
return outStream;
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
|
@ -47,7 +47,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
.Options;
|
||||
var db = new AsbCloudDbContext(contextOptions);
|
||||
|
||||
var cacheTelemetry = memoryCache.GetOrCreateBasic(db.Set<Telemetry>());
|
||||
var cacheTelemetry = memoryCache.GetOrCreateBasic(db.Set<Telemetry>().Include(t=>t.Well));
|
||||
var keyValuePairs = new Dictionary<string, TrackerStat>(cacheTelemetry.Count());
|
||||
foreach (var telemetry in cacheTelemetry)
|
||||
{
|
||||
|
@ -18,9 +18,9 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
||||
public abstract class TelemetryDataBaseController<TDto> : ControllerBase
|
||||
where TDto : ITelemetryData
|
||||
{
|
||||
protected readonly IWellService wellService;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly ITelemetryDataService<TDto> telemetryDataService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IHubContext<TelemetryHub> telemetryHubContext;
|
||||
|
||||
public string SirnalRMethodGetDataName { get; protected set; } = "ReceiveData";
|
||||
|
@ -3,6 +3,11 @@ using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.SAUB
|
||||
{
|
||||
@ -13,6 +18,8 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
||||
[ApiController]
|
||||
public class TelemetryDataSaubController : TelemetryDataBaseController<TelemetryDataSaubDto>
|
||||
{
|
||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||
|
||||
public TelemetryDataSaubController(
|
||||
ITelemetryService telemetryService,
|
||||
ITelemetryDataSaubService telemetryDataService,
|
||||
@ -25,6 +32,35 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
||||
telemetryHubContext)
|
||||
{
|
||||
SirnalRMethodGetDataName = "ReceiveDataSaub";
|
||||
telemetryDataSaubService = telemetryDataService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выгрузка архива. Не более 3-х суток. Формат даты строгий.
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины (из адресной строки)</param>
|
||||
/// <param name="beginDate">начало интервала в формате: yyyy-MM-DD HH:mm</param>
|
||||
/// <param name="endDate">конец интервала в формате: yyyy-MM-DD HH:mm</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{idWell}/export/csv")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
|
||||
bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
|
||||
if (!isCompanyOwnsWell)
|
||||
return Forbid();
|
||||
|
||||
var stream = await telemetryDataSaubService.GetZippedCsv(idWell, beginDate, endDate, token).ConfigureAwait(false);
|
||||
var fileName = $"DataSaub idWell{idWell} {beginDate:yyyy-MM-DDTHH-mm} - {endDate:yyyy-MM-DDTHH-mm}.zip";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
@ -19,20 +17,11 @@ namespace ConsoleApp1
|
||||
{
|
||||
static void Main(/*string[] args*/)
|
||||
{
|
||||
var db = ServiceFactory.Context;
|
||||
var q = db.TelemetryDataSaub
|
||||
.Select(t => new {
|
||||
t.IdTelemetry,
|
||||
t.DateTime,
|
||||
t.WellDepth,
|
||||
})
|
||||
.GroupBy(t => t.IdTelemetry)
|
||||
.Select(g => new {
|
||||
Id = g.Key,
|
||||
First = g.OrderBy(t => t.DateTime).FirstOrDefault(),
|
||||
Last = g.OrderBy(t => t.DateTime).LastOrDefault(),
|
||||
});
|
||||
var d = q.AsNoTracking().ToArray();
|
||||
|
||||
var n = "-159.99";
|
||||
var s = "159.99s";
|
||||
var r1 = reg.IsMatch( n );
|
||||
var r2 = reg.IsMatch( s );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user