diff --git a/.gitignore b/.gitignore index d65f82ed..fc614d65 100644 --- a/.gitignore +++ b/.gitignore @@ -174,13 +174,13 @@ publish/ *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj +# *.pubxml +# *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted -PublishScripts/ +# PublishScripts/ # NuGet Packages *.nupkg diff --git a/AsbCloudApp/AsbCloudApp.csproj b/AsbCloudApp/AsbCloudApp.csproj index 64a7b66a..7a10181c 100644 --- a/AsbCloudApp/AsbCloudApp.csproj +++ b/AsbCloudApp/AsbCloudApp.csproj @@ -13,4 +13,16 @@ + + + + + + + + + + + + diff --git a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs index c47b8934..920aeb54 100644 --- a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs +++ b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs @@ -1,5 +1,6 @@ namespace AsbCloudApp.Data.DailyReport { +#nullable enable /// /// Блоки для формирования суточного рапорта /// @@ -35,4 +36,5 @@ /// public SignDto Sign { get; set; } = new(); } +#nullable disable } diff --git a/AsbCloudApp/Data/DrillParamsDto.cs b/AsbCloudApp/Data/DrillParamsDto.cs index 0d667a58..d79f2451 100644 --- a/AsbCloudApp/Data/DrillParamsDto.cs +++ b/AsbCloudApp/Data/DrillParamsDto.cs @@ -13,14 +13,9 @@ namespace AsbCloudApp.Data public int IdWell { get; set; } /// - /// + /// /// - public double DepthStart { get; set; } - - /// - /// - /// - public double DepthEnd { get; set; } + public MinMaxDto Depth { get; set; } /// /// id well section type. @@ -28,78 +23,28 @@ namespace AsbCloudApp.Data public int IdWellSectionType { get; set; } /// - /// axial load min. + /// axial load /// - public double AxialLoadMin { get; set; } + public MinMaxExtendedViewDto AxialLoad { get; set; } /// - /// axial load avg. + /// pressure /// - public double AxialLoadAvg { get; set; } + public MinMaxExtendedViewDto Pressure { get; set; } /// - /// axial load max. + /// rotor torque /// - public double AxialLoadMax { get; set; } + public MinMaxExtendedViewDto RotorTorque { get; set; } /// - /// pressure min. + /// rotor speed /// - public double PressureMin { get; set; } + public MinMaxExtendedViewDto RotorSpeed { get; set; } /// - /// pressure avg. + /// flow /// - public double PressureAvg { get; set; } - - /// - /// pressure max. - /// - public double PressureMax { get; set; } - - /// - /// rotor torque min. - /// - public double RotorTorqueMin { get; set; } - - /// - /// rotor torque avg. - /// - public double RotorTorqueAvg { get; set; } - - /// - /// rotor torque max. - /// - public double RotorTorqueMax { get; set; } - - /// - /// rotor speed min. - /// - public double RotorSpeedMin { get; set; } - - /// - /// rotor speed avg. - /// - public double RotorSpeedAvg { get; set; } - - /// - /// rotor speed max. - /// - public double RotorSpeedMax { get; set; } - - /// - /// flow min. - /// - public double FlowMin { get; set; } - - /// - /// flow avg. - /// - public double FlowAvg { get; set; } - - /// - /// flow max. - /// - public double FlowMax { get; set; } + public MinMaxExtendedViewDto Flow { get; set; } } } \ No newline at end of file diff --git a/AsbCloudApp/Data/FileInfoDto.cs b/AsbCloudApp/Data/FileInfoDto.cs index 63abba8f..badcd5a4 100644 --- a/AsbCloudApp/Data/FileInfoDto.cs +++ b/AsbCloudApp/Data/FileInfoDto.cs @@ -39,6 +39,11 @@ namespace AsbCloudApp.Data /// public long Size { get; set; } + /// + /// Помечен как удаленный + /// + public bool IsDeleted { get; set; } + /// /// DTO автора /// diff --git a/AsbCloudApp/Data/JobDto.cs b/AsbCloudApp/Data/JobDto.cs new file mode 100644 index 00000000..2e9b336a --- /dev/null +++ b/AsbCloudApp/Data/JobDto.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; + +namespace AsbCloudApp.Data +{ +#nullable enable + /// + /// Состояние фоновой задачи + /// + public enum JobState + { + /// + /// Ожидает в очереди на выполнение + /// + Waiting, + /// + /// выполняется + /// + Working, + /// + /// успешно выполнена + /// + Done, + /// + /// завершена с ошибкой + /// + Fail + }; + + /// + /// работа фоновой задачи + /// + public class JobDto + { + /// + /// идентификатор + /// + public int Id { get; set; } + + /// + /// Состояние + /// + public JobState State { get; set; } + + /// + /// результат выполнения + /// + public Hashtable? Results { get; set; } + + /// + /// Исключение, если возникла ошибка + /// + public string? Error { get; set; } + } +#nullable disable +} diff --git a/AsbCloudApp/Data/MinMaxDto.cs b/AsbCloudApp/Data/MinMaxDto.cs new file mode 100644 index 00000000..291574bc --- /dev/null +++ b/AsbCloudApp/Data/MinMaxDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudApp.Data +{ +#nullable enable + /// + /// Минимальное и максимальное значение + /// + public class MinMaxDto + { + /// + /// Минимальное значение + /// + public T? Min { get; set; } + + /// + /// Максимальное значение + /// + public T? Max { get; set; } + } +#nullable disable +} diff --git a/AsbCloudApp/Data/MinMaxExtendedViewDto.cs b/AsbCloudApp/Data/MinMaxExtendedViewDto.cs new file mode 100644 index 00000000..cb66e60d --- /dev/null +++ b/AsbCloudApp/Data/MinMaxExtendedViewDto.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudApp.Data +{ +#nullable enable + /// + /// Расширение для класса MinMaxDto + /// + public class MinMaxExtendedViewDto : MinMaxDto + { + /// + /// Среднее значение + /// + public double Avg { get; set; } + + /// + /// Является максимальным + /// + public bool IsMax { get; set; } + + /// + /// Является минимальным + /// + public bool IsMin { get; set; } + } +#nullable disable +} diff --git a/AsbCloudApp/Data/SAUB/TelemetryDataSpinDto.cs b/AsbCloudApp/Data/SAUB/TelemetryDataSpinDto.cs index 1011f214..008bfeda 100644 --- a/AsbCloudApp/Data/SAUB/TelemetryDataSpinDto.cs +++ b/AsbCloudApp/Data/SAUB/TelemetryDataSpinDto.cs @@ -2,80 +2,77 @@ namespace AsbCloudApp.Data.SAUB { -#pragma warning disable CS1591 // Отсутствует комментарий XML для открытого видимого типа или члена +#nullable enable public class TelemetryDataSpinDto : ITelemetryData { - /// + /// + /// Идентификатор телеметрии + /// public int IdTelemetry { get; set; } + + /// + /// Дата + /// public DateTime DateTime { get; set; } - public DateTime Date // TODO: remove this legacy after all panels updated + + /// + /// Дата + /// + public DateTime Date { get { return DateTime; } set { DateTime = value; } } - public float? TopDriveSpeed { get; set; } - public float? TopDriveSpeedMin { get; set; } - public float? TopDriveSpeedMax { get; set; } - public float? TopDriveSpeedOffset { get; set; } - public short? TopDriveSpeedErr { get; set; } - public float? TopDriveTorque { get; set; } - public float? TopDriveTorqueMin { get; set; } - public float? TopDriveTorqueMax { get; set; } - public float? TopDriveTorqueOffset { get; set; } - public short? TopDriveTorqueErr { get; set; } - public float? TopDriveSpeedSpFrom { get; set; } - public float? TopDriveSpeedSpFromMin { get; set; } - public float? TopDriveSpeedSpFromMax { get; set; } - public float? TopDriveSpeedSpFromOffset { get; set; } - public short? TopDriveSpeedSpFromErr { get; set; } - public float? TopDriveTorqueSpFrom { get; set; } - public float? TopDriveTorqueSpFromMin { get; set; } - public float? TopDriveTorqueSpFromMax { get; set; } - public float? TopDriveTorqueSpFromOffset { get; set; } - public short? TopDriveTorqueSpFromErr { get; set; } - public float? TopDriveSpeedSpTo { get; set; } - public float? TopDriveSpeedSpToMin { get; set; } - public float? TopDriveSpeedSpToMax { get; set; } - public float? TopDriveSpeedSpToOffset { get; set; } - public short? TopDriveSpeedSpToErr { get; set; } - public float? TopDriveTorqueSpTo { get; set; } - public float? TopDriveTorqueSpToMin { get; set; } - public float? TopDriveTorqueSpToMax { get; set; } - public float? TopDriveTorqueSpToOffset { get; set; } - public short? TopDriveTorqueSpToErr { get; set; } - public short? W2800 { get; set; } - public short? W2810 { get; set; } - public short? Mode { get; set; } - public short? W2808 { get; set; } - public float? TorqueStarting { get; set; } - public float? RotorTorqueAvg { get; set; } - public float? EncoderResolution { get; set; } - public float? Ratio { get; set; } - public float? TorqueRightLimit { get; set; } - public float? TorqueLeftLimit { get; set; } + + /// + /// Ограничение числа оборотов вправо + /// public float? RevolsRightLimit { get; set; } + + /// + /// Ограничение числа оборотов влево + /// public float? RevolsLeftLimit { get; set; } + + /// + /// Заданная скорость вращения вправо + /// public float? SpeedRightSp { get; set; } + + /// + /// Заданная скорость вращения влево + /// public float? SpeedLeftSp { get; set; } + + /// + /// Суммарное количество оборотов вправо + /// public float? RevolsRightTotal { get; set; } + + /// + /// Суммарное количество оборотов влево + /// public float? RevolsLeftTotal { get; set; } - public float? TurnRightOnceByTorque { get; set; } - public float? TurnLeftOnceByTorque { get; set; } - public float? TurnRightOnceByAngle { get; set; } - public float? TurnLeftOnceByAngle { get; set; } - public float? TurnRightOnceByRevols { get; set; } - public float? TurnLeftOnceByRevols { get; set; } - public float? BreakAngleK { get; set; } - public float? ReverseKTorque { get; set; } + + /// + /// Нулевая позиция осцилляции + /// public float? PositionZero { get; set; } + + /// + /// Крайний правый угол осцилляции + /// public float? PositionRight { get; set; } - public float? TorqueRampTime { get; set; } - public float? Ver { get; set; } - public short? ReverseSpeedSpZeroTime { get; set; } - public float? UnlockBySectorOut { get; set; } - public float? PidMuxTorqueLeftLimit { get; set; } + + /// + /// Выбранный режим управления + /// + public short? Mode { get; set; } + + /// + /// Переменная этапа + /// public short? State { get; set; } - public float? BreakAngleLeft { get; set; } } -#pragma warning restore CS1591 // Отсутствует комментарий XML для открытого видимого типа или члена +#nullable disable } diff --git a/AsbCloudApp/Repositories/IFileRepository.cs b/AsbCloudApp/Repositories/IFileRepository.cs new file mode 100644 index 00000000..a05cf909 --- /dev/null +++ b/AsbCloudApp/Repositories/IFileRepository.cs @@ -0,0 +1,83 @@ +using AsbCloudApp.Requests; +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Repositories +{ +#nullable enable + /// + /// Сервис доступа к файлам + /// + public interface IFileRepository : ICrudService + { + /// + /// Получение файлов по скважине + /// + /// + /// + /// + Task> GetInfosAsync(FileRequest request, CancellationToken token); + + /// + /// Получить список файлов в контейнере + /// + /// + /// + /// + Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token = default); + + /// + /// Пометить файл как удаленный + /// + /// + /// + /// + Task MarkAsDeletedAsync(int idFile, CancellationToken token = default); + + /// + /// удалить файлы + /// + /// + /// + /// + Task> DeleteAsync(IEnumerable ids, CancellationToken token); + + /// + /// получить инфо о файле по метке + /// + /// + /// + /// + Task GetByMarkId(int idMark, CancellationToken token); + + /// + /// добавить метку на файл + /// + /// + /// + /// + /// + Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token); + + /// + /// Инфо о файлах + /// + /// + /// + /// + Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token); + + /// + /// пометить метки файлов как удаленные + /// + /// + /// + /// + Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token); + + } +#nullable disable +} diff --git a/AsbCloudApp/Repositories/IFileStorageRepository.cs b/AsbCloudApp/Repositories/IFileStorageRepository.cs new file mode 100644 index 00000000..0d867db0 --- /dev/null +++ b/AsbCloudApp/Repositories/IFileStorageRepository.cs @@ -0,0 +1,80 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Repositories +{ +#nullable enable + /// + /// Репозиторий хранения фалов + /// + public interface IFileStorageRepository + { + /// + /// Получение длинны фала и проверка его наличия, если отсутствует падает исключение + /// + /// + /// + long GetFileLength(string srcFilePath); + + /// + /// Перемещение файла + /// + /// + /// + void MoveFile(string srcFilePath, string filePath); + + /// + /// Копирование файла + /// + /// + /// + /// + /// + Task SaveFileAsync(string filePathRec, Stream fileStreamSrc, CancellationToken token); + + /// + /// Удаление файла + /// + /// + void DeleteFile(IEnumerable filesName); + + /// + /// Удаление всех файлов с диска о которых нет информации в базе + /// + /// + /// + int DeleteFilesNotInList(int idWell, IEnumerable idsFiles); + + /// + /// Вывод списка всех файлов из базы, для которых нет файла на диске + /// + /// + /// + /// + IEnumerable GetListFilesNotDisc(IEnumerable files); + + /// + /// Получение пути к файлу + /// + /// + /// + /// + /// + /// + string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId); + + /// + /// Получить путь для скачивания + /// + /// + /// + /// + /// + /// + string GetUrl(int idWell, int idCategory, int idFile, string dotExtention); + } +#nullable disable +} diff --git a/AsbCloudApp/Requests/FileRequest.cs b/AsbCloudApp/Requests/FileRequest.cs new file mode 100644 index 00000000..14a799e0 --- /dev/null +++ b/AsbCloudApp/Requests/FileRequest.cs @@ -0,0 +1,50 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudApp.Requests +{ +#nullable enable + /// + /// Параметры запроса для файлового сервиса + /// + public class FileRequest : RequestBase + { + /// + /// Идентификатор скважины + /// + [Required] + public int IdWell { get; set; } + + /// + /// Идентификатор категории файла + /// + [Required] + public int? IdCategory { get; set; } + + /// + /// Наименование компании + /// + public string? CompanyNamePart { get; set; } + + /// + /// Имя файла + /// + public string? FileNamePart { get; set; } + + /// + /// Дата начала периода + /// + public DateTime? Begin { get; set; } + + /// + /// Дата окончания периода + /// + public DateTime? End { get; set; } + + /// + /// Признак удаления + /// + public bool? IsDeleted { get; set; } + } +#nullable disable +} diff --git a/AsbCloudApp/Services/FileService.cs b/AsbCloudApp/Services/FileService.cs new file mode 100644 index 00000000..3ba250aa --- /dev/null +++ b/AsbCloudApp/Services/FileService.cs @@ -0,0 +1,312 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ +#nullable enable + /// + /// Сервис доступа к файлам + /// + public class FileService + { + private readonly IFileRepository fileRepository; + private readonly IFileStorageRepository fileStorageRepository; + + /// + /// Сервис доступа к файлам + /// + /// + /// + public FileService(IFileRepository fileRepository, IFileStorageRepository fileStorageRepository) + { + this.fileRepository = fileRepository; + this.fileStorageRepository = fileStorageRepository; + } + + /// + /// переместить файл + /// + /// + /// + /// + /// + /// + /// + /// + public async Task MoveAsync(int idWell, int? idUser, int idCategory, + string destinationFileName, string srcFilePath, CancellationToken token = default) + { + destinationFileName = Path.GetFileName(destinationFileName); + srcFilePath = Path.GetFullPath(srcFilePath); + var fileSize = fileStorageRepository.GetFileLength(srcFilePath); + + //save info to db + var dto = new FileInfoDto { + IdWell = idWell, + IdAuthor = idUser, + IdCategory = idCategory, + Name = destinationFileName, + Size = fileSize + }; + var fileId = await fileRepository.InsertAsync(dto, token) + .ConfigureAwait(false); + + string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, destinationFileName, fileId); + fileStorageRepository.MoveFile(srcFilePath, filePath); + + return await GetOrDefaultAsync(fileId, token); + } + + /// + /// Сохранить файл + /// + /// + /// + /// + /// + /// + /// + /// + public async Task SaveAsync(int idWell, int? idUser, int idCategory, + string fileFullName, Stream fileStream, CancellationToken token) + { + //save info to db + var dto = new FileInfoDto + { + IdWell = idWell, + IdAuthor = idUser, + IdCategory = idCategory, + Name = Path.GetFileName(fileFullName), + Size = fileStream.Length + }; + + var fileId = await fileRepository.InsertAsync(dto, token) + .ConfigureAwait(false); + + //save stream to disk + string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, fileFullName, fileId); + await fileStorageRepository.SaveFileAsync(filePath, fileStream, token); + + return await GetOrDefaultAsync(fileId, token); + } + + /// + /// удалить файл + /// + /// + /// + /// + public Task DeleteAsync(int idFile, CancellationToken token) + => DeleteAsync(new int[] { idFile }, token); + + /// + /// удалить файлы + /// + /// + /// + /// + public async Task DeleteAsync(IEnumerable ids, CancellationToken token) + { + if (ids is null || !ids.Any()) + return 0; + + var files = await fileRepository.DeleteAsync(ids, token).ConfigureAwait(false); + + if (files is null || !files.Any()) + return 0; + + var filesName = files.Select(x => GetUrl(x.IdWell, x.IdCategory, x.Id, Path.GetExtension(x.Name))); + fileStorageRepository.DeleteFile(filesName); + + return files.Any() ? 1 : 0; + } + + /// + /// получить путь для скачивания + /// + /// + /// + public string GetUrl(FileInfoDto fileInfo) => + GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); + + /// + /// получить путь для скачивания + /// + /// + /// + /// + /// + /// + public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => + fileStorageRepository.GetUrl(idWell, idCategory, idFile, dotExtention); + + /// + /// пометить метку файла как удаленную + /// + /// + /// + /// + public Task MarkFileMarkAsDeletedAsync(int idMark, + CancellationToken token) + => fileRepository.MarkFileMarkAsDeletedAsync(new int[] { idMark }, token); + + /// + /// Инфо о файле + /// + /// + /// + /// + public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) + { + var result = await fileRepository.GetInfoByIdsAsync(idsFile, token).ConfigureAwait(false); + + foreach (var entity in result) + { + + var ext = Path.GetExtension(entity.Name); + var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); + var fullPath = Path.GetFullPath(relativePath); + } + + return result; + } + + /// + /// Получить файлы определенной категории + /// + /// + /// + /// + public Task> GetInfosAsync(FileRequest request, CancellationToken token) + => fileRepository.GetInfosAsync(request, token); + + /// + /// Получить список файлов в контейнере + /// + /// + /// + /// + public Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token) + => fileRepository.GetInfosPaginatedAsync(request, token); + + /// + /// Пометить файл как удаленный + /// + /// + /// + /// + public Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) + => fileRepository.MarkAsDeletedAsync(idFile, token); + + /// + /// добавить метку на файл + /// + /// + /// + /// + /// + public Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) + => fileRepository.CreateFileMarkAsync(fileMarkDto, idUser, token); + + /// + /// Получить запись по id + /// + /// + /// + /// + public Task GetOrDefaultAsync(int id, CancellationToken token) + => fileRepository.GetOrDefaultAsync(id, token); + + /// + /// получить инфо о файле по метке + /// + /// + /// + /// + public Task GetByMarkId(int idMark, CancellationToken token) + => fileRepository.GetByMarkId(idMark, token); + + /// + /// получить инфо о файле по метке + /// + /// + /// + /// + public Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) + => fileRepository.MarkFileMarkAsDeletedAsync(idsMarks, token); + + /// + /// Удаление всех файлов по скважине помеченных как удаленные + /// + /// + /// + /// + public async Task DeleteFilesFromDbMarkedDeletionByIdWell(int idWell, CancellationToken token) + { + var files = await fileRepository.GetInfosAsync( + new FileRequest + { + IdWell = idWell, + IsDeleted = true + }, + token); + var result = await DeleteAsync(files.Select(x => x.Id), token); + return result; + } + + /// + /// Удаление всех файлов с диска о которых нет информации в базе + /// + /// + /// + public async Task DeleteFilesNotExistStorage(int idWell, CancellationToken token) + { + var files = await fileRepository.GetInfosAsync( + new FileRequest + { + IdWell = idWell + }, + token); + var result = await Task.FromResult(fileStorageRepository.DeleteFilesNotInList(idWell, files.Select(x => x.Id))); + return result; + } + + /// + /// Вывод списка всех файлов из базы, для которых нет файла на диске + /// + /// + /// + /// + public async Task> GetListFilesNotDisc(int idWell, CancellationToken token) + { + var files = await fileRepository.GetInfosAsync( + new FileRequest + { + IdWell = idWell + }, + token); + var result = fileStorageRepository.GetListFilesNotDisc(files); + return result; + } + + /// + /// Получить файловый поток по идентификатору файла + /// + /// + /// + public Stream GetFileStream(FileInfoDto fileInfo) + { + var relativePath = GetUrl(fileInfo); + var fileStream = new FileStream(Path.GetFullPath(relativePath), FileMode.Open); + + return fileStream; + } + } +#nullable disable +} diff --git a/AsbCloudApp/Services/IFileService.cs b/AsbCloudApp/Services/IFileService.cs deleted file mode 100644 index 18d0829d..00000000 --- a/AsbCloudApp/Services/IFileService.cs +++ /dev/null @@ -1,179 +0,0 @@ -using AsbCloudApp.Data; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudApp.Services -{ - //TODO: refactor IFileService - - /// - /// Сервис доступа к файлам - /// - public interface IFileService - { - /// - /// Директория хранения файлов - /// - string RootPath { get; } - - /// - /// Сохранить файл - /// - /// - /// - /// - /// - /// - /// - /// - Task SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token = default); - - /// - /// Получить список файлов в контейнере - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Task> GetInfosAsync(int idWell, - int idCategory, string companyName = default, string fileName = default, DateTime begin = default, DateTime end = default, - int skip = 0, int take = 32, CancellationToken token = default); - - /// - /// Инфо о файле - /// - /// - /// - /// - Task GetInfoAsync(int idFile, - CancellationToken token); - - /// - /// Пометить файл как удаленный - /// - /// - /// - /// - Task MarkAsDeletedAsync(int idFile, - CancellationToken token = default); - - /// - /// Получить файлы определенной категории - /// - /// - /// - /// - /// - Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token = default); - - /// - /// удалить файл - /// - /// - /// - /// - Task DeleteAsync(int id, CancellationToken token); - - /// - /// удалить файлы - /// - /// - /// - /// - Task DeleteAsync(IEnumerable ids, CancellationToken token); - - /// - /// получить путь для скачивания - /// - /// - /// - string GetUrl(FileInfoDto fileInfo); - - /// - /// получить путь для скачивания - /// - /// - /// - string GetUrl(int idFile); - - /// - /// получить путь для скачивания - /// - /// - /// - /// - /// - /// - string GetUrl(int idWell, int idCategory, int idFile, string dotExtention); - - /// - /// добавить метку на файл - /// - /// - /// - /// - /// - Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token); - - /// - /// пометить метку файла как удаленную - /// - /// - /// - /// - Task MarkFileMarkAsDeletedAsync(int idMark, CancellationToken token); - - /// - /// переместить файл - /// - /// - /// - /// - /// - /// - /// - /// - Task MoveAsync(int idWell, int? idUser, int idCategory, string destinationFileName, string srcFileFullName, CancellationToken token = default); - - /// - /// получить инфо о файле по метке - /// - /// - /// - /// - Task GetByMarkId(int idMark, CancellationToken token); - - /// - /// пометить метки файлов как удаленные - /// - /// - /// - /// - Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token); - - /// - /// Инфо о файле - /// - /// - /// - /// - Task> GetInfoByIdsAsync(List idsFile, CancellationToken token); - - /// - /// Получение файлов по скважине - /// - /// - /// - /// - Task> GetInfosByWellIdAsync(int idWell, CancellationToken token); - } -} diff --git a/AsbCloudApp/Services/IReduceSamplingService.cs b/AsbCloudApp/Services/IReduceSamplingService.cs new file mode 100644 index 00000000..a0220c58 --- /dev/null +++ b/AsbCloudApp/Services/IReduceSamplingService.cs @@ -0,0 +1,43 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; + +namespace AsbCloudApp.Services +{ +#nullable enable + /// + /// Делегат обновления состояния задачи + /// + /// + public delegate void OnJobProgressDelagate(JobDto job); + + /// + /// Сервис прореживания архива БД. + /// Удаляет часть телеметрии. + /// Понижает частоту записей в БД с 1 запись за 1 сек до 1 запись за N сек. + /// + public interface IReduceSamplingService + { + /// + /// Получить все задания. Задания удаляются минимум через 10 сек после выполнения, возможно позднее. + /// + /// Enumerable of JobDto or empty + IEnumerable GetJobs(); + + /// + /// Получить состояние определенной задачи + /// + /// + /// + JobDto? GetOrDefaultState(int idTelemetry); + + /// + /// Создать задачу прореживанию архива и добавить её в очередь на выполнение + /// + /// телеметрия для прореживания + /// колбек процесса выполнения + /// созданная задача или задача из очереди + /// задача добавлена == true + bool TryEnqueueRediceSamplingJob(int idTelemetry, OnJobProgressDelagate onProgress, out JobDto jobDto); + } +#nullable disable +} \ No newline at end of file diff --git a/AsbCloudDb/EFExtentions.cs b/AsbCloudDb/EFExtentions.cs index db66be04..3cbf3509 100644 --- a/AsbCloudDb/EFExtentions.cs +++ b/AsbCloudDb/EFExtentions.cs @@ -69,6 +69,15 @@ namespace AsbCloudDb return database.ExecuteSqlRawAsync(query, token); } + public static Task ExecInsertAsync(this Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade database, DbSet dbSet, IEnumerable items, CancellationToken token) + where T : class + { + var factory = GetQueryStringFactory(dbSet); + var query = factory.MakeInsertSql(items); + + return database.ExecuteSqlRawAsync(query, token); + } + public static string GetTableName(this DbSet dbSet) where T : class { @@ -108,6 +117,17 @@ namespace AsbCloudDb } return stat; } + + public static IQueryable SkipTake(this IQueryable query, int? skip, int? take) + { + if (skip > 0) + query = query.Skip((int)skip); + + if (take > 0) + query = query.Take((int)take); + + return query; + } } interface IQueryStringFactory { } @@ -154,6 +174,14 @@ namespace AsbCloudDb return builder.ToString(); } + public string MakeInsertSql(IEnumerable items) + { + var builder = new StringBuilder(insertHeader, 7); + BuildRows(builder, items); + builder.Append(';'); + return builder.ToString(); + } + private StringBuilder BuildRows(StringBuilder builder, IEnumerable items) { var list = items.ToList(); diff --git a/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.Designer.cs b/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.Designer.cs new file mode 100644 index 00000000..d42e6b13 --- /dev/null +++ b/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.Designer.cs @@ -0,0 +1,6543 @@ +// +using System; +using System.Text.Json; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + [DbContext(typeof(AsbCloudDbContext))] + [Migration("20221013040242_Delete_colums_table_t_telemetry_data_spin")] + partial class Delete_colums_table_t_telemetry_data_spin + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("Russian_Russia.1251") + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdDeposit") + .HasColumnType("integer") + .HasColumnName("id_deposit"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdDeposit"); + + b.ToTable("t_cluster"); + + b.HasComment("Кусты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCompanyType") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_company_type") + .HasComment("вид деятельности"); + + b.HasKey("Id"); + + b.HasIndex("IdCompanyType"); + + b.ToTable("t_company"); + + b.HasData( + new + { + Id = 1, + Caption = "ООО \"АСБ\"", + IdCompanyType = 3 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.HasKey("Id"); + + b.ToTable("t_company_type"); + + b.HasData( + new + { + Id = 1, + Caption = "Недрапользователь" + }, + new + { + Id = 2, + Caption = "Буровой подрядчик" + }, + new + { + Id = 3, + Caption = "Сервис автоматизации бурения" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ID скважины"); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("start_date") + .HasComment("Дата отчёта"); + + b.Property("Info") + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Список параметров для отчёта"); + + b.HasKey("IdWell", "StartDate") + .HasName("t_id_well_date_start_pk"); + + b.ToTable("t_daily_report"); + + b.HasComment("Ежедневные отчёты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.ToTable("t_deposit"); + + b.HasComment("Месторождение"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("Дата начала операции"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdReasonOfEnd") + .HasColumnType("integer") + .HasColumnName("id_reason_of_end") + .HasComment("Код признака окончания операции"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUsersAtStart") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя по телеметрии на момент начала операции"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value") + .HasComment("Ключевой показатель операции"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_detected_operation"); + + b.HasComment("автоматически определенные операции по телеметрии"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Имя"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("Отчество"); + + b.Property("Surname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("Фамилия"); + + b.HasKey("Id"); + + b.ToTable("t_driller"); + + b.HasComment("Бурильщик"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_max") + .HasComment("Максимальная нагрузка"); + + b.Property("AxialLoadMin") + .HasColumnType("double precision") + .HasColumnName("axial_load_min") + .HasComment("Минимальная нагрузка"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина окончания интервала"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Стартовая глубина"); + + b.Property("FlowMax") + .HasColumnType("double precision") + .HasColumnName("flow_max") + .HasComment("Максимальный расход"); + + b.Property("FlowMin") + .HasColumnType("double precision") + .HasColumnName("flow_min") + .HasComment("Минимальный расход"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("well_id") + .HasComment("Id скважины"); + + b.Property("IdWellOperationCategory") + .HasColumnType("integer") + .HasColumnName("id_operation_category") + .HasComment("Id типа операции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("PressureMax") + .HasColumnType("double precision") + .HasColumnName("pressure_max") + .HasComment("Максимальное давление"); + + b.Property("PressureMin") + .HasColumnType("double precision") + .HasColumnName("pressure_min") + .HasComment("Минимальное давление"); + + b.Property("RotorSpeedMax") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_max") + .HasComment("Максимальные обороты на ВСП"); + + b.Property("RotorSpeedMin") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_min") + .HasComment("Минимальные обороты на ВСП"); + + b.Property("RotorTorqueMax") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_max") + .HasComment("Максимальный момент на ВСП"); + + b.Property("RotorTorqueMin") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_min") + .HasComment("Минимальный момент на ВСП"); + + b.HasKey("Id"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellOperationCategory"); + + b.ToTable("t_drill_flow_chart"); + + b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdFileCategory") + .HasColumnType("integer") + .HasColumnName("id_file_category"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("Id"); + + b.HasIndex("IdFileCategory"); + + b.HasIndex("IdWell", "IdFileCategory") + .IsUnique(); + + b.ToTable("t_drilling_program_part"); + + b.HasComment("части программ бурения"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadAvg") + .HasColumnType("double precision") + .HasColumnName("axial_load_avg") + .HasComment("Средняя нагрузка"); + + b.Property("AxialLoadMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_max") + .HasComment("Максимальная нагрузка"); + + b.Property("AxialLoadMin") + .HasColumnType("double precision") + .HasColumnName("axial_load_min") + .HasComment("Минимальная нагрузка"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина окончания интервала"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Стартовая глубина"); + + b.Property("FlowAvg") + .HasColumnType("double precision") + .HasColumnName("flow_avg") + .HasComment("Средний расход"); + + b.Property("FlowMax") + .HasColumnType("double precision") + .HasColumnName("flow_max") + .HasComment("Максимальный расход"); + + b.Property("FlowMin") + .HasColumnType("double precision") + .HasColumnName("flow_min") + .HasComment("Минимальный расход"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("well_id") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Id с типом секции скважины"); + + b.Property("PressureAvg") + .HasColumnType("double precision") + .HasColumnName("pressure_avg") + .HasComment("Среднее давление"); + + b.Property("PressureMax") + .HasColumnType("double precision") + .HasColumnName("pressure_max") + .HasComment("Максимальное давление"); + + b.Property("PressureMin") + .HasColumnType("double precision") + .HasColumnName("pressure_min") + .HasComment("Минимальное давление"); + + b.Property("RotorSpeedAvg") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_avg") + .HasComment("Средние обороты на ВСП"); + + b.Property("RotorSpeedMax") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_max") + .HasComment("Максимальные обороты на ВСП"); + + b.Property("RotorSpeedMin") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_min") + .HasComment("Минимальные обороты на ВСП"); + + b.Property("RotorTorqueAvg") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_avg") + .HasComment("Средний момент на ВСП"); + + b.Property("RotorTorqueMax") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_max") + .HasComment("Максимальный момент на ВСП"); + + b.Property("RotorTorqueMin") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_min") + .HasComment("Минимальный момент на ВСП"); + + b.HasKey("Id"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_drill_params"); + + b.HasComment("Режим бурения в секции (диапазоны параметров бурения)"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_file_category"); + + b.HasComment("Категории файлов"); + + b.HasData( + new + { + Id = 1, + Name = "Растворный сервис", + ShortName = "fluidService" + }, + new + { + Id = 2, + Name = "Цементирование", + ShortName = "cement" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "nnb" + }, + new + { + Id = 4, + Name = "ГТИ", + ShortName = "gti" + }, + new + { + Id = 5, + Name = "Документы по скважине", + ShortName = "wellDocuments" + }, + new + { + Id = 6, + Name = "Супервайзер", + ShortName = "supervisor" + }, + new + { + Id = 7, + Name = "Мастер", + ShortName = "master" + }, + new + { + Id = 8, + Name = "Долотный сервис", + ShortName = "toolService" + }, + new + { + Id = 9, + Name = "Буровой подрядчик", + ShortName = "drillService" + }, + new + { + Id = 10, + Name = "Сервис по заканчиванию скважины", + ShortName = "closingService" + }, + new + { + Id = 12, + Name = "Рапорт", + ShortName = "report" + }, + new + { + Id = 1000, + Name = "Программа бурения" + }, + new + { + Id = 1001, + Name = "Задание от геологов" + }, + new + { + Id = 1002, + Name = "Профиль ствола скважины (ННБ)" + }, + new + { + Id = 1003, + Name = "Технологические расчеты (ННБ)" + }, + new + { + Id = 1004, + Name = "Долотная программа" + }, + new + { + Id = 1005, + Name = "Программа по растворам" + }, + new + { + Id = 1006, + Name = "Программа геофизических исследований" + }, + new + { + Id = 1007, + Name = "Планы спусков обсадных колонн" + }, + new + { + Id = 1008, + Name = "Программы цементирования обсадных колонн" + }, + new + { + Id = 10000, + Name = "Проект на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10001, + Name = "Программа на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10002, + Name = "Акт о начале бурения" + }, + new + { + Id = 10003, + Name = "План работ спуска и цементирования направления" + }, + new + { + Id = 10004, + Name = "Программа цементирования направления" + }, + new + { + Id = 10005, + Name = "Мера обсадных труб (направление)" + }, + new + { + Id = 10006, + Name = "Акт на выполненные работы по цементированию направления" + }, + new + { + Id = 10007, + Name = "Отчет по цементированию направления (график)" + }, + new + { + Id = 10008, + Name = "План работ спуска и цементирования кондуктора" + }, + new + { + Id = 10009, + Name = "Программа цементирования (кондуктор)" + }, + new + { + Id = 10010, + Name = "Мера обсадных труб (кондуктор)" + }, + new + { + Id = 10011, + Name = "Карта крепления кондуктора" + }, + new + { + Id = 10012, + Name = "Акт на выполненные работы по цементированию кондуктора" + }, + new + { + Id = 10013, + Name = "Отчет по цементированию кондуктора (график)" + }, + new + { + Id = 10014, + Name = "Акт о замере расстояния от стола ротора до муфты кондуктора" + }, + new + { + Id = 10015, + Name = "Акт опресовки цементного кольца за кондуктором" + }, + new + { + Id = 10016, + Name = "Акт опресовки ППГ с глухими плашками совместно с кондуктором" + }, + new + { + Id = 10017, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с кондуктором" + }, + new + { + Id = 10018, + Name = "План работ на крепление обсадной колонны (эк. колонна)" + }, + new + { + Id = 10019, + Name = "Программа цементирования (эк. колонна)" + }, + new + { + Id = 10020, + Name = "Мера труб эксплуатационной колонны" + }, + new + { + Id = 10021, + Name = "Карта по креплению скважины (эк. колонна)" + }, + new + { + Id = 10022, + Name = "Акт на установку пружинных центраторов" + }, + new + { + Id = 10023, + Name = "Отчет по цементированию эксплуатационной колонны (график)" + }, + new + { + Id = 10024, + Name = "Акт на выполненные работы по цементированию эксплуатационной колонны" + }, + new + { + Id = 10025, + Name = "Акт об испытании эк. колонны на герметичность (СТОП)" + }, + new + { + Id = 10026, + Name = "Акт опресовки ППГ с глухими плашками совместно с э/колонной" + }, + new + { + Id = 10027, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с э/колонной" + }, + new + { + Id = 10028, + Name = "Акт на вскрытие продуктивного пласта" + }, + new + { + Id = 10029, + Name = "Акт замера параметров раствора при бурении горизонтального участка" + }, + new + { + Id = 10030, + Name = "Разрешение на спуск «хвостовика» (телефонограмма)" + }, + new + { + Id = 10031, + Name = "План работ на спуск «хвостовика»" + }, + new + { + Id = 10032, + Name = "Акт готовности бурового и энергетического оборудования к спуску «хвостовика»" + }, + new + { + Id = 10033, + Name = "Акт шаблонировки ствола скважины перед спуском «хвостовика»" + }, + new + { + Id = 10034, + Name = "Мера обсадных труб (хвостовик)" + }, + new + { + Id = 10035, + Name = "Акт выполненных работ по спуску хвостовика с закачкой (нефти, солевого раствора" + }, + new + { + Id = 10036, + Name = "Акт о переводе скважины на тех. воду" + }, + new + { + Id = 10037, + Name = "Акт об окончании бурения" + }, + new + { + Id = 10038, + Name = "Акт на передачу скважины в освоение (КРС)" + }, + new + { + Id = 10039, + Name = "Акт на опресовку межколонного пространства с КРС" + }, + new + { + Id = 10040, + Name = "Акт на сдачу скважины в ЦДНГ" + }, + new + { + Id = 10041, + Name = "Паспорт ОУС (заполняется геологами)" + }, + new + { + Id = 10042, + Name = "Паспорт скважины (заполняется геологами)" + }, + new + { + Id = 10043, + Name = "Фактические данные бурения (вставляются в паспорт скважины)" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории файла"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Удален ли файл"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("file_size") + .HasComment("Размер файла"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_file_info"); + + b.HasComment("Файлы всех категорий"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created") + .HasComment("Дата совершенного действия"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла"); + + b.Property("IdMarkType") + .HasColumnType("integer") + .HasColumnName("id_mark_type") + .HasComment("0 - отклонен, 1 - согласован"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("id пользователя"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Помечен ли файл как удаленный"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdUser"); + + b.ToTable("t_file_mark"); + + b.HasComment("Действия с файлами."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasColumnType("jsonb") + .HasColumnName("data") + .HasComment("Данные таблицы последних данных"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Пометка удаленным"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp") + .HasComment("время добавления"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_measure"); + + b.HasComment("Таблица c данными для вкладки 'Последние данные'"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_measure_category"); + + b.HasComment("Категория последних данных"); + + b.HasData( + new + { + Id = 1, + Name = "Показатели бурового раствора", + ShortName = "Раствор" + }, + new + { + Id = 2, + Name = "Шламограмма", + ShortName = "Шламограмма" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "ННБ" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Конечная глубина"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Старотовая глубина"); + + b.Property("IdOperationCategory") + .HasColumnType("integer") + .HasColumnName("id_operation_category") + .HasComment("Ид категории операции"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Ид скважины"); + + b.Property("StandardValue") + .HasColumnType("double precision") + .HasColumnName("standard_value") + .HasComment("Нормативный показатель"); + + b.Property("TargetValue") + .HasColumnType("double precision") + .HasColumnName("target_value") + .HasComment("Целевой показатель"); + + b.HasKey("Id"); + + b.HasIndex("IdOperationCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_operationvalue"); + + b.HasComment("Целевые/нормативные показатели операции"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description") + .HasComment("Краткое описание"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_permission"); + + b.HasComment("Разрешения на доступ к данным"); + + b.HasData( + new + { + Id = 100, + Description = "Разрешение удалять админ. Кусты", + Name = "AdminCluster.delete" + }, + new + { + Id = 101, + Description = "Разрешение редактировать админ. Кусты", + Name = "AdminCluster.edit" + }, + new + { + Id = 102, + Description = "Разрешение просматривать админ. Кусты", + Name = "AdminCluster.get" + }, + new + { + Id = 103, + Description = "Разрешение удалять админ. Компании", + Name = "AdminCompany.delete" + }, + new + { + Id = 104, + Description = "Разрешение редактировать админ. Компании", + Name = "AdminCompany.edit" + }, + new + { + Id = 105, + Description = "Разрешение просматривать админ. Компании", + Name = "AdminCompany.get" + }, + new + { + Id = 106, + Description = "Разрешение удалять админ. Типы компаний", + Name = "AdminCompanyType.delete" + }, + new + { + Id = 107, + Description = "Разрешение редактировать админ. Типы компаний", + Name = "AdminCompanyType.edit" + }, + new + { + Id = 108, + Description = "Разрешение просматривать админ. Типы компаний", + Name = "AdminCompanyType.get" + }, + new + { + Id = 109, + Description = "Разрешение удалять админ. Месторождения", + Name = "AdminDeposit.delete" + }, + new + { + Id = 110, + Description = "Разрешение редактировать админ. Месторождения", + Name = "AdminDeposit.edit" + }, + new + { + Id = 111, + Description = "Разрешение просматривать админ. Месторождения", + Name = "AdminDeposit.get" + }, + new + { + Id = 112, + Description = "Разрешение удалять админ. Разрешения", + Name = "AdminPermission.delete" + }, + new + { + Id = 113, + Description = "Разрешение редактировать админ. Разрешения", + Name = "AdminPermission.edit" + }, + new + { + Id = 114, + Description = "Разрешение просматривать админ. Разрешения", + Name = "AdminPermission.get" + }, + new + { + Id = 115, + Description = "Разрешение удалять админ. Телеметрию", + Name = "AdminTelemetry.delete" + }, + new + { + Id = 116, + Description = "Разрешение редактировать админ. Телеметрию", + Name = "AdminTelemetry.edit" + }, + new + { + Id = 117, + Description = "Разрешение просматривать админ. Телеметрию", + Name = "AdminTelemetry.get" + }, + new + { + Id = 118, + Description = "Разрешение удалять админ. Пользователей", + Name = "AdminUser.delete" + }, + new + { + Id = 119, + Description = "Разрешение редактировать админ. Пользователей", + Name = "AdminUser.edit" + }, + new + { + Id = 120, + Description = "Разрешение просматривать админ. Пользователей", + Name = "AdminUser.get" + }, + new + { + Id = 121, + Description = "Разрешение удалять админ. Роли пользователей", + Name = "AdminUserRole.delete" + }, + new + { + Id = 122, + Description = "Разрешение редактировать админ. Роли пользователей", + Name = "AdminUserRole.edit" + }, + new + { + Id = 123, + Description = "Разрешение просматривать админ. Роли пользователей", + Name = "AdminUserRole.get" + }, + new + { + Id = 124, + Description = "Разрешение удалять админ. Скважины", + Name = "AdminWell.delete" + }, + new + { + Id = 125, + Description = "Разрешение редактировать админ. Скважины", + Name = "AdminWell.edit" + }, + new + { + Id = 126, + Description = "Разрешение просматривать админ. Скважины", + Name = "AdminWell.get" + }, + new + { + Id = 127, + Description = "Разрешение удалять админ. Подсистемы", + Name = "AdminSubsytem.delete" + }, + new + { + Id = 128, + Description = "Разрешение редактировать админ. Подсистемы", + Name = "AdminSubsytem.edit" + }, + new + { + Id = 129, + Description = "Разрешение просматривать админ. Подсистемы", + Name = "AdminSubsytem.get" + }, + new + { + Id = 200, + Description = "Разрешение редактировать 0", + Name = "Auth.edit" + }, + new + { + Id = 201, + Description = "Разрешение просматривать 0", + Name = "Auth.get" + }, + new + { + Id = 202, + Description = "Разрешение просматривать Кусты", + Name = "Cluster.get" + }, + new + { + Id = 203, + Description = "Разрешение просматривать Месторождения", + Name = "Deposit.get" + }, + new + { + Id = 204, + Description = "Разрешение удалять РТК", + Name = "DrillFlowChart.delete" + }, + new + { + Id = 205, + Description = "Разрешение редактировать РТК", + Name = "DrillFlowChart.edit" + }, + new + { + Id = 206, + Description = "Разрешение просматривать РТК", + Name = "DrillFlowChart.get" + }, + new + { + Id = 207, + Description = "Разрешение удалять Программу бурения", + Name = "DrillingProgram.delete" + }, + new + { + Id = 208, + Description = "Разрешение редактировать Программу бурения", + Name = "DrillingProgram.edit" + }, + new + { + Id = 209, + Description = "Разрешение просматривать Программу бурения", + Name = "DrillingProgram.get" + }, + new + { + Id = 210, + Description = "Разрешение удалять Режимы бурения", + Name = "DrillParams.delete" + }, + new + { + Id = 211, + Description = "Разрешение редактировать Режимы бурения", + Name = "DrillParams.edit" + }, + new + { + Id = 212, + Description = "Разрешение просматривать Режимы бурения", + Name = "DrillParams.get" + }, + new + { + Id = 213, + Description = "Разрешение удалять Файлы", + Name = "File.delete" + }, + new + { + Id = 214, + Description = "Разрешение редактировать Файлы", + Name = "File.edit" + }, + new + { + Id = 215, + Description = "Разрешение просматривать Файлы", + Name = "File.get" + }, + new + { + Id = 216, + Description = "Разрешение удалять Измерения", + Name = "Measure.delete" + }, + new + { + Id = 217, + Description = "Разрешение редактировать Измерения", + Name = "Measure.edit" + }, + new + { + Id = 218, + Description = "Разрешение просматривать Измерения", + Name = "Measure.get" + }, + new + { + Id = 219, + Description = "Разрешение просматривать Сообщения телеметрии", + Name = "Message.get" + }, + new + { + Id = 220, + Description = "Разрешение просматривать Статистику по операциям", + Name = "OperationStat.get" + }, + new + { + Id = 221, + Description = "Разрешение редактировать Рапорта", + Name = "Report.edit" + }, + new + { + Id = 222, + Description = "Разрешение просматривать Рапорта", + Name = "Report.get" + }, + new + { + Id = 223, + Description = "Разрешение просматривать админ. Системная статистика", + Name = "RequestTracker.get" + }, + new + { + Id = 224, + Description = "Разрешение удалять Рекомендации уставок", + Name = "Setpoints.delete" + }, + new + { + Id = 225, + Description = "Разрешение редактировать Рекомендации уставок", + Name = "Setpoints.edit" + }, + new + { + Id = 226, + Description = "Разрешение просматривать Рекомендации уставок", + Name = "Setpoints.get" + }, + new + { + Id = 227, + Description = "Разрешение редактировать Телеметрии", + Name = "Telemetry.edit" + }, + new + { + Id = 228, + Description = "Разрешение просматривать Анализ телеметрии", + Name = "TelemetryAnalytics.get" + }, + new + { + Id = 229, + Description = "Разрешение редактировать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.edit" + }, + new + { + Id = 230, + Description = "Разрешение просматривать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.get" + }, + new + { + Id = 231, + Description = "Разрешение редактировать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.edit" + }, + new + { + Id = 232, + Description = "Разрешение просматривать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.get" + }, + new + { + Id = 233, + Description = "Разрешение редактировать Скважины", + Name = "Well.edit" + }, + new + { + Id = 234, + Description = "Разрешение просматривать Скважины", + Name = "Well.get" + }, + new + { + Id = 235, + Description = "Разрешение редактировать Композитные скважины", + Name = "WellComposite.edit" + }, + new + { + Id = 236, + Description = "Разрешение просматривать Композитные скважины", + Name = "WellComposite.get" + }, + new + { + Id = 237, + Description = "Разрешение удалять Операции по скважинам", + Name = "WellOperation.delete" + }, + new + { + Id = 238, + Description = "Разрешение редактировать Операции по скважинам", + Name = "WellOperation.edit" + }, + new + { + Id = 239, + Description = "Разрешение просматривать Операции по скважинам", + Name = "WellOperation.get" + }, + new + { + Id = 240, + Description = "Разрешение редактировать Файлы категории 1 (Растворный сервис)", + Name = "File.edit1" + }, + new + { + Id = 241, + Description = "Разрешение редактировать Файлы категории 2 (Цементирование)", + Name = "File.edit2" + }, + new + { + Id = 242, + Description = "Разрешение редактировать Файлы категории 3 (ННБ)", + Name = "File.edit3" + }, + new + { + Id = 243, + Description = "Разрешение редактировать Файлы категории 4 (ГТИ)", + Name = "File.edit4" + }, + new + { + Id = 244, + Description = "Разрешение редактировать Файлы категории 5 (Документы по скважине)", + Name = "File.edit5" + }, + new + { + Id = 245, + Description = "Разрешение редактировать Файлы категории 6 (Супервайзер)", + Name = "File.edit6" + }, + new + { + Id = 246, + Description = "Разрешение редактировать Файлы категории 7 (Мастер)", + Name = "File.edit7" + }, + new + { + Id = 247, + Description = "Разрешение редактировать Файлы категории 8 (Долотный сервис)", + Name = "File.edit8" + }, + new + { + Id = 248, + Description = "Разрешение редактировать Файлы категории 9 (Буровой подрядчик)", + Name = "File.edit9" + }, + new + { + Id = 249, + Description = "Разрешение редактировать Файлы категории 10 (Сервис по заканчиванию скважины)", + Name = "File.edit10" + }, + new + { + Id = 250, + Description = "Разрешение редактировать Файлы категории 11 (Рапорт)", + Name = "File.edit11" + }, + new + { + Id = 251, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit12" + }, + new + { + Id = 252, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit13" + }, + new + { + Id = 253, + Description = "Разрешение редактировать Файлы категории 13", + Name = "File.edit14" + }, + new + { + Id = 254, + Description = "Разрешение редактировать Файлы категории 14", + Name = "File.edit15" + }, + new + { + Id = 255, + Description = "Разрешение редактировать Файлы категории 15", + Name = "File.edit16" + }, + new + { + Id = 256, + Description = "Разрешение редактировать Файлы категории 16", + Name = "File.edit17" + }, + new + { + Id = 257, + Description = "Разрешение редактировать Файлы категории 17", + Name = "File.edit18" + }, + new + { + Id = 258, + Description = "Разрешение редактировать Файлы категории 18", + Name = "File.edit19" + }, + new + { + Id = 259, + Description = "Разрешение редактировать Файлы категории 19", + Name = "File.edit20" + }, + new + { + Id = 260, + Description = "Разрешение редактировать Файлы категории 20", + Name = "File.edit21" + }, + new + { + Id = 261, + Description = "Разрешение редактировать Файлы категории 21", + Name = "File.edit22" + }, + new + { + Id = 262, + Description = "Разрешение редактировать Файлы категории 22", + Name = "File.edit23" + }, + new + { + Id = 263, + Description = "Разрешение редактировать Файлы категории 23", + Name = "File.edit24" + }, + new + { + Id = 264, + Description = "Разрешение редактировать Файлы категории 24", + Name = "File.edit25" + }, + new + { + Id = 265, + Description = "Разрешение редактировать Файлы категории 25", + Name = "File.edit26" + }, + new + { + Id = 266, + Description = "Разрешение редактировать Файлы категории 26", + Name = "File.edit27" + }, + new + { + Id = 267, + Description = "Разрешение редактировать Файлы категории 27", + Name = "File.edit28" + }, + new + { + Id = 268, + Description = "Разрешение редактировать Файлы категории 28", + Name = "File.edit29" + }, + new + { + Id = 269, + Description = "Разрешение редактировать Файлы категории 29", + Name = "File.edit30" + }, + new + { + Id = 380, + Description = "Разрешение просматривать список бурильщиков", + Name = "Driller.get" + }, + new + { + Id = 381, + Description = "Разрешение редактировать бурильщика", + Name = "Driller.edit" + }, + new + { + Id = 382, + Description = "Разрешение удалять бурильщик", + Name = "Driller.delete" + }, + new + { + Id = 383, + Description = "Разрешение просматривать графики бурильщиков", + Name = "Schedule.get" + }, + new + { + Id = 384, + Description = "Разрешение редактировать график бурильщика", + Name = "Schedule.edit" + }, + new + { + Id = 385, + Description = "Разрешение удалять график бурильщика", + Name = "Schedule.delete" + }, + new + { + Id = 386, + Description = "Разрешение просматривать суточный рапорт", + Name = "DailyReport.get" + }, + new + { + Id = 387, + Description = "Разрешение редактировать суточный рапорт", + Name = "DailyReport.edit" + }, + new + { + Id = 388, + Description = "Разрешение просматривать авто. определенные операции", + Name = "DetectedOperation.get" + }, + new + { + Id = 389, + Description = "Разрешение просматривать целевые значения", + Name = "OperationValue.get" + }, + new + { + Id = 390, + Description = "Разрешение редактировать целевые значения", + Name = "OperationValue.edit" + }, + new + { + Id = 391, + Description = "Разрешение удалять целевые значения", + Name = "OperationValue.delete" + }, + new + { + Id = 400, + Description = "Разрешение просматривать инфо по wits параметрам", + Name = "WitsInfo.get" + }, + new + { + Id = 401, + Description = "Разрешение просматривать WITS record 1", + Name = "WitsRecord1.get" + }, + new + { + Id = 407, + Description = "Разрешение просматривать WITS record 7", + Name = "WitsRecord7.get" + }, + new + { + Id = 408, + Description = "Разрешение просматривать WITS record 8", + Name = "WitsRecord8.get" + }, + new + { + Id = 450, + Description = "Разрешение просматривать WITS record 50", + Name = "WitsRecord50.get" + }, + new + { + Id = 460, + Description = "Разрешение просматривать WITS record 60", + Name = "WitsRecord60.get" + }, + new + { + Id = 461, + Description = "Разрешение просматривать WITS record 61", + Name = "WitsRecord61.get" + }, + new + { + Id = 500, + Description = "Разрешение удалять Категорий документов файлов", + Name = "FileCategory.delete" + }, + new + { + Id = 501, + Description = "Разрешение редактировать Категорий документов файлов", + Name = "FileCategory.edit" + }, + new + { + Id = 502, + Description = "Разрешение просматривать Категорий документов файлов", + Name = "FileCategory.get" + }, + new + { + Id = 503, + Description = "Разрешение удалять Дело скважины", + Name = "WellFinalDocuments.delete" + }, + new + { + Id = 504, + Description = "Разрешение редактировать Дело скважины", + Name = "WellFinalDocuments.edit" + }, + new + { + Id = 505, + Description = "Разрешение просматривать Дело скважины", + Name = "WellFinalDocuments.get" + }, + new + { + Id = 506, + Description = "Разрешение редактировать ответственных за загрузку файла Дело скважины", + Name = "WellFinalDocuments.editPublisher" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("IdCompany", "IdWell"); + + b.HasIndex("IdWell"); + + b.ToTable("t_relation_company_well"); + + b.HasComment("отношение скважин и компаний"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdDrillingProgramPart") + .HasColumnType("integer") + .HasColumnName("id_drilling_program_part"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_role") + .HasComment("1 - publisher, 2 - approver"); + + b.HasKey("IdUser", "IdDrillingProgramPart") + .HasName("t_relation_user_drilling_program_part_pk"); + + b.HasIndex("IdDrillingProgramPart"); + + b.ToTable("t_relation_user_drilling_program_part"); + + b.HasComment("Отношение пользователей и частей ПБ"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdPermission") + .HasColumnType("integer") + .HasColumnName("id_permission"); + + b.HasKey("IdUserRole", "IdPermission"); + + b.HasIndex("IdPermission"); + + b.ToTable("t_relation_user_role_permission"); + + b.HasComment("Отношение ролей пользователей и разрешений доступа"); + + b.HasData( + new + { + IdUserRole = 1100, + IdPermission = 102 + }, + new + { + IdUserRole = 1100, + IdPermission = 111 + }, + new + { + IdUserRole = 1101, + IdPermission = 101 + }, + new + { + IdUserRole = 1101, + IdPermission = 100 + }, + new + { + IdUserRole = 1102, + IdPermission = 105 + }, + new + { + IdUserRole = 1102, + IdPermission = 108 + }, + new + { + IdUserRole = 1103, + IdPermission = 104 + }, + new + { + IdUserRole = 1103, + IdPermission = 103 + }, + new + { + IdUserRole = 1104, + IdPermission = 108 + }, + new + { + IdUserRole = 1105, + IdPermission = 107 + }, + new + { + IdUserRole = 1105, + IdPermission = 106 + }, + new + { + IdUserRole = 1106, + IdPermission = 111 + }, + new + { + IdUserRole = 1107, + IdPermission = 110 + }, + new + { + IdUserRole = 1107, + IdPermission = 109 + }, + new + { + IdUserRole = 1108, + IdPermission = 114 + }, + new + { + IdUserRole = 1109, + IdPermission = 113 + }, + new + { + IdUserRole = 1109, + IdPermission = 112 + }, + new + { + IdUserRole = 1110, + IdPermission = 123 + }, + new + { + IdUserRole = 1110, + IdPermission = 114 + }, + new + { + IdUserRole = 1111, + IdPermission = 122 + }, + new + { + IdUserRole = 1111, + IdPermission = 121 + }, + new + { + IdUserRole = 1112, + IdPermission = 117 + }, + new + { + IdUserRole = 1113, + IdPermission = 105 + }, + new + { + IdUserRole = 1113, + IdPermission = 123 + }, + new + { + IdUserRole = 1113, + IdPermission = 120 + }, + new + { + IdUserRole = 1114, + IdPermission = 119 + }, + new + { + IdUserRole = 1114, + IdPermission = 118 + }, + new + { + IdUserRole = 1114, + IdPermission = 200 + }, + new + { + IdUserRole = 1115, + IdPermission = 223 + }, + new + { + IdUserRole = 1116, + IdPermission = 105 + }, + new + { + IdUserRole = 1116, + IdPermission = 102 + }, + new + { + IdUserRole = 1116, + IdPermission = 117 + }, + new + { + IdUserRole = 1116, + IdPermission = 126 + }, + new + { + IdUserRole = 1117, + IdPermission = 125 + }, + new + { + IdUserRole = 1117, + IdPermission = 124 + }, + new + { + IdUserRole = 1200, + IdPermission = 203 + }, + new + { + IdUserRole = 1200, + IdPermission = 230 + }, + new + { + IdUserRole = 1201, + IdPermission = 202 + }, + new + { + IdUserRole = 1201, + IdPermission = 203 + }, + new + { + IdUserRole = 1201, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 203 + }, + new + { + IdUserRole = 1202, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 236 + }, + new + { + IdUserRole = 1202, + IdPermission = 212 + }, + new + { + IdUserRole = 1203, + IdPermission = 235 + }, + new + { + IdUserRole = 1204, + IdPermission = 202 + }, + new + { + IdUserRole = 1204, + IdPermission = 203 + }, + new + { + IdUserRole = 1205, + IdPermission = 215 + }, + new + { + IdUserRole = 1206, + IdPermission = 203 + }, + new + { + IdUserRole = 1206, + IdPermission = 206 + }, + new + { + IdUserRole = 1207, + IdPermission = 205 + }, + new + { + IdUserRole = 1208, + IdPermission = 218 + }, + new + { + IdUserRole = 1209, + IdPermission = 217 + }, + new + { + IdUserRole = 1210, + IdPermission = 203 + }, + new + { + IdUserRole = 1210, + IdPermission = 230 + }, + new + { + IdUserRole = 1210, + IdPermission = 219 + }, + new + { + IdUserRole = 1211, + IdPermission = 203 + }, + new + { + IdUserRole = 1211, + IdPermission = 220 + }, + new + { + IdUserRole = 1211, + IdPermission = 239 + }, + new + { + IdUserRole = 1212, + IdPermission = 238 + }, + new + { + IdUserRole = 1212, + IdPermission = 237 + }, + new + { + IdUserRole = 1213, + IdPermission = 203 + }, + new + { + IdUserRole = 1213, + IdPermission = 239 + }, + new + { + IdUserRole = 1213, + IdPermission = 212 + }, + new + { + IdUserRole = 1214, + IdPermission = 211 + }, + new + { + IdUserRole = 1214, + IdPermission = 210 + }, + new + { + IdUserRole = 1215, + IdPermission = 203 + }, + new + { + IdUserRole = 1215, + IdPermission = 222 + }, + new + { + IdUserRole = 1216, + IdPermission = 221 + }, + new + { + IdUserRole = 1217, + IdPermission = 226 + }, + new + { + IdUserRole = 1218, + IdPermission = 225 + }, + new + { + IdUserRole = 1218, + IdPermission = 224 + }, + new + { + IdUserRole = 1219, + IdPermission = 203 + }, + new + { + IdUserRole = 1219, + IdPermission = 206 + }, + new + { + IdUserRole = 1219, + IdPermission = 230 + }, + new + { + IdUserRole = 1219, + IdPermission = 232 + }, + new + { + IdUserRole = 1220, + IdPermission = 203 + }, + new + { + IdUserRole = 1220, + IdPermission = 228 + }, + new + { + IdUserRole = 1221, + IdPermission = 202 + }, + new + { + IdUserRole = 1221, + IdPermission = 203 + }, + new + { + IdUserRole = 1221, + IdPermission = 220 + }, + new + { + IdUserRole = 1221, + IdPermission = 234 + }, + new + { + IdUserRole = 1501, + IdPermission = 214 + }, + new + { + IdUserRole = 1501, + IdPermission = 213 + }, + new + { + IdUserRole = 1502, + IdPermission = 207 + }, + new + { + IdUserRole = 1502, + IdPermission = 208 + }, + new + { + IdUserRole = 2000, + IdPermission = 205 + }, + new + { + IdUserRole = 2000, + IdPermission = 204 + }, + new + { + IdUserRole = 2000, + IdPermission = 245 + }, + new + { + IdUserRole = 2001, + IdPermission = 244 + }, + new + { + IdUserRole = 2001, + IdPermission = 245 + }, + new + { + IdUserRole = 2002, + IdPermission = 244 + }, + new + { + IdUserRole = 2002, + IdPermission = 246 + }, + new + { + IdUserRole = 2002, + IdPermission = 237 + }, + new + { + IdUserRole = 2002, + IdPermission = 238 + }, + new + { + IdUserRole = 2003, + IdPermission = 240 + }, + new + { + IdUserRole = 2003, + IdPermission = 217 + }, + new + { + IdUserRole = 2003, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 242 + }, + new + { + IdUserRole = 2004, + IdPermission = 217 + }, + new + { + IdUserRole = 2004, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 205 + }, + new + { + IdUserRole = 2004, + IdPermission = 204 + }, + new + { + IdUserRole = 2005, + IdPermission = 247 + }, + new + { + IdUserRole = 2005, + IdPermission = 205 + }, + new + { + IdUserRole = 2005, + IdPermission = 204 + }, + new + { + IdUserRole = 2006, + IdPermission = 243 + }, + new + { + IdUserRole = 2006, + IdPermission = 205 + }, + new + { + IdUserRole = 2006, + IdPermission = 204 + }, + new + { + IdUserRole = 2007, + IdPermission = 241 + }, + new + { + IdUserRole = 2007, + IdPermission = 205 + }, + new + { + IdUserRole = 2007, + IdPermission = 204 + }, + new + { + IdUserRole = 1, + IdPermission = 500 + }, + new + { + IdUserRole = 1, + IdPermission = 501 + }, + new + { + IdUserRole = 1, + IdPermission = 502 + }, + new + { + IdUserRole = 1, + IdPermission = 503 + }, + new + { + IdUserRole = 1, + IdPermission = 504 + }, + new + { + IdUserRole = 1, + IdPermission = 505 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdInclude") + .HasColumnType("integer") + .HasColumnName("id_include_user_role"); + + b.HasKey("Id", "IdInclude") + .HasName("t_relation_user_role_user_role_pk"); + + b.HasIndex("IdInclude"); + + b.ToTable("t_relation_user_role_user_role"); + + b.HasComment("Отношение ролей к ролям"); + + b.HasData( + new + { + Id = 1101, + IdInclude = 1100 + }, + new + { + Id = 1103, + IdInclude = 1102 + }, + new + { + Id = 1105, + IdInclude = 1104 + }, + new + { + Id = 1107, + IdInclude = 1106 + }, + new + { + Id = 1109, + IdInclude = 1108 + }, + new + { + Id = 1111, + IdInclude = 1110 + }, + new + { + Id = 1114, + IdInclude = 1113 + }, + new + { + Id = 1117, + IdInclude = 1116 + }, + new + { + Id = 1203, + IdInclude = 1202 + }, + new + { + Id = 1207, + IdInclude = 1206 + }, + new + { + Id = 1209, + IdInclude = 1208 + }, + new + { + Id = 1212, + IdInclude = 1211 + }, + new + { + Id = 1214, + IdInclude = 1213 + }, + new + { + Id = 1216, + IdInclude = 1215 + }, + new + { + Id = 1218, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1200 + }, + new + { + Id = 2000, + IdInclude = 1201 + }, + new + { + Id = 2000, + IdInclude = 1202 + }, + new + { + Id = 2000, + IdInclude = 1204 + }, + new + { + Id = 2000, + IdInclude = 1205 + }, + new + { + Id = 2000, + IdInclude = 1206 + }, + new + { + Id = 2000, + IdInclude = 1208 + }, + new + { + Id = 2000, + IdInclude = 1210 + }, + new + { + Id = 2000, + IdInclude = 1211 + }, + new + { + Id = 2000, + IdInclude = 1213 + }, + new + { + Id = 2000, + IdInclude = 1215 + }, + new + { + Id = 2000, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1219 + }, + new + { + Id = 2000, + IdInclude = 1220 + }, + new + { + Id = 2000, + IdInclude = 1221 + }, + new + { + Id = 2000, + IdInclude = 1500 + }, + new + { + Id = 2000, + IdInclude = 1501 + }, + new + { + Id = 2000, + IdInclude = 1502 + }, + new + { + Id = 2001, + IdInclude = 1500 + }, + new + { + Id = 2001, + IdInclude = 1501 + }, + new + { + Id = 2001, + IdInclude = 1502 + }, + new + { + Id = 2002, + IdInclude = 1500 + }, + new + { + Id = 2002, + IdInclude = 1501 + }, + new + { + Id = 2002, + IdInclude = 1502 + }, + new + { + Id = 2003, + IdInclude = 1500 + }, + new + { + Id = 2003, + IdInclude = 1501 + }, + new + { + Id = 2003, + IdInclude = 1502 + }, + new + { + Id = 2004, + IdInclude = 1500 + }, + new + { + Id = 2004, + IdInclude = 1501 + }, + new + { + Id = 2004, + IdInclude = 1502 + }, + new + { + Id = 2005, + IdInclude = 1500 + }, + new + { + Id = 2005, + IdInclude = 1501 + }, + new + { + Id = 2005, + IdInclude = 1502 + }, + new + { + Id = 2006, + IdInclude = 1500 + }, + new + { + Id = 2006, + IdInclude = 1501 + }, + new + { + Id = 2006, + IdInclude = 1502 + }, + new + { + Id = 2007, + IdInclude = 1500 + }, + new + { + Id = 2007, + IdInclude = 1501 + }, + new + { + Id = 2007, + IdInclude = 1502 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.HasKey("IdUser", "IdUserRole"); + + b.HasIndex("IdUserRole"); + + b.ToTable("t_relation_user_user_role"); + + b.HasComment("Отношение пользователей и ролей"); + + b.HasData( + new + { + IdUser = 1, + IdUserRole = 1 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Begin") + .HasColumnType("timestamp with time zone") + .HasColumnName("begin"); + + b.Property("End") + .HasColumnType("timestamp with time zone") + .HasColumnName("end") + .HasComment("timestamp with time zone"); + + b.Property("Format") + .HasColumnType("integer") + .HasColumnName("format") + .HasComment("Формат отчета"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла-родителя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("Step") + .HasColumnType("integer") + .HasColumnName("step") + .HasComment("размер шага в секундах"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdWell"); + + b.ToTable("t_report_property"); + + b.HasComment("Отчеты с данными по буровым"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DrillEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_end") + .HasComment("Конец вахты"); + + b.Property("DrillStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_start") + .HasComment("Начало вахты"); + + b.Property("IdDriller") + .HasColumnType("integer") + .HasColumnName("id_driller") + .HasComment("Идентификатор бурильщика"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Идентификатор скважины"); + + b.Property("ShiftEnd") + .HasColumnType("time without time zone") + .HasColumnName("shift_end") + .HasComment("Конец смены"); + + b.Property("ShiftStart") + .HasColumnType("time without time zone") + .HasColumnName("shift_start") + .HasComment("Начало смены"); + + b.HasKey("Id"); + + b.HasIndex("IdDriller"); + + b.HasIndex("IdWell"); + + b.ToTable("t_schedule"); + + b.HasComment("График работы бурильщика"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("комментарий для оператора"); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("id_state") + .HasComment("0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("ObsolescenceSec") + .HasColumnType("integer") + .HasColumnName("obsolescence") + .HasComment("сек. до устаревания"); + + b.Property("Setpoints") + .HasColumnType("jsonb") + .HasColumnName("setpoint_set") + .HasComment("Набор уставок"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdWell"); + + b.ToTable("t_setpoints_rquest"); + + b.HasComment("Запросы на изменение уставок панели оператора"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.Subsystem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("t_subsystem"); + + b.HasComment("Описание подсистем"); + + b.HasData( + new + { + Id = 1, + Description = "Совместная работа режимов \"Бурение в роторе\" и \"Бурение в слайде\"", + Name = "АКБ" + }, + new + { + Id = 2, + Description = "Алгоритм поиска оптимальных параметров бурения САУБ", + Name = "MSE" + }, + new + { + Id = 65536, + Description = "Spin master", + Name = "Spin master" + }, + new + { + Id = 65537, + Description = "Torque master", + Name = "Torque master" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("дата/время выключения подсистемы"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("дата/время включения подсистемы"); + + b.Property("DepthEnd") + .HasColumnType("real") + .HasColumnName("depth_end") + .HasComment("глубина забоя на момент выключения подсистемы"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depth_start") + .HasComment("глубина забоя на момент включения подсистемы"); + + b.Property("IdSubsystem") + .HasColumnType("integer") + .HasColumnName("id_subsystem"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("ИД телеметрии по которой выдается информация"); + + b.HasKey("Id"); + + b.HasIndex("IdSubsystem"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_subsystem_operation_time"); + + b.HasComment("наработки подсистем"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Info") + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Информация с панели о скважине"); + + b.Property("RemoteUid") + .HasColumnType("text") + .HasColumnName("remote_uid") + .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); + + b.Property("TimeZone") + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index"); + + b.ToTable("t_telemetry"); + + b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("AxialLoad") + .HasColumnType("real") + .HasColumnName("axial_load") + .HasComment("Осевая нагрузка"); + + b.Property("AxialLoadLimitMax") + .HasColumnType("real") + .HasColumnName("axial_load_limit_max") + .HasComment("Осевая нагрузка. Аварийная макс."); + + b.Property("AxialLoadSp") + .HasColumnType("real") + .HasColumnName("axial_load_sp") + .HasComment("Осевая нагрузка. Задание"); + + b.Property("BitDepth") + .HasColumnType("real") + .HasColumnName("bit_depth") + .HasComment("Положение инструмента"); + + b.Property("BlockPosition") + .HasColumnType("real") + .HasColumnName("block_position") + .HasComment("Высота талевого блока"); + + b.Property("BlockPositionMax") + .HasColumnType("real") + .HasColumnName("block_position_max") + .HasComment("Талевый блок. Макс положение"); + + b.Property("BlockPositionMin") + .HasColumnType("real") + .HasColumnName("block_position_min") + .HasComment("Талевый блок. Мин положение"); + + b.Property("BlockSpeed") + .HasColumnType("real") + .HasColumnName("block_speed") + .HasComment("Скорость талевого блока"); + + b.Property("BlockSpeedSp") + .HasColumnType("real") + .HasColumnName("block_speed_sp") + .HasComment("Скорости талевого блока. Задание"); + + b.Property("BlockSpeedSpDevelop") + .HasColumnType("real") + .HasColumnName("block_speed_sp_develop") + .HasComment("Талевый блок. Задание скорости для проработки"); + + b.Property("BlockSpeedSpRotor") + .HasColumnType("real") + .HasColumnName("block_speed_sp_rotor") + .HasComment("Талевый блок. Задание скорости для роторного бурения"); + + b.Property("BlockSpeedSpSlide") + .HasColumnType("real") + .HasColumnName("block_speed_sp_slide") + .HasComment("Талевый блок. Задание скорости для режима слайда"); + + b.Property("Flow") + .HasColumnType("real") + .HasColumnName("flow") + .HasComment("Расход"); + + b.Property("FlowDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("flow_delta_limit_max") + .HasComment("Расход. Аварийный макс."); + + b.Property("FlowIdle") + .HasColumnType("real") + .HasColumnName("flow_idle") + .HasComment("Расход. Холостой ход"); + + b.Property("HookWeight") + .HasColumnType("real") + .HasColumnName("hook_weight") + .HasComment("Вес на крюке"); + + b.Property("HookWeightIdle") + .HasColumnType("real") + .HasColumnName("hook_weight_idle") + .HasComment("Вес на крюке. Холостой ход"); + + b.Property("HookWeightLimitMax") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_max") + .HasComment("Вес на крюке. Затяжка"); + + b.Property("HookWeightLimitMin") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_min") + .HasComment("Вес на крюке. Посадка"); + + b.Property("IdFeedRegulator") + .HasColumnType("smallint") + .HasColumnName("id_feed_regulator") + .HasComment("Текущий критерий бурения"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Пользователь САУБ"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Режим САУБ"); + + b.Property("Mse") + .HasColumnType("real") + .HasColumnName("mse") + .HasComment("MSE"); + + b.Property("MseState") + .HasColumnType("smallint") + .HasColumnName("mse_state") + .HasComment("Текущее состояние работы MSE"); + + b.Property("Pressure") + .HasColumnType("real") + .HasColumnName("pressure") + .HasComment("Давление"); + + b.Property("PressureDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("pressure_delta_limit_max") + .HasComment("Давление дифф. Аварийное макс."); + + b.Property("PressureIdle") + .HasColumnType("real") + .HasColumnName("pressure_idle") + .HasComment("Давление. Холостой ход"); + + b.Property("PressureSp") + .HasColumnType("real") + .HasColumnName("pressure_sp") + .HasComment("Давление. Задание"); + + b.Property("PressureSpDevelop") + .HasColumnType("real") + .HasColumnName("pressure_sp_develop") + .HasComment("Давление. Задание для проработки"); + + b.Property("PressureSpRotor") + .HasColumnType("real") + .HasColumnName("pressure_sp_rotor") + .HasComment("Давление. Задание для роторного бурения"); + + b.Property("PressureSpSlide") + .HasColumnType("real") + .HasColumnName("pressure_sp_slide") + .HasComment("Давление. Задание для режима слайда"); + + b.Property("RotorSpeed") + .HasColumnType("real") + .HasColumnName("rotor_speed") + .HasComment("Обороты ротора"); + + b.Property("RotorTorque") + .HasColumnType("real") + .HasColumnName("rotor_torque") + .HasComment("Момент на роторе"); + + b.Property("RotorTorqueIdle") + .HasColumnType("real") + .HasColumnName("rotor_torque_idle") + .HasComment("Момент на роторе. Холостой ход"); + + b.Property("RotorTorqueLimitMax") + .HasColumnType("real") + .HasColumnName("rotor_torque_limit_max") + .HasComment("Момент на роторе. Аварийный макс."); + + b.Property("RotorTorqueSp") + .HasColumnType("real") + .HasColumnName("rotor_torque_sp") + .HasComment("Момент на роторе. Задание"); + + b.Property("WellDepth") + .HasColumnType("real") + .HasColumnName("well_depth") + .HasComment("Глубина забоя"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_saub"); + + b.HasComment("набор основных данных по SAUB"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaubStat", b => + { + b.Property("Count") + .HasColumnType("bigint") + .HasColumnName("count_items"); + + b.Property("DateMax") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_max"); + + b.Property("DateMin") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_min"); + + b.Property("DepthMax") + .HasColumnType("real") + .HasColumnName("depth_max"); + + b.Property("DepthMin") + .HasColumnType("real") + .HasColumnName("depth_min"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.ToView("mw_telemetry_datas_saub_stat"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Выбранный режим управления"); + + b.Property("PositionRight") + .HasColumnType("real") + .HasColumnName("position_right") + .HasComment("Крайний правый угол осцилляции"); + + b.Property("PositionZero") + .HasColumnType("real") + .HasColumnName("position_zero") + .HasComment("Нулевая позиция осцилляции"); + + b.Property("RevolsLeftLimit") + .HasColumnType("real") + .HasColumnName("revols_left_limit") + .HasComment("Ограничение числа оборотов влево"); + + b.Property("RevolsLeftTotal") + .HasColumnType("real") + .HasColumnName("revols_left_total") + .HasComment("Суммарное количество оборотов влево"); + + b.Property("RevolsRightLimit") + .HasColumnType("real") + .HasColumnName("revols_right_limit") + .HasComment("Ограничение числа оборотов вправо"); + + b.Property("RevolsRightTotal") + .HasColumnType("real") + .HasColumnName("revols_right_total") + .HasComment("Суммарное количество оборотов вправо"); + + b.Property("SpeedLeftSp") + .HasColumnType("real") + .HasColumnName("speed_left_sp") + .HasComment("Заданная скорость вращения влево"); + + b.Property("SpeedRightSp") + .HasColumnType("real") + .HasColumnName("speed_right_sp") + .HasComment("Заданная скорость вращения вправо"); + + b.Property("State") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("Переменная этапа"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_spin"); + + b.HasComment("набор основных данных по SpinMaster"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.Property("MessageTemplate") + .HasColumnType("text") + .HasColumnName("message_template"); + + b.HasKey("IdTelemetry", "IdEvent"); + + b.ToTable("t_telemetry_event"); + + b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Arg0") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg0") + .HasComment("Аргумент №0 для вставки в шаблон сообщения"); + + b.Property("Arg1") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg1"); + + b.Property("Arg2") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg2"); + + b.Property("Arg3") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg3"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdTelemetryUser") + .HasColumnType("integer") + .HasColumnName("id_telemetry_user") + .HasComment("Пользователь панели отправляющей телеметрию. не пользователь облака."); + + b.Property("WellDepth") + .HasColumnType("double precision") + .HasColumnName("well_depth"); + + b.HasKey("Id"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_telemetry_message"); + + b.HasComment("Сообщения на буровых"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic"); + + b.Property("Surname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname"); + + b.HasKey("IdTelemetry", "IdUser"); + + b.ToTable("t_telemetry_user"); + + b.HasComment("Пользователи панели САУБ. Для сообщений."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email") + .HasComment("должность"); + + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdState") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("состояние:\n100 - удален"); + + b.Property("Login") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("login"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("имя"); + + b.Property("PasswordHash") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("password_hash") + .HasComment("соленый хэш пароля.\nпервые 5 символов - соль"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("отчество"); + + b.Property("Phone") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("phone") + .HasComment("номер телефона"); + + b.Property("Position") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("position") + .HasComment("email"); + + b.Property("Surname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("фамилия"); + + b.HasKey("Id"); + + b.HasIndex("IdCompany"); + + b.HasIndex("Login") + .IsUnique(); + + b.ToTable("t_user"); + + b.HasComment("Пользователи облака"); + + b.HasData( + new + { + Id = 1, + IdCompany = 1, + Login = "dev", + Name = "Разработчик", + PasswordHash = "Vlcj|4fa529103dde7ff72cfe76185f344d4aa87931f8e1b2044e8a7739947c3d18923464eaad93843e4f809c5e126d013072" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0-роль из стандартной матрицы, \n1-специальная роль для какого-либо пользователя"); + + b.HasKey("Id"); + + b.ToTable("t_user_role"); + + b.HasComment("Роли пользователей в системе"); + + b.HasData( + new + { + Id = 1, + Caption = "root", + IdType = 1 + }, + new + { + Id = 1100, + Caption = "admin_cluster.view", + IdType = 1 + }, + new + { + Id = 1101, + Caption = "admin_cluster.edit", + IdType = 1 + }, + new + { + Id = 1102, + Caption = "admin_company.view", + IdType = 1 + }, + new + { + Id = 1103, + Caption = "admin_company.edit", + IdType = 1 + }, + new + { + Id = 1104, + Caption = "admin_company_type.view", + IdType = 1 + }, + new + { + Id = 1105, + Caption = "admin_company_type.edit", + IdType = 1 + }, + new + { + Id = 1106, + Caption = "admin_deposit.view", + IdType = 1 + }, + new + { + Id = 1107, + Caption = "admin_deposit.edit", + IdType = 1 + }, + new + { + Id = 1108, + Caption = "admin_permission.view", + IdType = 1 + }, + new + { + Id = 1109, + Caption = "admin_permission.edit", + IdType = 1 + }, + new + { + Id = 1110, + Caption = "admin_role.view", + IdType = 1 + }, + new + { + Id = 1111, + Caption = "admin_role.edit", + IdType = 1 + }, + new + { + Id = 1112, + Caption = "admin_telemetry.view", + IdType = 1 + }, + new + { + Id = 1113, + Caption = "admin_user.view", + IdType = 1 + }, + new + { + Id = 1114, + Caption = "admin_user.edit", + IdType = 1 + }, + new + { + Id = 1115, + Caption = "admin_visit_log.view", + IdType = 1 + }, + new + { + Id = 1116, + Caption = "admin_well.view", + IdType = 1 + }, + new + { + Id = 1117, + Caption = "admin_well.edit", + IdType = 1 + }, + new + { + Id = 1200, + Caption = "archive.view", + IdType = 1 + }, + new + { + Id = 1201, + Caption = "cluster.view", + IdType = 1 + }, + new + { + Id = 1202, + Caption = "composite.view", + IdType = 1 + }, + new + { + Id = 1203, + Caption = "composite.edit", + IdType = 1 + }, + new + { + Id = 1204, + Caption = "deposit.view", + IdType = 1 + }, + new + { + Id = 1205, + Caption = "document.view", + IdType = 1 + }, + new + { + Id = 1206, + Caption = "drillProcessFlow.view", + IdType = 1 + }, + new + { + Id = 1207, + Caption = "drillProcessFlow.edit", + IdType = 1 + }, + new + { + Id = 1208, + Caption = "measure.view", + IdType = 1 + }, + new + { + Id = 1209, + Caption = "measure.edit", + IdType = 1 + }, + new + { + Id = 1210, + Caption = "message.view", + IdType = 1 + }, + new + { + Id = 1211, + Caption = "operations.view", + IdType = 1 + }, + new + { + Id = 1212, + Caption = "operations.edit", + IdType = 1 + }, + new + { + Id = 1213, + Caption = "params.view", + IdType = 1 + }, + new + { + Id = 1214, + Caption = "params.edit", + IdType = 1 + }, + new + { + Id = 1215, + Caption = "report.view", + IdType = 1 + }, + new + { + Id = 1216, + Caption = "report.edit", + IdType = 1 + }, + new + { + Id = 1217, + Caption = "setpoints.view", + IdType = 1 + }, + new + { + Id = 1218, + Caption = "setpoints.edit", + IdType = 1 + }, + new + { + Id = 1219, + Caption = "telemetry.view", + IdType = 1 + }, + new + { + Id = 1220, + Caption = "telemetryAnalysis.view", + IdType = 1 + }, + new + { + Id = 1221, + Caption = "well.view", + IdType = 1 + }, + new + { + Id = 1500, + Caption = "Просмотр всего", + IdType = 1 + }, + new + { + Id = 1501, + Caption = "file.edit", + IdType = 1 + }, + new + { + Id = 1502, + Caption = "drillingProgram.edit", + IdType = 1 + }, + new + { + Id = 2000, + Caption = "Заказчик", + IdType = 0 + }, + new + { + Id = 2001, + Caption = "Супервайзер", + IdType = 0 + }, + new + { + Id = 2002, + Caption = "Буровой подрядчик", + IdType = 0 + }, + new + { + Id = 2003, + Caption = "Растворщик", + IdType = 0 + }, + new + { + Id = 2004, + Caption = "Телеметрист", + IdType = 0 + }, + new + { + Id = 2005, + Caption = "Долотный сервис", + IdType = 0 + }, + new + { + Id = 2006, + Caption = "ГТИ", + IdType = 0 + }, + new + { + Id = 2007, + Caption = "Цементирование", + IdType = 0 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Key") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("key") + .HasComment("Ключ настроек пользователя"); + + b.Property("Value") + .HasColumnType("jsonb") + .HasColumnName("setting_value") + .HasComment("Значение настроек пользователя"); + + b.HasKey("IdUser", "Key"); + + b.ToTable("t_user_settings"); + + b.HasComment("настройки интерфейса пользователя"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCluster") + .HasColumnType("integer") + .HasColumnName("id_cluster"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("state") + .HasComment("0 - неизвестно, 1 - в работе, 2 - завершена"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdWellType") + .HasColumnType("integer") + .HasColumnName("id_well_type"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdCluster"); + + b.HasIndex("IdTelemetry") + .IsUnique(); + + b.HasIndex("IdWellType"); + + b.ToTable("t_well"); + + b.HasComment("скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины получателя"); + + b.Property("IdWellSrc") + .HasColumnType("integer") + .HasColumnName("id_well_src") + .HasComment("Id скважины композита"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции композита"); + + b.HasKey("IdWell", "IdWellSrc", "IdWellSectionType"); + + b.HasIndex("IdWellSectionType"); + + b.HasIndex("IdWellSrc"); + + b.ToTable("t_well_composite"); + + b.HasComment("Композитная скважина"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.HasKey("IdWell", "IdUser", "IdCategory") + .HasName("t_well_final_documents_pk"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdUser"); + + b.ToTable("t_well_final_documents"); + + b.HasComment("Дело скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryInfo") + .HasColumnType("text") + .HasColumnName("category_info") + .HasComment("Доп. информация к выбраной категории"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("DurationHours") + .HasColumnType("double precision") + .HasColumnName("duration_hours") + .HasComment("Продолжительность, часы"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0 = План или 1 = Факт"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции скважины"); + + b.HasKey("Id"); + + b.HasIndex("DateStart"); + + b.HasIndex("DepthEnd"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_well_operation"); + + b.HasComment("Данные по операциям на скважине"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Code") + .HasColumnType("integer") + .HasColumnName("code") + .HasComment("Код операции"); + + b.Property("KeyValueName") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("key_value_name") + .HasComment("Название ключевого показателя операции"); + + b.Property("KeyValueUnits") + .HasMaxLength(16) + .HasColumnType("character varying(16)") + .HasColumnName("key_value_units") + .HasComment("Единицы измерения ключевого показателя операции"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории операции"); + + b.HasKey("Id"); + + b.ToTable("t_well_operation_category"); + + b.HasComment("Справочник операций на скважине"); + + b.HasData( + new + { + Id = 1, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Невозможно определить операцию" + }, + new + { + Id = 2, + Code = 0, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Роторное бурение" + }, + new + { + Id = 3, + Code = 0, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Слайдирование" + }, + new + { + Id = 4, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем с проработкой" + }, + new + { + Id = 5, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск с проработкой" + }, + new + { + Id = 6, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем с промывкой" + }, + new + { + Id = 7, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск с промывкой" + }, + new + { + Id = 8, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск в скважину" + }, + new + { + Id = 9, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск с вращением" + }, + new + { + Id = 10, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем из скважины" + }, + new + { + Id = 11, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем с вращением" + }, + new + { + Id = 12, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка в покое" + }, + new + { + Id = 13, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка с вращением" + }, + new + { + Id = 14, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Удержание в клиньях" + }, + new + { + Id = 15, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Неподвижное состояние" + }, + new + { + Id = 16, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вращение без циркуляции" + }, + new + { + Id = 17, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "На поверхности" + }, + new + { + Id = 18, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка перед наращиванием" + }, + new + { + Id = 19, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка перед наращиванием" + }, + new + { + Id = 20, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка перед наращиванием" + }, + new + { + Id = 21, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Статический замер телесистемы" + }, + new + { + Id = 22, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка" + }, + new + { + Id = 23, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка при бурении" + }, + new + { + Id = 1001, + Code = 0, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение" + }, + new + { + Id = 1002, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГИС" + }, + new + { + Id = 1003, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГФР" + }, + new + { + Id = 1004, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Монтаж ПВО" + }, + new + { + Id = 1005, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Демонтаж ПВО" + }, + new + { + Id = 1006, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Установка ФА" + }, + new + { + Id = 1007, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Оборудование устья" + }, + new + { + Id = 1008, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ОЗЦ" + }, + new + { + Id = 1011, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Начало цикла строительства скважины" + }, + new + { + Id = 1012, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Окончание цикла строительства скважины" + }, + new + { + Id = 1013, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ПВО" + }, + new + { + Id = 1014, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка Ц.К." + }, + new + { + Id = 1015, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ВЗД" + }, + new + { + Id = 1016, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перевод скв на другой тип промывочной жидкости" + }, + new + { + Id = 1017, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перезапись каротажа" + }, + new + { + Id = 1018, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перетяжка талевого каната" + }, + new + { + Id = 1019, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наращивание, промывка" + }, + new + { + Id = 1020, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем инструмента" + }, + new + { + Id = 1021, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем инструмента с промывкой" + }, + new + { + Id = 1022, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обратная проработка" + }, + new + { + Id = 1023, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка инструмента с мостков" + }, + new + { + Id = 1024, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подготовительные работы" + }, + new + { + Id = 1025, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка КНБК" + }, + new + { + Id = 1026, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разборка КНБК" + }, + new + { + Id = 1027, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка" + }, + new + { + Id = 1028, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промежуточная промывка" + }, + new + { + Id = 1029, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Прокачка пачек" + }, + new + { + Id = 1030, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разбуривание тех.оснастки" + }, + new + { + Id = 1031, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт" + }, + new + { + Id = 1032, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента" + }, + new + { + Id = 1033, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента с промывкой" + }, + new + { + Id = 1034, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Прямая проработка" + }, + new + { + Id = 1035, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Принудительная проработка" + }, + new + { + Id = 1037, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тех СПО-подъем" + }, + new + { + Id = 1038, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тех СПО-спуск" + }, + new + { + Id = 1039, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Техническое обслуживание" + }, + new + { + Id = 1040, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Цементаж" + }, + new + { + Id = 1041, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка ствола" + }, + new + { + Id = 1042, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Геологическое осложнение" + }, + new + { + Id = 1043, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "НПВ" + }, + new + { + Id = 1044, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ВМР" + }, + new + { + Id = 1045, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Прочее" + }, + new + { + Id = 1046, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск КНБК" + }, + new + { + Id = 1047, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем КНБК" + }, + new + { + Id = 1048, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск ОК" + }, + new + { + Id = 1050, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка при спуске ОК" + }, + new + { + Id = 1051, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Замер ТС" + }, + new + { + Id = 1052, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тех. отстой" + }, + new + { + Id = 1053, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Циркуляция и Обработка БР" + }, + new + { + Id = 1054, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Срезка ствола" + }, + new + { + Id = 1055, + Code = 0, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные работы" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_well_section_type"); + + b.HasComment("конструкция секции скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Пилотный ствол" + }, + new + { + Id = 2, + Caption = "Направление" + }, + new + { + Id = 3, + Caption = "Кондуктор" + }, + new + { + Id = 4, + Caption = "Эксплуатационная колонна" + }, + new + { + Id = 5, + Caption = "Транспортный ствол" + }, + new + { + Id = 6, + Caption = "Хвостовик" + }, + new + { + Id = 7, + Caption = "Пилотный ствол 2" + }, + new + { + Id = 8, + Caption = "Направление 2" + }, + new + { + Id = 9, + Caption = "Кондуктор 2" + }, + new + { + Id = 10, + Caption = "Эксплуатационная колонна 2" + }, + new + { + Id = 11, + Caption = "Транспортный ствол 2" + }, + new + { + Id = 12, + Caption = "Хвостовик 2" + }, + new + { + Id = 13, + Caption = "Пилотный ствол 3" + }, + new + { + Id = 14, + Caption = "Направление 3" + }, + new + { + Id = 15, + Caption = "Кондуктор 3" + }, + new + { + Id = 16, + Caption = "Эксплуатационная колонна 3" + }, + new + { + Id = 17, + Caption = "Транспортный ствол 3" + }, + new + { + Id = 18, + Caption = "Хвостовик 3" + }, + new + { + Id = 19, + Caption = "Пилотный ствол 4" + }, + new + { + Id = 20, + Caption = "Направление 4" + }, + new + { + Id = 21, + Caption = "Кондуктор 4" + }, + new + { + Id = 22, + Caption = "Эксплуатационная колонна 4" + }, + new + { + Id = 23, + Caption = "Транспортный ствол 4" + }, + new + { + Id = 24, + Caption = "Хвостовик 4" + }, + new + { + Id = 25, + Caption = "Пилотный ствол 5" + }, + new + { + Id = 26, + Caption = "Направление 5" + }, + new + { + Id = 27, + Caption = "Кондуктор 5" + }, + new + { + Id = 28, + Caption = "Эксплуатационная колонна 5" + }, + new + { + Id = 29, + Caption = "Транспортный ствол 5" + }, + new + { + Id = 30, + Caption = "Хвостовик 5" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_well_type"); + + b.HasComment("конструкция скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Наклонно-направленная" + }, + new + { + Id = 2, + Caption = "Горизонтальная" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.RecordBase", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Actcod") + .HasColumnType("smallint") + .HasColumnName("ACTCOD"); + + b.Property("Date") + .HasColumnType("integer") + .HasColumnName("DATE"); + + b.Property("Recid") + .HasColumnType("smallint") + .HasColumnName("RECID"); + + b.Property("Seqid") + .HasColumnType("integer") + .HasColumnName("SEQID"); + + b.Property("Stknum") + .HasColumnType("smallint") + .HasColumnName("STKNUM"); + + b.Property("Time") + .HasColumnType("integer") + .HasColumnName("TIME"); + + b.Property("Wellid") + .HasColumnType("text") + .HasColumnName("WELLID"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_wits_base"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Blkpos") + .HasColumnType("real") + .HasColumnName("BLKPOS"); + + b.Property("Chkp") + .HasColumnType("real") + .HasColumnName("CHKP"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptretm") + .HasColumnType("real") + .HasColumnName("DEPTRETM"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Gasa") + .HasColumnType("real") + .HasColumnName("GASA"); + + b.Property("Hkla") + .HasColumnType("real") + .HasColumnName("HKLA"); + + b.Property("Hklx") + .HasColumnType("real") + .HasColumnName("HKLX"); + + b.Property("Lagstks") + .HasColumnType("smallint") + .HasColumnName("LAGSTKS"); + + b.Property("Mcia") + .HasColumnType("real") + .HasColumnName("MCIA"); + + b.Property("Mcoa") + .HasColumnType("real") + .HasColumnName("MCOA"); + + b.Property("Mdia") + .HasColumnType("real") + .HasColumnName("MDIA"); + + b.Property("Mdoa") + .HasColumnType("real") + .HasColumnName("MDOA"); + + b.Property("Mfia") + .HasColumnType("real") + .HasColumnName("MFIA"); + + b.Property("Mfoa") + .HasColumnType("real") + .HasColumnName("MFOA"); + + b.Property("Mfop") + .HasColumnType("smallint") + .HasColumnName("MFOP"); + + b.Property("Mtia") + .HasColumnType("real") + .HasColumnName("MTIA"); + + b.Property("Mtoa") + .HasColumnType("real") + .HasColumnName("MTOA"); + + b.Property("Ropa") + .HasColumnType("real") + .HasColumnName("ROPA"); + + b.Property("Rpma") + .HasColumnType("smallint") + .HasColumnName("RPMA"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spm1") + .HasColumnType("smallint") + .HasColumnName("SPM1"); + + b.Property("Spm2") + .HasColumnType("smallint") + .HasColumnName("SPM2"); + + b.Property("Spm3") + .HasColumnType("smallint") + .HasColumnName("SPM3"); + + b.Property("Sppa") + .HasColumnType("real") + .HasColumnName("SPPA"); + + b.Property("Stkc") + .HasColumnType("integer") + .HasColumnName("STKC"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.Property("Torqa") + .HasColumnType("real") + .HasColumnName("TORQA"); + + b.Property("Torqx") + .HasColumnType("real") + .HasColumnName("TORQX"); + + b.Property("Tvolact") + .HasColumnType("real") + .HasColumnName("TVOLACT"); + + b.Property("Tvolcact") + .HasColumnType("real") + .HasColumnName("TVOLCACT"); + + b.Property("Woba") + .HasColumnType("real") + .HasColumnName("WOBA"); + + b.Property("Wobx") + .HasColumnType("real") + .HasColumnName("WOBX"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_1"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("DeptmeasGdpMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_GDP_mc"); + + b.Property("DeptmeasMcrstat") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_MCRSTAT"); + + b.Property("DeptmeasRa33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33_mc"); + + b.Property("DeptmeasRa33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F2_mc"); + + b.Property("DeptmeasRa33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F4_mc"); + + b.Property("DeptmeasRp33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33_mc"); + + b.Property("DeptmeasRp33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F2_mc"); + + b.Property("DeptmeasRp33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F4_mc"); + + b.Property("DeptmeasSlvlMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_SLVL_mc"); + + b.Property("GdpMc") + .HasColumnType("real") + .HasColumnName("GDP_mc"); + + b.Property("Mcrstat") + .HasColumnType("real") + .HasColumnName("MCRSTAT"); + + b.Property("Ra33Mc") + .HasColumnType("real") + .HasColumnName("RA33_mc"); + + b.Property("Ra33f2Mc") + .HasColumnType("real") + .HasColumnName("RA33F2_mc"); + + b.Property("Ra33f4Mc") + .HasColumnType("real") + .HasColumnName("RA33F4_mc"); + + b.Property("Rp33Mc") + .HasColumnType("real") + .HasColumnName("RP33_mc"); + + b.Property("Rp33f2Mc") + .HasColumnType("real") + .HasColumnName("RP33F2_mc"); + + b.Property("Rp33f4Mc") + .HasColumnType("real") + .HasColumnName("RP33F4_mc"); + + b.Property("SlvlMc") + .HasColumnType("real") + .HasColumnName("SLVL_mc"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_50"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Btot") + .HasColumnType("real") + .HasColumnName("Btot"); + + b.Property("Bx") + .HasColumnType("real") + .HasColumnName("Bx"); + + b.Property("By") + .HasColumnType("real") + .HasColumnName("By"); + + b.Property("Bz") + .HasColumnType("real") + .HasColumnName("Bz"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Gtot") + .HasColumnType("real") + .HasColumnName("Gtot"); + + b.Property("Gx") + .HasColumnType("real") + .HasColumnName("Gx"); + + b.Property("Gy") + .HasColumnType("real") + .HasColumnName("Gy"); + + b.Property("Gz") + .HasColumnType("real") + .HasColumnName("Gz"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_60"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Att06h") + .HasColumnType("real") + .HasColumnName("ATT06H"); + + b.Property("Att06l") + .HasColumnType("real") + .HasColumnName("ATT06L"); + + b.Property("Att10h") + .HasColumnType("real") + .HasColumnName("ATT10H"); + + b.Property("Att10l") + .HasColumnType("real") + .HasColumnName("ATT10L"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Phl1f1") + .HasColumnType("real") + .HasColumnName("PHL1F1"); + + b.Property("Phl1f2") + .HasColumnType("real") + .HasColumnName("PHL1F2"); + + b.Property("Phl2f1") + .HasColumnType("real") + .HasColumnName("PHL2F1"); + + b.Property("Phl2f2") + .HasColumnType("real") + .HasColumnName("PHL2F2"); + + b.Property("Status") + .HasColumnType("real") + .HasColumnName("Status"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_61"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptsvym") + .HasColumnType("real") + .HasColumnName("DEPTSVYM"); + + b.Property("Deptsvyv") + .HasColumnType("real") + .HasColumnName("DEPTSVYV"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Svyazc") + .HasColumnType("real") + .HasColumnName("SVYAZC"); + + b.Property("Svyazu") + .HasColumnType("real") + .HasColumnName("SVYAZU"); + + b.Property("Svydls") + .HasColumnType("real") + .HasColumnName("SVYDLS"); + + b.Property("Svyew") + .HasColumnType("real") + .HasColumnName("SVYEW"); + + b.Property("Svygtf") + .HasColumnType("real") + .HasColumnName("SVYGTF"); + + b.Property("Svyinc") + .HasColumnType("real") + .HasColumnName("SVYINC"); + + b.Property("Svymtf") + .HasColumnType("real") + .HasColumnName("SVYMTF"); + + b.Property("Svyns") + .HasColumnType("real") + .HasColumnName("SVYNS"); + + b.Property("Svytype") + .HasColumnType("text") + .HasColumnName("SVYTYPE"); + + b.Property("Svywalk") + .HasColumnType("real") + .HasColumnName("SVYWALK"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_7"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptcalm") + .HasColumnType("real") + .HasColumnName("DEPTCALM"); + + b.Property("Deptcalv") + .HasColumnType("real") + .HasColumnName("DEPTCALV"); + + b.Property("Deptfdm") + .HasColumnType("real") + .HasColumnName("DEPTFDM"); + + b.Property("Deptfdv") + .HasColumnType("real") + .HasColumnName("DEPTFDV"); + + b.Property("Deptgr1m") + .HasColumnType("real") + .HasColumnName("DEPTGR1M"); + + b.Property("Deptgr1v") + .HasColumnType("real") + .HasColumnName("DEPTGR1V"); + + b.Property("Deptgr2m") + .HasColumnType("real") + .HasColumnName("DEPTGR2M"); + + b.Property("Deptgr2v") + .HasColumnType("real") + .HasColumnName("DEPTGR2V"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptp1m") + .HasColumnType("real") + .HasColumnName("DEPTP1M"); + + b.Property("Deptp1v") + .HasColumnType("real") + .HasColumnName("DEPTP1V"); + + b.Property("Deptp2m") + .HasColumnType("real") + .HasColumnName("DEPTP2M"); + + b.Property("Deptp2v") + .HasColumnType("real") + .HasColumnName("DEPTP2V"); + + b.Property("Deptrs1m") + .HasColumnType("real") + .HasColumnName("DEPTRS1M"); + + b.Property("Deptrs1v") + .HasColumnType("real") + .HasColumnName("DEPTRS1V"); + + b.Property("Deptrs2m") + .HasColumnType("real") + .HasColumnName("DEPTRS2M"); + + b.Property("Deptrs2v") + .HasColumnType("real") + .HasColumnName("DEPTRS2V"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Mclp") + .HasColumnType("real") + .HasColumnName("MCLP"); + + b.Property("Mfd") + .HasColumnType("real") + .HasColumnName("MFD"); + + b.Property("Mffp") + .HasColumnType("real") + .HasColumnName("MFFP"); + + b.Property("Mfpp") + .HasColumnType("real") + .HasColumnName("MFPP"); + + b.Property("Mfrann") + .HasColumnType("real") + .HasColumnName("MFRANN"); + + b.Property("Mfrpipe") + .HasColumnType("real") + .HasColumnName("MFRPIPE"); + + b.Property("Mftann") + .HasColumnType("real") + .HasColumnName("MFTANN"); + + b.Property("Mftpipe") + .HasColumnType("real") + .HasColumnName("MFTPIPE"); + + b.Property("Mg1") + .HasColumnType("real") + .HasColumnName("MG1"); + + b.Property("Mg1c") + .HasColumnType("real") + .HasColumnName("MG1C"); + + b.Property("Mg2") + .HasColumnType("real") + .HasColumnName("MG2"); + + b.Property("Mg2c") + .HasColumnType("real") + .HasColumnName("MG2C"); + + b.Property("Mpo1") + .HasColumnType("real") + .HasColumnName("MPO1"); + + b.Property("Mpo2") + .HasColumnType("real") + .HasColumnName("MPO2"); + + b.Property("Mr1") + .HasColumnType("real") + .HasColumnName("MR1"); + + b.Property("Mr1c") + .HasColumnType("real") + .HasColumnName("MR1C"); + + b.Property("Mr2") + .HasColumnType("real") + .HasColumnName("MR2"); + + b.Property("Mr2c") + .HasColumnType("real") + .HasColumnName("MR2C"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spare6") + .HasColumnType("real") + .HasColumnName("SPARE6"); + + b.Property("Spare7") + .HasColumnType("real") + .HasColumnName("SPARE7"); + + b.Property("Spare8") + .HasColumnType("real") + .HasColumnName("SPARE8"); + + b.Property("Spare9") + .HasColumnType("real") + .HasColumnName("SPARE9"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_8"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.HasOne("AsbCloudDb.Model.Deposit", "Deposit") + .WithMany("Clusters") + .HasForeignKey("IdDeposit") + .HasConstraintName("t_cluster_t_deposit_id_fk"); + + b.Navigation("Deposit"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType") + .WithMany("Companies") + .HasForeignKey("IdCompanyType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdFileCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("DrillingProgramParts") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("DrillParamsCollection") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_drill_params_t_well_section_type_id_fk"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany("Files") + .HasForeignKey("IdAuthor"); + + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "FileInfo") + .WithMany("FileMarks") + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_file_mark_t_file_info_fk"); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("FileMarks") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_user_t_file_mark_fk"); + + b.Navigation("FileInfo"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.HasOne("AsbCloudDb.Model.MeasureCategory", "Category") + .WithMany("Measures") + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdOperationCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_company_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_well_id_fk"); + + b.Navigation("Company"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.DrillingProgramPart", "DrillingProgramPart") + .WithMany("RelatedUsers") + .HasForeignKey("IdDrillingProgramPart") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DrillingProgramPart"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.HasOne("AsbCloudDb.Model.Permission", "Permission") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdPermission") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.HasOne("AsbCloudDb.Model.UserRole", "Role") + .WithMany("RelationUserRoleUserRoles") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "IncludeRole") + .WithMany() + .HasForeignKey("IdInclude") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("IncludeRole"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "File") + .WithMany() + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.HasOne("AsbCloudDb.Model.Driller", "Driller") + .WithMany("Schedule") + .HasForeignKey("IdDriller") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_schedule_t_driller_id_driller"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Driller"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany() + .HasForeignKey("IdAuthor") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.HasOne("AsbCloudDb.Model.Subsystems.Subsystem", "Subsystem") + .WithMany() + .HasForeignKey("IdSubsystem") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Subsystem"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSaub") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_saub_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSpin") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_spin_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Events") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_event_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Messages") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_messages_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Users") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_user_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("Users") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("t_user_t_company_id_fk"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.HasOne("AsbCloudDb.Model.Cluster", "Cluster") + .WithMany("Wells") + .HasForeignKey("IdCluster") + .HasConstraintName("t_well_t_cluster_id_fk"); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithOne("Well") + .HasForeignKey("AsbCloudDb.Model.Well", "IdTelemetry") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("t_well_t_telemetry_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellType", "WellType") + .WithMany("Wells") + .HasForeignKey("IdWellType"); + + b.Navigation("Cluster"); + + b.Navigation("Telemetry"); + + b.Navigation("WellType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellComposites") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellComposites") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_section_type_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "WellSrc") + .WithMany("WellCompositeSrcs") + .HasForeignKey("IdWellSrc") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_src_t_well_id_fk"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + + b.Navigation("WellSrc"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "Category") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellOperations") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellOperations") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record1", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record50", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record60", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record61", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record7", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record8", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Navigation("Wells"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Navigation("RelationCompaniesWells"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Navigation("Companies"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Navigation("Clusters"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Navigation("Schedule"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Navigation("RelatedUsers"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Navigation("FileMarks"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Navigation("Measures"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Navigation("RelationUserRolePermissions"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Navigation("DataSaub"); + + b.Navigation("DataSpin"); + + b.Navigation("Events"); + + b.Navigation("Messages"); + + b.Navigation("Users"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Navigation("FileMarks"); + + b.Navigation("Files"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Navigation("RelationUserRolePermissions"); + + b.Navigation("RelationUserRoleUserRoles"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Navigation("DrillingProgramParts"); + + b.Navigation("RelationCompaniesWells"); + + b.Navigation("WellCompositeSrcs"); + + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Navigation("DrillParamsCollection"); + + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Navigation("Wells"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.cs b/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.cs new file mode 100644 index 00000000..0ebf1f57 --- /dev/null +++ b/AsbCloudDb/Migrations/20221013040242_Delete_colums_table_t_telemetry_data_spin.cs @@ -0,0 +1,577 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + public partial class Delete_colums_table_t_telemetry_data_spin : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "break_angle_k", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "break_angle_left", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "encoder_resolution", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "pid_mux_torque_left_limit", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "ratio", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "reverse_k_torque", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "reverse_speed_sp_zero_time", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "rotor_torque_avg", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_from", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_from_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_from_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_from_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_from_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_to", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_to_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_to_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_to_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_speed_sp_to_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_from", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_from_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_from_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_from_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_from_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_to", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_to_err", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_to_max", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_to_min", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "top_drive_torque_sp_to_offset", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "torque_left_limit", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "torque_ramp_time", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "torque_right_limit", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "torque_starting", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_left_once_by_angle", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_left_once_by_revols", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_left_once_by_torque", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_right_once_by_angle", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_right_once_by_revols", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "turn_right_once_by_torque", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "unlock_by_sector_out", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "ver", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "w2800", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "w2808", + table: "t_telemetry_data_spin"); + + migrationBuilder.DropColumn( + name: "w2810", + table: "t_telemetry_data_spin"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "break_angle_k", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Коэффициент для расчёта за какой угол нужно тормозить"); + + migrationBuilder.AddColumn( + name: "break_angle_left", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Угол торможения влево при работе по моменту"); + + migrationBuilder.AddColumn( + name: "encoder_resolution", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Разрешение энкодера"); + + migrationBuilder.AddColumn( + name: "pid_mux_torque_left_limit", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Момент при котором определяется ехать назад по моменту или по скорости"); + + migrationBuilder.AddColumn( + name: "ratio", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Коэффициент редукции редуктора"); + + migrationBuilder.AddColumn( + name: "reverse_k_torque", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону"); + + migrationBuilder.AddColumn( + name: "reverse_speed_sp_zero_time", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true, + comment: "Время выдачи сигнала нулевой скорости на при смене направления"); + + migrationBuilder.AddColumn( + name: "rotor_torque_avg", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Момент в роторе средний"); + + migrationBuilder.AddColumn( + name: "top_drive_speed", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Скорость СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "верхний предел"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "нижний предел"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "смещение"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_from", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Заданная скорость c СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_from_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_from_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_from_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_from_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_to", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Задание скорости на СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_to_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_to_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_to_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_speed_sp_to_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Момент СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_torque_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_from", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Заданный момент c СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_from_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_from_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_from_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_from_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_to", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Задание момента на СВП"); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_to_err", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_to_max", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_to_min", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "top_drive_torque_sp_to_offset", + table: "t_telemetry_data_spin", + type: "real", + nullable: true); + + migrationBuilder.AddColumn( + name: "torque_left_limit", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Ограничение крутящего момента влево"); + + migrationBuilder.AddColumn( + name: "torque_ramp_time", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Время нарастания момента"); + + migrationBuilder.AddColumn( + name: "torque_right_limit", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Ограничение крутящего момента вправо"); + + migrationBuilder.AddColumn( + name: "torque_starting", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Страгивающий момент"); + + migrationBuilder.AddColumn( + name: "turn_left_once_by_angle", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по градусам единожды влево"); + + migrationBuilder.AddColumn( + name: "turn_left_once_by_revols", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по оборотам единожды влево"); + + migrationBuilder.AddColumn( + name: "turn_left_once_by_torque", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по моменту единожды влево"); + + migrationBuilder.AddColumn( + name: "turn_right_once_by_angle", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по градусам единожды вправо"); + + migrationBuilder.AddColumn( + name: "turn_right_once_by_revols", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по оборотам единожды вправо"); + + migrationBuilder.AddColumn( + name: "turn_right_once_by_torque", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Доворот по моменту единожды вправо"); + + migrationBuilder.AddColumn( + name: "unlock_by_sector_out", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Градус отклонения от сектора для автоматического сброса блокировки"); + + migrationBuilder.AddColumn( + name: "ver", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Версия ПО ПЛК"); + + migrationBuilder.AddColumn( + name: "w2800", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true, + comment: "Установка нуля энкодера"); + + migrationBuilder.AddColumn( + name: "w2808", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true, + comment: "Неисправность энкодера"); + + migrationBuilder.AddColumn( + name: "w2810", + table: "t_telemetry_data_spin", + type: "smallint", + nullable: true, + comment: " автоматический сброс блокировки"); + } + } +} diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs index aa3f655c..af644955 100644 --- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs +++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs @@ -3435,31 +3435,11 @@ namespace AsbCloudDb.Migrations .HasColumnName("date") .HasComment("'2021-10-19 18:23:54+05'"); - b.Property("BreakAngleK") - .HasColumnType("real") - .HasColumnName("break_angle_k") - .HasComment("Коэффициент для расчёта за какой угол нужно тормозить"); - - b.Property("BreakAngleLeft") - .HasColumnType("real") - .HasColumnName("break_angle_left") - .HasComment("Угол торможения влево при работе по моменту"); - - b.Property("EncoderResolution") - .HasColumnType("real") - .HasColumnName("encoder_resolution") - .HasComment("Разрешение энкодера"); - b.Property("Mode") .HasColumnType("smallint") .HasColumnName("mode") .HasComment("Выбранный режим управления"); - b.Property("PidMuxTorqueLeftLimit") - .HasColumnType("real") - .HasColumnName("pid_mux_torque_left_limit") - .HasComment(" Момент при котором определяется ехать назад по моменту или по скорости"); - b.Property("PositionRight") .HasColumnType("real") .HasColumnName("position_right") @@ -3470,21 +3450,6 @@ namespace AsbCloudDb.Migrations .HasColumnName("position_zero") .HasComment("Нулевая позиция осцилляции"); - b.Property("Ratio") - .HasColumnType("real") - .HasColumnName("ratio") - .HasComment(" Коэффициент редукции редуктора"); - - b.Property("ReverseKTorque") - .HasColumnType("real") - .HasColumnName("reverse_k_torque") - .HasComment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону"); - - b.Property("ReverseSpeedSpZeroTime") - .HasColumnType("smallint") - .HasColumnName("reverse_speed_sp_zero_time") - .HasComment("Время выдачи сигнала нулевой скорости на при смене направления"); - b.Property("RevolsLeftLimit") .HasColumnType("real") .HasColumnName("revols_left_limit") @@ -3505,11 +3470,6 @@ namespace AsbCloudDb.Migrations .HasColumnName("revols_right_total") .HasComment("Суммарное количество оборотов вправо"); - b.Property("RotorTorqueAvg") - .HasColumnType("real") - .HasColumnName("rotor_torque_avg") - .HasComment("Момент в роторе средний"); - b.Property("SpeedLeftSp") .HasColumnType("real") .HasColumnName("speed_left_sp") @@ -3525,210 +3485,6 @@ namespace AsbCloudDb.Migrations .HasColumnName("state") .HasComment("Переменная этапа"); - b.Property("TopDriveSpeed") - .HasColumnType("real") - .HasColumnName("top_drive_speed") - .HasComment("Скорость СВП"); - - b.Property("TopDriveSpeedErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_speed_err"); - - b.Property("TopDriveSpeedMax") - .HasColumnType("real") - .HasColumnName("top_drive_speed_max") - .HasComment("верхний предел"); - - b.Property("TopDriveSpeedMin") - .HasColumnType("real") - .HasColumnName("top_drive_speed_min") - .HasComment("нижний предел"); - - b.Property("TopDriveSpeedOffset") - .HasColumnType("real") - .HasColumnName("top_drive_speed_offset") - .HasComment("смещение"); - - b.Property("TopDriveSpeedSpFrom") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_from") - .HasComment("Заданная скорость c СВП"); - - b.Property("TopDriveSpeedSpFromErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_speed_sp_from_err"); - - b.Property("TopDriveSpeedSpFromMax") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_from_max"); - - b.Property("TopDriveSpeedSpFromMin") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_from_min"); - - b.Property("TopDriveSpeedSpFromOffset") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_from_offset"); - - b.Property("TopDriveSpeedSpTo") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_to") - .HasComment("Задание скорости на СВП"); - - b.Property("TopDriveSpeedSpToErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_speed_sp_to_err"); - - b.Property("TopDriveSpeedSpToMax") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_to_max"); - - b.Property("TopDriveSpeedSpToMin") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_to_min"); - - b.Property("TopDriveSpeedSpToOffset") - .HasColumnType("real") - .HasColumnName("top_drive_speed_sp_to_offset"); - - b.Property("TopDriveTorque") - .HasColumnType("real") - .HasColumnName("top_drive_torque") - .HasComment("Момент СВП"); - - b.Property("TopDriveTorqueErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_torque_err"); - - b.Property("TopDriveTorqueMax") - .HasColumnType("real") - .HasColumnName("top_drive_torque_max"); - - b.Property("TopDriveTorqueMin") - .HasColumnType("real") - .HasColumnName("top_drive_torque_min"); - - b.Property("TopDriveTorqueOffset") - .HasColumnType("real") - .HasColumnName("top_drive_torque_offset"); - - b.Property("TopDriveTorqueSpFrom") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_from") - .HasComment("Заданный момент c СВП"); - - b.Property("TopDriveTorqueSpFromErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_torque_sp_from_err"); - - b.Property("TopDriveTorqueSpFromMax") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_from_max"); - - b.Property("TopDriveTorqueSpFromMin") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_from_min"); - - b.Property("TopDriveTorqueSpFromOffset") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_from_offset"); - - b.Property("TopDriveTorqueSpTo") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_to") - .HasComment("Задание момента на СВП"); - - b.Property("TopDriveTorqueSpToErr") - .HasColumnType("smallint") - .HasColumnName("top_drive_torque_sp_to_err"); - - b.Property("TopDriveTorqueSpToMax") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_to_max"); - - b.Property("TopDriveTorqueSpToMin") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_to_min"); - - b.Property("TopDriveTorqueSpToOffset") - .HasColumnType("real") - .HasColumnName("top_drive_torque_sp_to_offset"); - - b.Property("TorqueLeftLimit") - .HasColumnType("real") - .HasColumnName("torque_left_limit") - .HasComment("Ограничение крутящего момента влево"); - - b.Property("TorqueRampTime") - .HasColumnType("real") - .HasColumnName("torque_ramp_time") - .HasComment("Время нарастания момента"); - - b.Property("TorqueRightLimit") - .HasColumnType("real") - .HasColumnName("torque_right_limit") - .HasComment("Ограничение крутящего момента вправо"); - - b.Property("TorqueStarting") - .HasColumnType("real") - .HasColumnName("torque_starting") - .HasComment("Страгивающий момент"); - - b.Property("TurnLeftOnceByAngle") - .HasColumnType("real") - .HasColumnName("turn_left_once_by_angle") - .HasComment("Доворот по градусам единожды влево"); - - b.Property("TurnLeftOnceByRevols") - .HasColumnType("real") - .HasColumnName("turn_left_once_by_revols") - .HasComment("Доворот по оборотам единожды влево"); - - b.Property("TurnLeftOnceByTorque") - .HasColumnType("real") - .HasColumnName("turn_left_once_by_torque") - .HasComment("Доворот по моменту единожды влево"); - - b.Property("TurnRightOnceByAngle") - .HasColumnType("real") - .HasColumnName("turn_right_once_by_angle") - .HasComment("Доворот по градусам единожды вправо"); - - b.Property("TurnRightOnceByRevols") - .HasColumnType("real") - .HasColumnName("turn_right_once_by_revols") - .HasComment("Доворот по оборотам единожды вправо"); - - b.Property("TurnRightOnceByTorque") - .HasColumnType("real") - .HasColumnName("turn_right_once_by_torque") - .HasComment("Доворот по моменту единожды вправо"); - - b.Property("UnlockBySectorOut") - .HasColumnType("real") - .HasColumnName("unlock_by_sector_out") - .HasComment(" Градус отклонения от сектора для автоматического сброса блокировки"); - - b.Property("Ver") - .HasColumnType("real") - .HasColumnName("ver") - .HasComment("Версия ПО ПЛК"); - - b.Property("W2800") - .HasColumnType("smallint") - .HasColumnName("w2800") - .HasComment("Установка нуля энкодера"); - - b.Property("W2808") - .HasColumnType("smallint") - .HasColumnName("w2808") - .HasComment("Неисправность энкодера"); - - b.Property("W2810") - .HasColumnType("smallint") - .HasColumnName("w2810") - .HasComment(" автоматический сброс блокировки"); - b.HasKey("IdTelemetry", "DateTime"); b.ToTable("t_telemetry_data_spin"); diff --git a/AsbCloudDb/Model/TelemetryDataSpin.cs b/AsbCloudDb/Model/TelemetryDataSpin.cs index 5976860f..320dd2f2 100644 --- a/AsbCloudDb/Model/TelemetryDataSpin.cs +++ b/AsbCloudDb/Model/TelemetryDataSpin.cs @@ -11,135 +11,37 @@ namespace AsbCloudDb.Model { [Column("id_telemetry")] public int IdTelemetry { get; set; } + [Column("date", TypeName = "timestamp with time zone"), Comment("'2021-10-19 18:23:54+05'")] public DateTimeOffset DateTime { get; set; } - [Column("top_drive_speed"), Comment("Скорость СВП")] - public float? TopDriveSpeed { get; set; } - [Column("top_drive_speed_min"), Comment("нижний предел")] - public float? TopDriveSpeedMin { get; set; } - [Column("top_drive_speed_max"), Comment("верхний предел")] - public float? TopDriveSpeedMax { get; set; } - [Column("top_drive_speed_offset"), Comment("смещение")] - public float? TopDriveSpeedOffset { get; set; } - [Column("top_drive_torque"), Comment("Момент СВП")] - public float? TopDriveTorque { get; set; } - [Column("top_drive_torque_min")] - public float? TopDriveTorqueMin { get; set; } - [Column("top_drive_torque_max")] - public float? TopDriveTorqueMax { get; set; } - [Column("top_drive_torque_offset")] - public float? TopDriveTorqueOffset { get; set; } - [Column("top_drive_speed_sp_from"), Comment("Заданная скорость c СВП")] - public float? TopDriveSpeedSpFrom { get; set; } - [Column("top_drive_speed_sp_from_min")] - public float? TopDriveSpeedSpFromMin { get; set; } - [Column("top_drive_speed_sp_from_max")] - public float? TopDriveSpeedSpFromMax { get; set; } - [Column("top_drive_speed_sp_from_offset")] - public float? TopDriveSpeedSpFromOffset { get; set; } - [Column("top_drive_torque_sp_from"), Comment("Заданный момент c СВП")] - public float? TopDriveTorqueSpFrom { get; set; } - [Column("top_drive_torque_sp_from_min")] - public float? TopDriveTorqueSpFromMin { get; set; } - [Column("top_drive_torque_sp_from_max")] - public float? TopDriveTorqueSpFromMax { get; set; } - [Column("top_drive_torque_sp_from_offset")] - public float? TopDriveTorqueSpFromOffset { get; set; } - [Column("top_drive_speed_sp_to"), Comment("Задание скорости на СВП")] - public float? TopDriveSpeedSpTo { get; set; } - [Column("top_drive_speed_sp_to_min")] - public float? TopDriveSpeedSpToMin { get; set; } - [Column("top_drive_speed_sp_to_max")] - public float? TopDriveSpeedSpToMax { get; set; } - [Column("top_drive_speed_sp_to_offset")] - public float? TopDriveSpeedSpToOffset { get; set; } - [Column("top_drive_torque_sp_to"), Comment("Задание момента на СВП")] - public float? TopDriveTorqueSpTo { get; set; } - [Column("top_drive_torque_sp_to_min")] - public float? TopDriveTorqueSpToMin { get; set; } - [Column("top_drive_torque_sp_to_max")] - public float? TopDriveTorqueSpToMax { get; set; } - [Column("top_drive_torque_sp_to_offset")] - public float? TopDriveTorqueSpToOffset { get; set; } - [Column("torque_starting"), Comment("Страгивающий момент")] - public float? TorqueStarting { get; set; } - [Column("rotor_torque_avg"), Comment("Момент в роторе средний")] - public float? RotorTorqueAvg { get; set; } - [Column("encoder_resolution"), Comment("Разрешение энкодера")] - public float? EncoderResolution { get; set; } - [Column("ratio"), Comment(" Коэффициент редукции редуктора")] - public float? Ratio { get; set; } - [Column("torque_right_limit"), Comment("Ограничение крутящего момента вправо")] - public float? TorqueRightLimit { get; set; } - [Column("torque_left_limit"), Comment("Ограничение крутящего момента влево")] - public float? TorqueLeftLimit { get; set; } [Column("revols_right_limit"), Comment("Ограничение числа оборотов вправо")] public float? RevolsRightLimit { get; set; } + [Column("revols_left_limit"), Comment("Ограничение числа оборотов влево")] public float? RevolsLeftLimit { get; set; } + [Column("speed_right_sp"), Comment("Заданная скорость вращения вправо")] public float? SpeedRightSp { get; set; } + [Column("speed_left_sp"), Comment("Заданная скорость вращения влево")] public float? SpeedLeftSp { get; set; } + [Column("revols_right_total"), Comment("Суммарное количество оборотов вправо")] public float? RevolsRightTotal { get; set; } + [Column("revols_left_total"), Comment("Суммарное количество оборотов влево")] public float? RevolsLeftTotal { get; set; } - [Column("turn_right_once_by_torque"), Comment("Доворот по моменту единожды вправо")] - public float? TurnRightOnceByTorque { get; set; } - [Column("turn_left_once_by_torque"), Comment("Доворот по моменту единожды влево")] - public float? TurnLeftOnceByTorque { get; set; } - [Column("turn_right_once_by_angle"), Comment("Доворот по градусам единожды вправо")] - public float? TurnRightOnceByAngle { get; set; } - [Column("turn_left_once_by_angle"), Comment("Доворот по градусам единожды влево")] - public float? TurnLeftOnceByAngle { get; set; } - [Column("turn_right_once_by_revols"), Comment("Доворот по оборотам единожды вправо")] - public float? TurnRightOnceByRevols { get; set; } - [Column("turn_left_once_by_revols"), Comment("Доворот по оборотам единожды влево")] - public float? TurnLeftOnceByRevols { get; set; } - [Column("break_angle_k"), Comment("Коэффициент для расчёта за какой угол нужно тормозить")] - public float? BreakAngleK { get; set; } - [Column("reverse_k_torque"), Comment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону")] - public float? ReverseKTorque { get; set; } + [Column("position_zero"), Comment("Нулевая позиция осцилляции")] public float? PositionZero { get; set; } + [Column("position_right"), Comment("Крайний правый угол осцилляции")] public float? PositionRight { get; set; } - [Column("torque_ramp_time"), Comment("Время нарастания момента")] - public float? TorqueRampTime { get; set; } - [Column("ver"), Comment("Версия ПО ПЛК")] - public float? Ver { get; set; } - [Column("unlock_by_sector_out"), Comment(" Градус отклонения от сектора для автоматического сброса блокировки")] - public float? UnlockBySectorOut { get; set; } - [Column("pid_mux_torque_left_limit"), Comment(" Момент при котором определяется ехать назад по моменту или по скорости")] - public float? PidMuxTorqueLeftLimit { get; set; } - [Column("break_angle_left"), Comment("Угол торможения влево при работе по моменту")] - public float? BreakAngleLeft { get; set; } - - [Column("top_drive_speed_err")] - public short? TopDriveSpeedErr { get; set; } - [Column("top_drive_torque_err")] - public short? TopDriveTorqueErr { get; set; } - [Column("top_drive_speed_sp_from_err")] - public short? TopDriveSpeedSpFromErr { get; set; } - [Column("top_drive_torque_sp_from_err")] - public short? TopDriveTorqueSpFromErr { get; set; } - [Column("top_drive_speed_sp_to_err")] - public short? TopDriveSpeedSpToErr { get; set; } - [Column("top_drive_torque_sp_to_err")] - public short? TopDriveTorqueSpToErr { get; set; } - [Column("w2800"), Comment("Установка нуля энкодера")] - public short? W2800 { get; set; } - [Column("w2810"), Comment(" автоматический сброс блокировки")] - public short? W2810 { get; set; } [Column("mode"), Comment("Выбранный режим управления")] public short? Mode { get; set; } - [Column("w2808"), Comment("Неисправность энкодера")] - public short? W2808 { get; set; } - [Column("reverse_speed_sp_zero_time"), Comment("Время выдачи сигнала нулевой скорости на при смене направления")] - public short? ReverseSpeedSpZeroTime { get; set; } + [Column("state"), Comment("Переменная этапа")] public short? State { get; set; } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 04e707f6..3f089a0c 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; using AsbCloudApp.Data.Subsystems; +using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudApp.Services.Subsystems; using AsbCloudDb.Model; @@ -82,8 +83,12 @@ namespace AsbCloudInfrastructure public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) { MapsterSetup(); + var connectionStringName = "DefaultConnection"; +#if DEBUG + connectionStringName = "DebugConnection"; +#endif services.AddDbContext(options => - options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))); + options.UseNpgsql(configuration.GetConnectionString(connectionStringName))); services.AddFluentValidation(); @@ -98,6 +103,7 @@ namespace AsbCloudInfrastructure services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(provider => ReduceSamplingService.GetInstance(configuration)); services.AddTransient(); services.AddTransient(); @@ -105,7 +111,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -154,6 +160,8 @@ namespace AsbCloudInfrastructure dbSet => dbSet .Include(c => c.Wells) .Include(c => c.Deposit))); // может быть включен в сервис ClusterService + services.AddTransient(); + services.AddTransient(); // Subsystem service services.AddTransient, CrudCacheServiceBase>(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/Repository/FileRepository.cs b/AsbCloudInfrastructure/Repository/FileRepository.cs new file mode 100644 index 00000000..deb43445 --- /dev/null +++ b/AsbCloudInfrastructure/Repository/FileRepository.cs @@ -0,0 +1,297 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services; +using DocumentFormat.OpenXml.Drawing.Charts; +using DocumentFormat.OpenXml.Wordprocessing; +using Mapster; +using Microsoft.EntityFrameworkCore; +using Org.BouncyCastle.Asn1.Ocsp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Repository +{ +#nullable enable + public class FileRepository : IFileRepository + { + private readonly IQueryable dbSetConfigured; + private readonly IAsbCloudDbContext db; + + public FileRepository(IAsbCloudDbContext db) + { + this.db = db; + this.dbSetConfigured = db.Files + .Include(f => f.Author) + .ThenInclude(u => u.Company) + .ThenInclude(c => c.CompanyType) + .Include(f => f.FileMarks) + .ThenInclude(m => m.User) + .Include(f => f.Well); + } + + private IQueryable BuildQuery(FileRequest request) + { + var query = dbSetConfigured + .Where(e => e.IdWell == request.IdWell); + + double timezoneOffsetHours = query.FirstOrDefault() + ?.Well.Timezone.Hours ?? 5d; + + if (request.IdCategory is not null) + query = query.Where(x => x.IdCategory == request.IdCategory); + + if (request.IsDeleted is not null) + query = query.Where(x => x.IsDeleted == request.IsDeleted); + + if (request.CompanyNamePart is not null) + query = query.Where(e => e.Author.Company.Caption.ToLower().Contains(request.CompanyNamePart.ToLower())); + + if (request.FileNamePart is not null) + query = query.Where(e => e.Name.ToLower().Contains(request.FileNamePart.ToLower())); + + if (request.Begin is not null) + { + var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezoneOffsetHours); + query = query.Where(e => e.UploadDate >= beginUtc); + } + + if (request.End is not null) + { + var endUtc = request.End.Value.ToUtcDateTimeOffset(timezoneOffsetHours); + query = query.Where(e => e.UploadDate <= endUtc); + } + + if (request?.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + query = query + .OrderBy(o => o.UploadDate); + + return query; + } + + public async Task> GetInfosAsync(FileRequest request, CancellationToken token) + { + var query = BuildQuery(request); + + var entities = await query + .SkipTake(request.Skip, request.Take) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + + var dtos = entities.Select(e => Convert(e)); + return dtos; + } + + public async Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token = default) + { + var skip = request.Skip ?? 0; + var take = request.Take ?? 32; + + var query = BuildQuery(request); + + var result = new PaginationContainer() + { + Skip = skip, + Take = take, + Count = await query.CountAsync(token), + }; + + if (result.Count == 0) + return result; + + var entities = await query + .SkipTake(skip, take) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + + result.Items = entities.Select(e => Convert(e)).ToList(); + + return result; + } + + public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) + { + var result = Enumerable.Empty(); + + var entities = await dbSetConfigured + .AsNoTracking() + .Where(f => idsFile.Contains(f.Id)) + .ToListAsync(token) + .ConfigureAwait(false); + + if (entities is not null) + result = entities.Select(entity => Convert(entity)); + + return result; + } + + public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) + { + var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false); + + if (fileInfo is null) + return 0; + + fileInfo.IsDeleted = true; + + return await db.SaveChangesAsync(token).ConfigureAwait(false); + } + + public async Task> DeleteAsync(IEnumerable ids, CancellationToken token) + { + var query = dbSetConfigured + .Where(f => ids.Contains(f.Id) && f.IsDeleted); + + var files = await query.ToListAsync(token); + + var filesDtos = files.Select(x => Convert(x)); + + db.Files.RemoveRange(query); + await db.SaveChangesAsync(token).ConfigureAwait(false); + + return filesDtos; + } + + public async Task GetByMarkId(int idMark, CancellationToken token) + { + var entity = await dbSetConfigured + .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) + .ConfigureAwait(false); + + FileInfoDto dto = Convert(entity!); + return dto; + } + + public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) + { + var fileMark = await db.FileMarks + .FirstOrDefaultAsync(m => m.IdFile == fileMarkDto.IdFile && + m.IdMarkType == fileMarkDto.IdMarkType && + m.IdUser == idUser && + m.IsDeleted == false, + token) + .ConfigureAwait(false); + + if (fileMark is not null) + return 0; + + var newFileMark = fileMarkDto.Adapt(); + newFileMark.Id = default; + newFileMark.DateCreated = DateTime.UtcNow; + newFileMark.IdUser = idUser; + newFileMark.User = null; + + db.FileMarks.Add(newFileMark); + return await db.SaveChangesAsync(token); + } + + public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) + { + var fileMarkQuery = db.FileMarks + .Where(m => idsMarks.Contains(m.Id)); + + foreach (var fileMark in fileMarkQuery) + fileMark.IsDeleted = true; + + return await db.SaveChangesAsync(token); + } + + public async Task> GetAllAsync(CancellationToken token) + => await dbSetConfigured.AsNoTracking() + .Select(x => Convert(x)) + .ToListAsync(token) + .ConfigureAwait(false); + + public async Task GetOrDefaultAsync(int id, CancellationToken token) + { + var entity = await dbSetConfigured + .AsNoTracking() + .FirstOrDefaultAsync(f => f.Id == id, token) + .ConfigureAwait(false); + + if (entity is null) + return null; + + var dto = Convert(entity); + return dto; + } + + public FileInfoDto? GetOrDefault(int id) + { + var entity = dbSetConfigured + .AsNoTracking() + .FirstOrDefault(f => f.Id == id); + + if (entity is null) + return null; + + var dto = Convert(entity); + return dto; + } + + public async Task InsertAsync(FileInfoDto newItem, CancellationToken token) + { + var fileInfo = new FileInfo() + { + IdWell = newItem.IdWell, + IdAuthor = newItem.IdAuthor, + IdCategory = newItem.IdCategory, + Name = newItem.Name, + UploadDate = DateTime.UtcNow, + IsDeleted = false, + Size = newItem.Size, + }; + + var entry = db.Files.Add(fileInfo); + await db.SaveChangesAsync(token).ConfigureAwait(false); + return entry.Entity.Id; + } + + public Task InsertRangeAsync(IEnumerable newItems, CancellationToken token) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(FileInfoDto item, CancellationToken token) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(int id, CancellationToken token) + { + throw new NotImplementedException(); + } + + private static FileInfoDto Convert(FileInfo entity) + { + var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; + return Convert(entity, timezoneOffset); + } + + private static FileInfoDto Convert(FileInfo entity, double timezoneOffset) + { + var dto = entity.Adapt(); + dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); + dto.FileMarks = entity.FileMarks.Select(m => + { + var mark = m.Adapt(); + mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset); + return mark; + }); + return dto; + } + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Repository/FileStorageRepository.cs b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs new file mode 100644 index 00000000..8bd61e2f --- /dev/null +++ b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs @@ -0,0 +1,121 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Repositories; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Repository +{ +#nullable enable + public class FileStorageRepository : IFileStorageRepository + { + /// + /// Директория хранения файлов + /// + private readonly string RootPath = "files"; + + public FileStorageRepository() + { + } + + public async Task SaveFileAsync(string filePathRec, Stream fileStreamSrc, CancellationToken token) + { + CreateDirectory(filePathRec); + using var newfileStream = new FileStream(filePathRec, FileMode.Create); + await fileStreamSrc.CopyToAsync(newfileStream, token).ConfigureAwait(false); + } + + public void DeleteFile(IEnumerable filesName) + { + foreach (var fileName in filesName) + { + if (File.Exists(fileName)) + File.Delete(fileName); + } + } + + public long GetFileLength(string srcFilePath) + { + var sysFileInfo = new FileInfo(srcFilePath); + return sysFileInfo.Length; + } + + public void MoveFile(string srcFilePath, string filePath) + { + CreateDirectory(filePath); + File.Move(srcFilePath, filePath); + } + + public string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) + { + return Path.Combine(RootPath, $"{idWell}", + $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}"); + } + + public int DeleteFilesNotInList(int idWell, IEnumerable idsFilesList) + { + var allFilesPath = GetFilesPath(idWell); + var result = 0; + + foreach (var filePath in allFilesPath) + { + if (int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile) + || !idsFilesList.Any(x => x == idFile)) + { + File.Delete(filePath); + result++; + } + } + + return result; + } + + public IEnumerable GetListFilesNotDisc(IEnumerable files) + { + var resutl = new List(); + var groupFiles = files.GroupBy(x => x.IdWell); + + foreach (var itemGroupFiles in groupFiles) + { + var idsFilesStorage = GetIdsFiles(itemGroupFiles.Key); + foreach (var file in files) + { + if (!idsFilesStorage.Any(x => x == file.Id)) + resutl.Add(file); + } + } + + return resutl; + } + + public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => + Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); + + private IEnumerable GetIdsFiles(int idWell) + { + var result = new List(); + var allFilesPath = GetFilesPath(idWell); + + foreach (var filePath in allFilesPath) + if(int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile)) + result.Add(idFile); + + return result; + } + + private IEnumerable GetFilesPath(int idWell) + { + var path = Path.Combine(RootPath, $"{idWell}"); + return Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); + } + + private static void CreateDirectory(string filePath) + { + var directoryName = Path.GetDirectoryName(filePath)!; + Directory.CreateDirectory(directoryName); + } + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Repository/WitsRecordRepository.cs b/AsbCloudInfrastructure/Repository/WitsRecordRepository.cs index 1be9a7de..0c750c6b 100644 --- a/AsbCloudInfrastructure/Repository/WitsRecordRepository.cs +++ b/AsbCloudInfrastructure/Repository/WitsRecordRepository.cs @@ -66,17 +66,33 @@ namespace AsbCloudInfrastructure.Repository return new TDto[] { Convert(data, timezoneHours) }; } - public Task SaveDataAsync(int idTelemetry, IEnumerable dtos, CancellationToken token) + public async Task SaveDataAsync(int idTelemetry, IEnumerable dtos, CancellationToken token) { if (dtos?.Any() != true) - return Task.CompletedTask; + return; var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours; var entities = dtos .DistinctBy(d => d.DateTime) .Select(dto => Convert(dto, idTelemetry, timezoneHours)); - dbset.AddRange(entities); - return db.SaveChangesAsync(token); + + var dateMin = entities.Min(e => e.DateTime); + var dateMax = entities.Max(e => e.DateTime); + var existingEntities = await dbset + .Where(e => e.IdTelemetry == idTelemetry) + .Where(e => e.DateTime >= dateMin && e.DateTime <= dateMax) + .Select(e => new { e.DateTime, e.IdTelemetry}) + .ToArrayAsync(token); + + foreach (var entity in entities) + { + if (existingEntities.Any(e=>e.IdTelemetry == entity.IdTelemetry && e.DateTime == entity.DateTime)) + dbset.Update(entity); + else + dbset.Add(entity); + } + + await db.SaveChangesAsync(token); } private static TEntity Convert(TDto dto, int idTelemetry, double timezoneHours) diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs index 2eab984d..2acc1160 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs @@ -162,7 +162,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks sheet.Cell(AddressWatchData[1]) ._SetValue($"{blockDto.WorkTimeSpinMaster}"); sheet.Cell(AddressMetreData[1]) - ._SetValue($"{blockDto.PenetrationTorkMaster}"); + ._SetValue($"{blockDto.PenetrationSpinMaster}"); sheet._Range(AddressWorkSaubData[2], AddressWorkSaubData[2] + (0, 2)) ._SetValue("Торк Мастер (демпфирование), ч/:"); sheet.Cell(AddressWatchData[2]) diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs index d5e9728a..a54a8e90 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs @@ -44,7 +44,9 @@ namespace AsbCloudInfrastructure.Services.DailyReport timeBalance.Draw(sheet); blockDimensionless.Draw(sheet); blockSaub.Draw(sheet); - blockSign.Draw(sheet); + blockSign.Draw(sheet); + //sheet.Columns().AdjustToContents(); // Adjust column width + sheet.Rows().AdjustToContents(); } } } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index 1c30ba0b..df762093 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -48,9 +48,10 @@ namespace AsbCloudInfrastructure.Services.DailyReport public async Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) { - var dailyReportDto = await GetAsync(idWell, date, token); + var dateOnly = DateTime.SpecifyKind(date.Date, DateTimeKind.Utc); + var dailyReportDto = await GetAsync(idWell, dateOnly, token); if (dailyReportDto is null) - dailyReportDto = await MakeDefaultDailyReportAsync(idWell, date, token); + dailyReportDto = await MakeDefaultDailyReportAsync(idWell, dateOnly, token); return dailyReportDto; } @@ -124,10 +125,27 @@ namespace AsbCloudInfrastructure.Services.DailyReport ClusterName = well?.Cluster ?? "", }, TimeBalance = await MakeTimeBalanceAsync(idWell, date, token), + Bha = await GetPrevOrNewBhaAsync(idWell, date, token) }; return dto; } + private async Task GetPrevOrNewBhaAsync(int idWell, DateTime date, CancellationToken token) + { + var dateOffset = date.Date; + var entity = await db.DailyReports + .Where(x => x.IdWell == idWell) + .OrderByDescending(x => x.StartDate) + .FirstOrDefaultAsync(r => r.StartDate.Year <= dateOffset.Year && + r.StartDate.DayOfYear <= dateOffset.DayOfYear, token); + + if (entity is null) + return new BhaDto(); + + var dto = Convert(entity); + return dto.Bha; + } + private async Task MakeTimeBalanceAsync(int idWell, DateTime date, CancellationToken token) { var stat = await detectedOperationService.GetOperationsStatAsync(new DetectedOperationRequest diff --git a/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs b/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs index ff079b14..5297b0e1 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/XLExtentions.cs @@ -10,12 +10,12 @@ namespace AsbCloudInfrastructure.Services.DailyReport var mergedRange = range.Merge(); mergedRange.FirstCell()._SetValue(value); var colWidth = mergedRange.FirstCell().WorksheetColumn().Width; - var maxCharsToWrap = colWidth / (0.05d * mergedRange.FirstCell().Style.Font.FontSize); + var maxCharsToWrap = colWidth / (0.1d * mergedRange.FirstCell().Style.Font.FontSize); if (value is string valueString && valueString.Length > maxCharsToWrap) { var row = mergedRange.FirstCell().WorksheetRow(); var baseHeight = row.Height; - row.Height = 0.45d * baseHeight * Math.Ceiling(1d + valueString.Length / maxCharsToWrap); + row.Height = 0.5d * baseHeight * Math.Ceiling(1d + valueString.Length / maxCharsToWrap); } mergedRange.Style.SetAllBorders() .Alignment.SetWrapText(true); @@ -59,7 +59,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport { var row = cell.WorksheetRow(); var baseHeight = row.Height; - row.Height = 0.52d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); + row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); } } @@ -80,7 +80,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport { var row = cell.WorksheetRow(); var baseHeight = row.Height; - row.Height = 0.52d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); + row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); } } diff --git a/AsbCloudInfrastructure/Services/DrillParamsService.cs b/AsbCloudInfrastructure/Services/DrillParamsService.cs index 1af54956..95528330 100644 --- a/AsbCloudInfrastructure/Services/DrillParamsService.cs +++ b/AsbCloudInfrastructure/Services/DrillParamsService.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { +#nullable enable public class DrillParamsService : CrudServiceBase, IDrillParamsService { private readonly IAsbCloudDbContext db; @@ -23,7 +24,7 @@ namespace AsbCloudInfrastructure.Services this.telemetryService = telemetryService; } - public async Task GetDefaultDrillParamsAsync(int idWell, + public async Task GetDefaultDrillParamsAsync(int idWell, double startDepth, double endDepth, CancellationToken token = default) { var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); @@ -39,28 +40,46 @@ namespace AsbCloudInfrastructure.Services select new DrillParamsDto() { IdWell = idWell, - DepthStart = startDepth, - DepthEnd = endDepth, + Depth = new MinMaxDto + { + Min = endDepth, + Max = startDepth + }, IdWellSectionType = 0, - AxialLoadMin = g.Min(t => t.AxialLoad) ?? double.NaN, - AxialLoadAvg = g.Average(t => t.AxialLoad) ?? double.NaN, - AxialLoadMax = g.Max(t => t.AxialLoad) ?? double.NaN, - PressureMin = g.Min(t => t.Pressure) ?? double.NaN, - PressureAvg = g.Average(t => t.Pressure) ?? double.NaN, - PressureMax = g.Max(t => t.Pressure) ?? double.NaN, - RotorTorqueMin = g.Min(t => t.RotorTorque) ?? double.NaN, - RotorTorqueAvg = g.Average(t => t.RotorTorque) ?? double.NaN, - RotorTorqueMax = g.Max(t => t.RotorTorque) ?? double.NaN, - RotorSpeedMin = g.Min(t => t.RotorSpeed) ?? double.NaN, - RotorSpeedAvg = g.Average(t => t.RotorSpeed) ?? double.NaN, - RotorSpeedMax = g.Max(t => t.RotorSpeed) ?? double.NaN, - FlowMin = g.Min(t => t.Flow) ?? double.NaN, - FlowAvg = g.Min(t => t.Flow) ?? double.NaN, - FlowMax = g.Min(t => t.Flow) ?? double.NaN + AxialLoad = new MinMaxExtendedViewDto + { + Min = g.Min(t => t.AxialLoad) ?? double.NaN, + Avg = g.Average(t => t.AxialLoad) ?? double.NaN, + Max = g.Max(t => t.AxialLoad) ?? double.NaN + }, + Pressure = new MinMaxExtendedViewDto + { + Min = g.Min(t => t.Pressure) ?? double.NaN, + Avg = g.Average(t => t.Pressure) ?? double.NaN, + Max = g.Max(t => t.Pressure) ?? double.NaN + }, + RotorTorque = new MinMaxExtendedViewDto + { + Min = g.Min(t => t.RotorTorque) ?? double.NaN, + Avg = g.Average(t => t.RotorTorque) ?? double.NaN, + Max = g.Max(t => t.RotorTorque) ?? double.NaN + }, + RotorSpeed = new MinMaxExtendedViewDto + { + Min = g.Min(t => t.RotorSpeed) ?? double.NaN, + Avg = g.Average(t => t.RotorSpeed) ?? double.NaN, + Max = g.Max(t => t.RotorSpeed) ?? double.NaN + }, + Flow = new MinMaxExtendedViewDto + { + Min = g.Min(t => t.Flow) ?? double.NaN, + Avg = g.Min(t => t.Flow) ?? double.NaN, + Max = g.Min(t => t.Flow) ?? double.NaN + } }) .AsNoTracking() .DefaultIfEmpty() - .OrderBy(t => t.AxialLoadMin) + .OrderBy(t => t.AxialLoad.Min) .FirstOrDefaultAsync(token) .ConfigureAwait(false); @@ -70,35 +89,62 @@ namespace AsbCloudInfrastructure.Services public async Task> GetAllAsync(int idWell, CancellationToken token = default) { - var entities = await (from p in db.DrillParams - where p.IdWell == idWell - orderby p.Id - select p) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); + var entities = await db.DrillParams + .Where(p => p.IdWell == idWell) + .OrderBy(p=> p.Id) + .AsNoTracking() + .ToArrayAsync(token) + .ConfigureAwait(false); - var dto = entities.Adapt>(); - return dto; + var dtos = entities.Select(p => + { + var dto = new DrillParamsDto + { + IdWell = p.IdWell, + Id = p.Id, + IdWellSectionType = p.IdWellSectionType, + Depth = new MinMaxDto { Max = p.PressureMax, Min = p.PressureMin }, + Pressure = MakeMinMaxExtended(p.PressureAvg, p.PressureMax, p.PressureMin), + AxialLoad = MakeMinMaxExtended(p.AxialLoadAvg, p.AxialLoadMax, p.AxialLoadMin), + Flow = MakeMinMaxExtended(p.FlowAvg, p.FlowMax, p.FlowMin), + RotorSpeed = MakeMinMaxExtended(p.RotorSpeedAvg, p.RotorSpeedMax, p.RotorSpeedMin), + RotorTorque = MakeMinMaxExtended(p.RotorTorqueAvg, p.RotorTorqueMax, p.RotorTorqueMin) + }; + return dto; + }); + + return dtos; } public async Task> GetCompositeAllAsync(int idWell, CancellationToken token = default) { - var compositeWellDrillParams = - await (from p in db.DrillParams - from c in db.WellComposites - where c.IdWell == idWell && - p.IdWell == c.IdWellSrc && - p.IdWellSectionType == c.IdWellSectionType - select p) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); + var allDrillParamsQuery = db.WellComposites + .Where(c => c.IdWell == idWell) + .Join(db.DrillParams, + c => c.IdWellSrc, + p => p.IdWell, + (c, p) => p); - var compositeDrillParamsDtos = compositeWellDrillParams.Adapt>(); + var allDrillParams = await allDrillParamsQuery + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); - return compositeDrillParamsDtos; + var compositeWellDrillParamsQuery = db.WellComposites + .Where(c => c.IdWell == idWell) + .Join(db.DrillParams, + c => new { IdWell = c.IdWellSrc, IdSection = c.IdWellSectionType }, + p => new { IdWell = p.IdWell, IdSection = p.IdWellSectionType }, + (c, p) => p); + + var compositeWellDrillParams = await compositeWellDrillParamsQuery + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + + var result = compositeWellDrillParams.Select(x => Convert(x, allDrillParams)); + return result; } public async Task InsertAsync(int idWell, DrillParamsDto dto, @@ -143,5 +189,34 @@ namespace AsbCloudInfrastructure.Services var result = await base.UpdateAsync(dto, token).ConfigureAwait(false); return result; } + + private static DrillParamsDto Convert(DrillParams entity, IEnumerable drillParams) + { + return new DrillParamsDto + { + Id = entity.Id, + IdWellSectionType = entity.IdWellSectionType, + AxialLoad = MakeMinMaxExtended(entity.AxialLoadAvg, entity.AxialLoadMax, entity.AxialLoadMin, drillParams.Select(x => (x.AxialLoadMin, x.AxialLoadMax))), + Depth = new MinMaxDto { + Min = entity.DepthEnd, + Max = entity.DepthStart + }, + Flow = MakeMinMaxExtended(entity.FlowAvg, entity.FlowMax, entity.FlowMin, drillParams.Select(x => (x.FlowMin, x.FlowMax))), + IdWell = entity.IdWell, + Pressure = MakeMinMaxExtended(entity.PressureAvg, entity.PressureMax, entity.PressureMin, drillParams.Select(x => (x.PressureMin, x.PressureMax))), + RotorSpeed = MakeMinMaxExtended(entity.RotorSpeedAvg, entity.RotorSpeedMax, entity.RotorSpeedMin, drillParams.Select(x => (x.RotorSpeedMin, x.RotorSpeedMax))), + RotorTorque = MakeMinMaxExtended(entity.RotorTorqueAvg, entity.RotorTorqueMax, entity.RotorTorqueMin, drillParams.Select(x => (x.RotorTorqueMin, x.RotorTorqueMax))) + }; + } + + private static MinMaxExtendedViewDto MakeMinMaxExtended(double avg, double max, double min, IEnumerable<(double min, double max)>? allDrillParams = null) + => new MinMaxExtendedViewDto { + Avg = avg, + Max = max, + Min = min, + IsMax = (! allDrillParams?.Any (mx => mx.max > max)) ?? false, + IsMin = (! allDrillParams?.Any (mn => mn.min < min)) ?? false + }; } +#nullable disable } diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index 5fbc7301..e926a886 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -2,6 +2,7 @@ using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -19,7 +20,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private static readonly Dictionary drillingProgramCreateErrors = new Dictionary(); private readonly IAsbCloudDbContext context; - private readonly IFileService fileService; + private readonly FileService fileService; private readonly IUserService userService; private readonly IWellService wellService; private readonly IConfiguration configuration; @@ -49,7 +50,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram public DrillingProgramService( IAsbCloudDbContext context, - IFileService fileService, + FileService fileService, IUserService userService, IWellService wellService, IConfiguration configuration, @@ -281,7 +282,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram fileMarkDto.IdMarkType != idMarkTypeReject) throw new ArgumentInvalidException($"В этом методе допустимы только отметки о принятии или отклонении.", nameof(fileMarkDto)); - var fileInfo = await fileService.GetInfoAsync(fileMarkDto.IdFile, token) + var fileInfo = await fileService.GetOrDefaultAsync(fileMarkDto.IdFile, token) .ConfigureAwait(false); if (fileInfo is null) @@ -356,7 +357,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private async Task NotifyPublisherOnFullAccepAsync(FileMarkDto fileMark, CancellationToken token) { - var file = await fileService.GetInfoAsync(fileMark.IdFile, token); + var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var user = file.Author; var factory = new DrillingMailBodyFactory(configuration); @@ -368,7 +369,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private async Task NotifyPublisherOnRejectAsync(FileMarkDto fileMark, CancellationToken token) { - var file = await fileService.GetInfoAsync(fileMark.IdFile, token); + var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var user = file.Author; var factory = new DrillingMailBodyFactory(configuration); @@ -472,14 +473,15 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram var well = await wellService.GetOrDefaultAsync(idWell, token); var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx"; var tempResultFilePath = Path.Combine(Path.GetTempPath(), "drillingProgram", resultFileName); - var mailService = new EmailService(backgroundWorker, configuration); async Task funcProgramMake(string id, CancellationToken token) { var contextOptions = new DbContextOptionsBuilder() .UseNpgsql(connectionString) .Options; using var context = new AsbCloudDbContext(contextOptions); - var fileService = new FileService(context); + var fileRepository = new FileRepository(context); + var fileStorageRepository = new FileStorageRepository(); + var fileService = new FileService(fileRepository, fileStorageRepository); var files = state.Parts.Select(p => fileService.GetUrl(p.File)); DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath, state.Parts, well); await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token); diff --git a/AsbCloudInfrastructure/Services/FileService.cs b/AsbCloudInfrastructure/Services/FileService.cs deleted file mode 100644 index 947fd853..00000000 --- a/AsbCloudInfrastructure/Services/FileService.cs +++ /dev/null @@ -1,379 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Services; -using AsbCloudDb.Model; -using Mapster; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudInfrastructure.Services -{ - public class FileService : IFileService - { - public string RootPath { get; private set; } - - private readonly IQueryable dbSetConfigured; - private readonly IAsbCloudDbContext db; - - public FileService(IAsbCloudDbContext db) - { - RootPath = "files"; - this.db = db; - dbSetConfigured = db.Files - .Include(f => f.Author) - .ThenInclude(u => u.Company) - .ThenInclude(c => c.CompanyType) - .Include(f => f.FileMarks) - .ThenInclude(m => m.User) - .Include(f => f.Well); - } - - public async Task MoveAsync(int idWell, int? idUser, int idCategory, - string destinationFileName, string srcFilePath, CancellationToken token = default) - { - destinationFileName = Path.GetFileName(destinationFileName); - srcFilePath = Path.GetFullPath(srcFilePath); - if (!File.Exists(srcFilePath)) - throw new ArgumentInvalidException($"file {srcFilePath} doesn't exist", nameof(srcFilePath)); - - var sysFileInfo = new System.IO.FileInfo(srcFilePath); - - //save info to db - var fileInfo = new AsbCloudDb.Model.FileInfo() - { - IdWell = idWell, - IdAuthor = idUser, - IdCategory = idCategory, - Name = destinationFileName, - UploadDate = DateTime.UtcNow, - IsDeleted = false, - Size = sysFileInfo.Length, - }; - - var entry = db.Files.Add(fileInfo); - await db.SaveChangesAsync(token).ConfigureAwait(false); - var fileId = entry.Entity.Id; - string filePath = MakeFilePath(idWell, idCategory, destinationFileName, fileId); - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); - File.Move(srcFilePath, filePath); - - return await GetInfoAsync(entry.Entity.Id, token); - } - - public async Task SaveAsync(int idWell, int? idUser, int idCategory, - string fileFullName, Stream fileStream, CancellationToken token) - { - //save info to db - var fileInfo = new AsbCloudDb.Model.FileInfo() - { - IdWell = idWell, - IdAuthor = idUser, - IdCategory = idCategory, - Name = Path.GetFileName(fileFullName), - UploadDate = DateTime.UtcNow, - IsDeleted = false, - Size = fileStream?.Length ?? 0 - }; - - var entry = db.Files.Add(fileInfo); - await db.SaveChangesAsync(token).ConfigureAwait(false); - var fileId = entry.Entity.Id; - //save stream to disk - string filePath = MakeFilePath(idWell, idCategory, fileFullName, fileId); - - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); - - using var newfileStream = new FileStream(filePath, FileMode.Create); - await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); - - return await GetInfoAsync(entry.Entity.Id, token); - } - - private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) - { - return Path.Combine(RootPath, $"{idWell}", - $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}"); - } - - public async Task> GetInfosByCategoryAsync(int idWell, - int idCategory, CancellationToken token) - { - var entities = await dbSetConfigured - .Where(e => e.IdWell == idWell && e.IdCategory == idCategory && e.IsDeleted == false) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e)); - return dtos; - } - - public async Task> GetInfosAsync(int idWell, - int idCategory, string companyName = default, string fileName = default, DateTime begin = default, - DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) - { - var query = dbSetConfigured - .Where(e => e.IdWell == idWell && - e.IdCategory == idCategory && - !e.IsDeleted); - - if (!string.IsNullOrEmpty(companyName)) - query = query.Where(e => (e.Author == null) || - (e.Author.Company == null) || - e.Author.Company.Caption.Contains(companyName)); - - if (!string.IsNullOrEmpty(fileName)) - query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower())); - - var firstFile = await query.FirstOrDefaultAsync(token); - if (firstFile is null) - return new PaginationContainer() - { - Skip = skip, - Take = take, - Count = 0, - }; - - var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; - - if (begin != default) - { - var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate >= beginUtc); - } - - if (end != default) - { - var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate <= endUtc); - } - - var count = await query.CountAsync(token).ConfigureAwait(false); - - var result = new PaginationContainer(count) - { - Skip = skip, - Take = take, - Count = count, - }; - - if (count <= skip) - return result; - - query = query.OrderBy(e => e.UploadDate); - - if (skip > 0) - query = query.Skip(skip); - query = query.Take(take); - - var entities = await query - .Take(take).AsNoTracking().ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e, timezoneOffset)); - result.Items.AddRange(dtos); - return result; - } - - public async Task GetInfoAsync(int idFile, - CancellationToken token) - { - var entity = await dbSetConfigured - .AsNoTracking() - .FirstOrDefaultAsync(f => f.Id == idFile, token) - .ConfigureAwait(false); - - if (entity is null) - { - throw new FileNotFoundException($"fileId:{idFile} not found"); - } - - var ext = Path.GetExtension(entity.Name); - - var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); - var fullPath = Path.GetFullPath(relativePath); - if (!File.Exists(fullPath)) - { - throw new FileNotFoundException("not found", relativePath); - } - - var dto = Convert(entity); - return dto; - } - - public async Task MarkAsDeletedAsync(int idFile, - CancellationToken token = default) - { - var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false); - - if (fileInfo is null) - return 0; - - fileInfo.IsDeleted = true; - - return await db.SaveChangesAsync(token).ConfigureAwait(false); - } - - public Task DeleteAsync(int idFile, CancellationToken token) - => DeleteAsync(new int[] { idFile }, token); - - public async Task DeleteAsync(IEnumerable ids, CancellationToken token) - { - if (ids is null || !ids.Any()) - return 0; - - var filesQuery = db.Files - .Where(f => ids.Contains(f.Id)); - - var files = await filesQuery.ToListAsync(token); - - if (files is null || !files.Any()) - return 0; - - foreach (var file in files) - { - var fileName = GetUrl(file.IdWell, file.IdCategory, file.Id, Path.GetExtension(file.Name)); - if (File.Exists(fileName)) - File.Delete(fileName); - } - - db.Files.RemoveRange(filesQuery); - - return await db.SaveChangesAsync(token).ConfigureAwait(false); - } - - public string GetUrl(int idFile) - { - var fileInfo = db.Files - .FirstOrDefault(f => f.Id == idFile); - - if (fileInfo is null) - return null; - - return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); - } - - public string GetUrl(FileInfoDto fileInfo) => - GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); - - public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => - Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); - - public async Task GetByMarkId(int idMark, - CancellationToken token) - { - var entity = await dbSetConfigured - .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) - .ConfigureAwait(false); - - FileInfoDto dto = Convert(entity); - return dto; - } - - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity) - { - var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; - return Convert(entity, timezoneOffset); - } - - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity, double timezoneOffset) - { - var dto = entity.Adapt(); - dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); - dto.FileMarks = entity.FileMarks.Select(m => - { - var mark = m.Adapt(); - mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset); - return mark; - }); - return dto; - } - public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) - { - var fileMark = await db.FileMarks - .FirstOrDefaultAsync(m => m.IdFile == fileMarkDto.IdFile && - m.IdMarkType == fileMarkDto.IdMarkType && - m.IdUser == idUser && - m.IsDeleted == false, - token) - .ConfigureAwait(false); - - if (fileMark is not null) - return 0; - - var newFileMark = fileMarkDto.Adapt(); - newFileMark.Id = default; - newFileMark.DateCreated = DateTime.UtcNow; - newFileMark.IdUser = idUser; - newFileMark.User = null; - - db.FileMarks.Add(newFileMark); - return await db.SaveChangesAsync(token); - } - - public Task MarkFileMarkAsDeletedAsync(int idMark, - CancellationToken token) - => MarkFileMarkAsDeletedAsync(new int[] { idMark }, token); - - public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, - CancellationToken token) - { - var fileMarkQuery = db.FileMarks - .Where(m => idsMarks.Contains(m.Id)); - - foreach (var fileMark in fileMarkQuery) - fileMark.IsDeleted = true; - - return await db.SaveChangesAsync(token); - } - - public async Task> GetInfoByIdsAsync(List idsFile, CancellationToken token) - { - var result = new List(); - - var entities = await dbSetConfigured - .AsNoTracking() - .Where(f => idsFile.Contains(f.Id)) - .ToListAsync(token) - .ConfigureAwait(false); - - foreach (var entity in entities) - { - if (entity is null) - { - throw new FileNotFoundException($"fileId:{entity.Id} not found"); - } - - var ext = Path.GetExtension(entity.Name); - - var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); - var fullPath = Path.GetFullPath(relativePath); - if (!File.Exists(fullPath)) - { - throw new FileNotFoundException("not found", relativePath); - } - - result.Add(Convert(entity)); - } - - return result; - } - - public async Task> GetInfosByWellIdAsync(int idWell, CancellationToken token) - { - var entities = await dbSetConfigured - .Where(e => e.IdWell == idWell && e.IsDeleted == false) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e)); - return dtos; - } - } -} diff --git a/AsbCloudInfrastructure/Services/ReduceSamplingService.cs b/AsbCloudInfrastructure/Services/ReduceSamplingService.cs new file mode 100644 index 00000000..d9c11e0d --- /dev/null +++ b/AsbCloudInfrastructure/Services/ReduceSamplingService.cs @@ -0,0 +1,335 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services +{ +#nullable enable + class JobHandle + { + public int Id => Job.Id; + public JobDto Job { get; set; } = null!; + public DateTime DateCreate { get; set; } = DateTime.Now; + public OnJobProgressDelagate? OnProgress { get; set; } + } + + public class ReduceSamplingService : IReduceSamplingService + { + private const string jobResultKeyDeleted = "deleted"; + private const string jobResultKeyTotal = "total"; + private static ReduceSamplingService? instance; + private readonly string connectionString; + private const int ratio = 5; + private readonly List jobHandlers = new(5); + private bool isHandling; + private CancellationTokenSource? cancellationTokenSource; + private Task? task; + + private ReduceSamplingService(IConfiguration configuration) + { + connectionString = configuration.GetConnectionString("DefaultConnection"); + } + + ~ReduceSamplingService() + { + Stop(); + } + + /// + /// Get singleton Instance + /// + /// + /// + public static ReduceSamplingService GetInstance(IConfiguration configuration) + { + instance ??= new(configuration); + return instance; + } + + /// + public bool TryEnqueueRediceSamplingJob(int idTelemetry, OnJobProgressDelagate? onProgress, out JobDto jobDto) + { + lock (jobHandlers) + { + var oldJob = jobHandlers.FirstOrDefault(j => j.Id == idTelemetry); + if (oldJob is not null) + { + jobDto = oldJob.Job; + return false; + } + + jobDto = new JobDto + { + Id = idTelemetry, + State = JobState.Waiting, + Results = new(), + }; + var jobHandler = new JobHandle + { + Job = jobDto, + OnProgress = onProgress, + }; + + jobHandlers.Add(jobHandler); + } + EnsureHandleQueueStarted(); + return true; + } + + /// + public JobDto? GetOrDefaultState(int idTelemetry) + { + JobHandle? jobHandler; + lock (jobHandlers) + { + jobHandler = jobHandlers.FirstOrDefault(j => j.Id == idTelemetry); + } + return jobHandler?.Job; + } + + /// + public IEnumerable GetJobs() => jobHandlers.Select(j=>j.Job); + + private bool TryTakeWaitingJob(out JobHandle? job) + { + lock (jobHandlers) + { + job = jobHandlers.FirstOrDefault(j => j.Job.State == JobState.Waiting); + } + return job is not null; + } + + private void EnsureHandleQueueStarted() + { + if (isHandling) + return; + isHandling = true; + cancellationTokenSource = new CancellationTokenSource(); + var token = cancellationTokenSource.Token; + task = Task.Run(async () => await HandleJobs(token)) + .ContinueWith(_ => isHandling = false); + } + + private async Task HandleJobs(CancellationToken token) + { + while (TryTakeWaitingJob(out JobHandle? jobHandler)) + { + jobHandler!.Job.State = JobState.Working; + try + { + await RediceSamplingSaubAsync(jobHandler, token); + await RediceSamplingSpinAsync(jobHandler, token); + jobHandler.Job.State = JobState.Done; + } + catch (Exception exception) + { + jobHandler.Job.State = JobState.Fail; + jobHandler.Job.Results = null; + jobHandler.Job.Error = exception.Message; + jobHandler.OnProgress?.Invoke(jobHandler.Job); + } + + if (!jobHandlers.Any(j => j.Job.State == JobState.Waiting)) + { + var sw = Stopwatch.StartNew(); + await VacuumAsync(token); + sw.Stop(); + if (sw.ElapsedMilliseconds < 10_000) + { + var delayMs = 10_000 - (int)sw.ElapsedMilliseconds; + await Task.Delay(delayMs, token); + } + CleanJobs(); + } + } + } + + private void CleanJobs() + { + lock (jobHandlers) + { + jobHandlers.RemoveAll(j => j.Job.State == JobState.Done || j.Job.State == JobState.Fail); + } + } + + private async Task VacuumAsync(CancellationToken token) + { + using var db = MakeContext(); + var sqlVacuum = "vacuum (SKIP_LOCKED);"; + await db.Database.ExecuteSqlRawAsync(sqlVacuum, token); + } + + private void Stop() + { + cancellationTokenSource?.Cancel(); + task?.Wait(1_000); + task = null; + cancellationTokenSource?.Dispose(); + cancellationTokenSource = null; + } + + private Task RediceSamplingSaubAsync(JobHandle job, CancellationToken token) + { + const int ramLimit = 10 * 1024 * 1024; + const int dataItemSize = 345; // by profiler + const int chankSize = ramLimit / dataItemSize; // ~ 90_000 + const double maxWellDepthGap = 0.1; + + var maxDateGapSec = ratio; + + var sqlSelectTemplate = + "select " + + " * " + + "from " + + " (select " + + " *, " + + " rank() over win1 as row_num, " + + " lag(\"date\", 1) over win1 as lag_date, " + + " lag(\"mode\", 1) over win1 as lag_mode, " + + " lag(mse_state, 1) over win1 as lag_mse_state, " + + " lag(well_depth, 1) over win1 as lag_well_depth, " + + " lag(id_feed_regulator, 1) over win1 as lag_id_feed_regulator " + + " from t_telemetry_data_saub " + + $" where id_telemetry = {job.Id} and \"date\" > {{0}}" + + " window win1 as (order by \"date\") " + + " ) as t_1 " + + "where " + + $" (row_num % {ratio}) = 0 " + + " or \"mode\" != lag_mode " + + $" or(\"date\" - lag_date) >= interval '{maxDateGapSec} second' " + + $" or well_depth - lag_well_depth > {maxWellDepthGap:#0,0#} " + + " or mse_state != lag_mse_state " + + " or id_feed_regulator != lag_id_feed_regulator " + + "order by \"date\" "; + + var sqlDeleteTemplate = "delete " + + "from t_telemetry_data_saub " + + $"where id_telemetry = {job.Id} and \"date\" between {{0}} and {{1}};"; + + return RediceSamplingAsync( + job, + chankSize, + sqlSelectTemplate, + sqlDeleteTemplate, + token); + } + + private Task RediceSamplingSpinAsync(JobHandle job, CancellationToken token) + { + const int ramLimit = 10 * 1024 * 1024; + const int dataItemSize = 345; // by profiler + const int chankSize = ramLimit / dataItemSize; // ~ 90_000 + var maxDateGapSec = ratio; + + var sqlSelectTemplate = + "select " + + " * " + + "from " + + " (select " + + " *, " + + " rank() over win1 as row_num, " + + " lag(\"date\", 1) over win1 as lag_date, " + + " lag(\"mode\", 1) over win1 as lag_mode, " + + " lag(state, 1) over win1 as lag_state " + + " from t_telemetry_data_spin " + + $" where id_telemetry = {job.Id} and \"date\" > {{0}}" + + " window win1 as (order by \"date\") " + + " ) as t_1 " + + "where " + + $" (row_num % {ratio}) = 0 " + + " or \"mode\" != lag_mode " + + $" or(\"date\" - lag_date) >= interval '{maxDateGapSec} second' " + + " or state != lag_state " + + "order by \"date\" "; + + var sqlDeleteTemplate = "delete " + + "from t_telemetry_data_spin " + + $"where id_telemetry = {job.Id} and \"date\" between {{0}} and {{1}};"; + + return RediceSamplingAsync( + job, + chankSize, + sqlSelectTemplate, + sqlDeleteTemplate, + token); + } + + private async Task RediceSamplingAsync( + JobHandle jobHandle, + int chankSize, + string sqlSelectTemplate, + string sqlDeleteTemplate, + CancellationToken token) + where TEntity : class, AsbCloudDb.Model.ITelemetryData + { + using var db = MakeContext(); + var dbset = db.Set(); + + var deleted = 0; + var totalCount = await dbset.Where(t => t.IdTelemetry == jobHandle.Id).CountAsync(token); + + var result = jobHandle.Job.Results!; + if (result[jobResultKeyDeleted] is int previousDeleted) + deleted += previousDeleted; + + if (result[jobResultKeyTotal] is int previousCount) + totalCount += previousCount; + + result[jobResultKeyDeleted] = deleted; + result[jobResultKeyTotal] = totalCount; + + jobHandle.OnProgress?.Invoke(jobHandle.Job); + var startDate = DateTimeOffset.MinValue; + + do + { + var query = dbset + .FromSqlRaw(sqlSelectTemplate, startDate) + .AsNoTracking(); + + var data = await query + .Take(chankSize) + .ToArrayAsync(token); + + var currentDataCount = data.Length; + if (currentDataCount == 0) + break; + + var lastDate = data.Last().DateTime; + + var currentDeleted = await db.Database.ExecuteSqlRawAsync(sqlDeleteTemplate, new object[] { startDate, lastDate }.AsEnumerable(), token); + if (currentDeleted == 0) + break; + + await db.Database.ExecInsertAsync(dbset, data, token); + + startDate = lastDate; + deleted += currentDeleted; + result[jobResultKeyDeleted] = deleted; + result[jobResultKeyTotal] = totalCount; + jobHandle.OnProgress?.Invoke(jobHandle.Job); + } while (true); + + return; + } + + private AsbCloudDbContext MakeContext() + { + var options = new DbContextOptionsBuilder() + .UseNpgsql(connectionString) + .Options; + + return new AsbCloudDbContext(options); + } + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index 3c70915b..7d60f852 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using AsbSaubReport; using Mapster; using Microsoft.EntityFrameworkCore; @@ -65,7 +66,9 @@ namespace AsbCloudInfrastructure.Services }; generator.Make(reportFileName); - var fileService = new FileService(context); + var fileRepository = new FileRepository(context); + var fileStorageRepository = new FileStorageRepository(); + var fileService = new FileService(fileRepository, fileStorageRepository); var fileInfo = await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token); progressHandler.Invoke(new diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index c8983361..285ac3d8 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -16,7 +16,7 @@ namespace AsbCloudInfrastructure.Services.SAUB where TDto : AsbCloudApp.Data.ITelemetryData where TModel : class, AsbCloudDb.Model.ITelemetryData { - private readonly IAsbCloudDbContext db; + protected readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; protected readonly CacheTable cacheTelemetry; protected readonly CacheTable cacheTelemetryUsers; @@ -134,25 +134,6 @@ namespace AsbCloudInfrastructure.Services.SAUB if (fullDataCount > 1.75 * approxPointsCount) { var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); - - switch (m) - { - //case var i when i <= 1: // тут для полноты, но никогда не сработает из-за условия выше - // break; - case var i when i < 10: - query = query.Where((d) => d.DateTime.Second % m == 0); - break; - case var i when i < 30: - query = query.Where((d) => (d.DateTime.Minute * 60 + d.DateTime.Second) % m == 0); - break; - case var i when i < 600: - query = query.Where((d) => ((d.DateTime.Hour * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); - break; - default: - query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); - break; - } - if (m > 1) query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0); } @@ -189,5 +170,7 @@ namespace AsbCloudInfrastructure.Services.SAUB return offset; } + + } } diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs index 2941b1ca..419c5831 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs @@ -2,7 +2,12 @@ using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; +using DocumentFormat.OpenXml.Drawing.Charts; using Mapster; +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs index c33b7cab..5cd51161 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs @@ -3,6 +3,8 @@ using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; +using System.Threading; +using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs index 8fbc75df..18566010 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs @@ -145,8 +145,8 @@ namespace AsbCloudInfrastructure.Services.Subsystems SumDepthInterval = periodGroupDepth, OperationCount = g.Count() }; - if(subsystemStat.KUsage > 100) - subsystemStat.KUsage = 100; + if(subsystemStat.KUsage > 1) + subsystemStat.KUsage = 1; return subsystemStat; }); diff --git a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs index 3885d0e3..4d44f38c 100644 --- a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs +++ b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs @@ -1,7 +1,9 @@ using AsbCloudApp.Data; using AsbCloudApp.Exceptions; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -21,7 +23,7 @@ namespace AsbCloudInfrastructure.Services public class WellFinalDocumentsService : IWellFinalDocumentsService { private readonly IAsbCloudDbContext context; - private readonly IFileService fileService; + private readonly FileService fileService; private readonly IUserService userService; private readonly IWellService wellService; private readonly IConfiguration configuration; @@ -31,7 +33,7 @@ namespace AsbCloudInfrastructure.Services private const int FileServiceThrewException = -1; public WellFinalDocumentsService(IAsbCloudDbContext context, - IFileService fileService, + FileService fileService, IUserService userService, IWellService wellService, IConfiguration configuration, @@ -95,7 +97,7 @@ namespace AsbCloudInfrastructure.Services .Select(g => g.Key); var files = (await fileService - .GetInfosByWellIdAsync(idWell, token) + .GetInfosAsync(new FileRequest { IdWell = idWell}, token) .ConfigureAwait(false)) .Where(f => categoriesIds.Contains(f.IdCategory)) .ToArray(); @@ -161,7 +163,12 @@ namespace AsbCloudInfrastructure.Services public async Task GetFilesHistoryByIdCategory(int idWell, int idCategory, CancellationToken token) { - var files = await fileService.GetInfosByCategoryAsync(idWell, idCategory, token).ConfigureAwait(false); + var request = new FileRequest + { + IdWell = idWell, + IdCategory = idCategory, + }; + var files = await fileService.GetInfosAsync(request, token).ConfigureAwait(false); return new WellFinalDocumentsHistoryDto { IdWell = idWell, diff --git a/AsbCloudInfrastructure/Services/_Readme.md b/AsbCloudInfrastructure/Services/_Readme.md new file mode 100644 index 00000000..d05ae29e --- /dev/null +++ b/AsbCloudInfrastructure/Services/_Readme.md @@ -0,0 +1,9 @@ +# Создание репозитория для сервися + +1. Создать интерфейс репозитория в AsbCloudApp.Services +2. Создать репозиторий в AsbCloudInfrastructure.Repository, наследоваться от созданного интерфейса, в нем добавить работу с БД +3. Добавить репозиторий в AsbCloudInfrastructure.DependencyInjection +4. Добавить в конструктор сервиса новый репозиторий и использовать его методы +5. Перенести сервис из AsbCloudInfrastructure.Services в AsbCloudApp.Services +6. Добавить или поправить тесты на изменяемый сервис используя AsbCloudWebApi.Tests.RepositoryFactory +7. В тестах сделать мок данных для репозитория \ No newline at end of file diff --git a/AsbCloudInfrastructure/Startup.cs b/AsbCloudInfrastructure/Startup.cs index 884a3383..5ccb0df7 100644 --- a/AsbCloudInfrastructure/Startup.cs +++ b/AsbCloudInfrastructure/Startup.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; +using System.Linq; namespace AsbCloudInfrastructure { diff --git a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj index f8b181c5..0f182ff4 100644 --- a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj +++ b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj @@ -4,6 +4,8 @@ net6.0 false + + enable diff --git a/AsbCloudWebApi.Tests/IRepositoryFactory.cs b/AsbCloudWebApi.Tests/IRepositoryFactory.cs new file mode 100644 index 00000000..e7028689 --- /dev/null +++ b/AsbCloudWebApi.Tests/IRepositoryFactory.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Tests +{ + public interface IRepositoryFactory + { + Task DeleteAsync(int id, CancellationToken token); + Task> GetAllAsync(CancellationToken token); + TDto? GetOrDefault(int id); + Task GetOrDefaultAsync(int id, CancellationToken token); + Task InsertAsync(TDto newItem, CancellationToken token); + Task InsertRangeAsync(IEnumerable newItems, CancellationToken token); + Task UpdateAsync(TDto item, CancellationToken token); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi.Tests/RepositoryFactory.cs b/AsbCloudWebApi.Tests/RepositoryFactory.cs new file mode 100644 index 00000000..a8588dda --- /dev/null +++ b/AsbCloudWebApi.Tests/RepositoryFactory.cs @@ -0,0 +1,42 @@ +using AsbCloudApp.Services; +using Moq; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Tests +{ + public class RepositoryFactory + { + public static Mock Make(ICollection data) + where TDto : AsbCloudApp.Data.IId + where TRepository : class, ICrudService + { + var repositoryMock = new Mock(); + + repositoryMock.Setup(x => x.InsertAsync(It.IsAny(), It.IsAny())) + .Returns((TDto dto, CancellationToken token) => { + var id = data.Max(x => x.Id); + dto.Id = ++id; + data.Add(dto); + return Task.FromResult(dto.Id); + }); + repositoryMock.Setup(x => x.DeleteAsync(It.IsAny(), It.IsAny())) + .Returns((int idFile, CancellationToken token) => { + var cnt = data.Count; + var dto = data.FirstOrDefault(x => x.Id == idFile); + data.Remove(dto); + return Task.FromResult(cnt - data.Count); + }); + + repositoryMock.Setup(x => x.GetAllAsync(It.IsAny())).ReturnsAsync(data); + repositoryMock.Setup(x => x.GetOrDefaultAsync(It.IsAny(), It.IsAny())) + .Returns((int idFile, CancellationToken token) => { + return Task.FromResult(data.FirstOrDefault(x => x.Id == idFile)); + }); + + return repositoryMock; + } + } +} diff --git a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs index 7cea8d32..a1e275b9 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Services.DrillingProgram; using Mapster; using Microsoft.Extensions.Configuration; @@ -77,7 +78,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests new RelationCompanyWell { IdCompany = 3003, IdWell = 3002, }, }; - private readonly Mock fileServiceMock; + private readonly Mock fileServiceMock; private readonly Mock userServiceMock; private readonly Mock wellServiceMock; private readonly Mock configurationMock; @@ -96,7 +97,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests db.RelationCompaniesWells.AddRange(relationsCompanyWell); db.SaveChanges(); - fileServiceMock = new Mock(); + fileServiceMock = new Mock(); userServiceMock = new Mock(); wellServiceMock = new Mock(); configurationMock = new Mock(); @@ -219,7 +220,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests { ConfigureNotApproved(); fileServiceMock - .Setup(s => s.GetInfoAsync(It.IsAny(), It.IsAny())) + .Setup(s => s.GetOrDefaultAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(file1002.Adapt())); fileServiceMock @@ -250,7 +251,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests { ConfigureNotApproved(); fileServiceMock - .Setup(s => s.GetInfoAsync(It.IsAny(), It.IsAny())) + .Setup(s => s.GetOrDefaultAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(file1002.Adapt())); fileServiceMock diff --git a/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs new file mode 100644 index 00000000..698f83cd --- /dev/null +++ b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs @@ -0,0 +1,200 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using Moq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace AsbCloudWebApi.Tests.ServicesTests +{ + public class FileServiceTest + { + private FileService fileService; + + private static UserDto Author = new UserDto { + Id = 1, + IdCompany = 1 + }; + + private static List FileMarks = new List { + new FileMarkDto + { + Id = 132, + IdFile = 1742, + User = Author, + Comment = "qqq", + IdMarkType = 1, + DateCreated = DateTime.Now, + IsDeleted = false + }, + new FileMarkDto + { + Id = 133, + IdFile = 1742, + User = Author, + Comment = "qqq3", + IdMarkType = 1, + DateCreated = DateTime.Now, + IsDeleted = false + } + }; + + private static List Files = new List { + new FileInfoDto { + Id = 1742, + IdAuthor = 1, + Author = Author, + IdWell = 90, + IdCategory = 10040, + Name = "test.txt", + Size = 0, + UploadDate = DateTime.Now, + FileMarks = FileMarks + }, + new FileInfoDto + { + Id = 1743, + IdAuthor = 1, + Author = Author, + IdWell = 90, + IdCategory = 10021, + Name = "test1.txt", + Size = 0, + UploadDate = DateTime.Now + } + }; + + public FileServiceTest() + { + var repositoryMock = RepositoryFactory.Make(Files); + + repositoryMock.Setup(x => x.GetByMarkId(It.IsAny(), It.IsAny())) + .Returns((int idMark, CancellationToken token) => { + var data = Files.FirstOrDefault(x => x.FileMarks.Any(m => m.Id == idMark)); + return Task.FromResult(data); + }); + repositoryMock.Setup(x => x.GetInfoByIdsAsync(It.IsAny>(), It.IsAny())) + .Returns((int[] idsFile, CancellationToken token) => { + var data = Files.Where(x => idsFile.Contains(x.Id)); + return Task.FromResult(data); + }); + + repositoryMock.Setup(x => x.DeleteAsync(It.IsAny>(), It.IsAny())) + .Returns((int[] idsFile, CancellationToken token) => { + var dtos = Files.Where(x => idsFile.Contains(x.Id)).ToArray(); + Files.RemoveAll(x => dtos.Select(d => d.Id).Contains(x.Id)); + return Task.FromResult(dtos.AsEnumerable()); + }); + + repositoryMock.Setup(x => x.MarkFileMarkAsDeletedAsync(It.IsAny>(), It.IsAny())) + .Returns((int[] idsMarks, CancellationToken token) => { + var data = FileMarks.Where(m => idsMarks.Contains(m.Id)); + + foreach (var fileMark in data) + fileMark.IsDeleted = true; + + var result = data.All(x => x.IsDeleted) ? 1 : 0; + return Task.FromResult(result); + }); + + repositoryMock.Setup(x => x.MarkAsDeletedAsync(It.IsAny(), It.IsAny())) + .Returns((int idFile, CancellationToken token) => { + var result = Files.Where(x => x.Id == idFile).Any() ? 1 : 0; + return Task.FromResult(result); + }); + + repositoryMock.Setup(x => x.GetInfosAsync(It.IsAny(), It.IsAny())) + .Returns((FileRequest request, CancellationToken token) => { + var data = Files.Where(x => x.IdWell == request.IdWell); + return Task.FromResult(data); + }); + + repositoryMock.Setup(x => x.CreateFileMarkAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((FileMarkDto dto, int idUser, CancellationToken token) => { + dto.Id = FileMarks.Max(x => x.Id) + 1; + dto.DateCreated = DateTime.UtcNow; + dto.User = null; + FileMarks.Add(dto); + + var result = FileMarks.Any(x => x.Id == dto.Id) ? 1 : 0; + return Task.FromResult(result); + }); + + var storageRepositoryMock = new Mock(); + storageRepositoryMock.Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((int idWell, int idCategory, int idFile, string dotExtention) => { + return Path.Combine("files", idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); + }); + + fileService = new FileService(repositoryMock.Object, storageRepositoryMock.Object); + } + + [Fact] + public async Task GetByMarkId_returns_FileInfo_by_idMark() + { + var data = await fileService.GetByMarkId(133, CancellationToken.None); + Assert.NotNull(data); + } + + [Fact] + public async Task GetOrDefaultAsync_returns_FileInfo() + { + var data = await fileService.GetOrDefaultAsync(1742, CancellationToken.None); + Assert.NotNull(data); + } + + [Fact] + public async Task GetInfoByIdsAsync_returns_FileInfo() + { + var data = await fileService.GetInfoByIdsAsync(new int[] { 1742, 1743 }, CancellationToken.None); + Assert.NotNull(data); + } + + [Fact] + public async Task SaveAsync_returns_FileInfo() + { + using var stream = new MemoryStream(Array.Empty()); + var data = await fileService.SaveAsync(90, 1, 10040, "test.txt", stream, CancellationToken.None); + Assert.NotNull(data); + } + + [Fact] + public async Task DeleteAsync() + { + var result = await fileService.DeleteAsync(new int[] { 1743 }, CancellationToken.None); + Assert.True(result > 0); + } + + [Fact] + public async Task MarkFileMarkAsDeletedAsync() + { + var result = await fileService.MarkFileMarkAsDeletedAsync(new int[] { 132, 133 }, CancellationToken.None); + Assert.True(result > 0); + } + + [Fact] + public async Task MarkAsDeletedAsync() + { + var result = await fileService.MarkAsDeletedAsync(1742, CancellationToken.None); + Assert.True(result > 0); + } + + [Fact] + public async Task CreateFileMarkAsync() + { + var dto = new FileMarkDto { + Comment = "test", + IdFile = 1742, + IdMarkType = 1 + }; + var result = await fileService.CreateFileMarkAsync(dto, 1, CancellationToken.None); + Assert.True(result > 0); + } + } +} diff --git a/AsbCloudWebApi.Tests/ServicesTests/WellFinalDocumentsServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/WellFinalDocumentsServiceTest.cs index ac53a5b9..1718b92d 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/WellFinalDocumentsServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/WellFinalDocumentsServiceTest.cs @@ -17,7 +17,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests { private readonly AsbCloudDbContext context; private WellFinalDocumentsService service; - private readonly Mock fileServiceMock; + private readonly Mock fileServiceMock; private readonly Mock userServiceMock; private readonly Mock wellServiceMock; private readonly Mock configurationMock; @@ -44,7 +44,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests context = TestHelpter.MakeTestContext(); context.SaveChanges(); - fileServiceMock = new Mock(); + fileServiceMock = new Mock(); userServiceMock = new Mock(); userServiceMock.Setup(x => x.GetAllAsync(CancellationToken.None)).Returns(Task.Run(() => users.Select(x => (UserExtendedDto)x))); diff --git a/AsbCloudWebApi.Tests/TestHelpter.cs b/AsbCloudWebApi.Tests/TestHelpter.cs index 9322503b..f7c8e8a9 100644 --- a/AsbCloudWebApi.Tests/TestHelpter.cs +++ b/AsbCloudWebApi.Tests/TestHelpter.cs @@ -1,4 +1,5 @@ -using AsbCloudDb.Model; +using AsbCloudApp.Services; +using AsbCloudDb.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; diff --git a/AsbCloudWebApi/Controllers/FileController.cs b/AsbCloudWebApi/Controllers/FileController.cs index 46f9d589..d4dfad33 100644 --- a/AsbCloudWebApi/Controllers/FileController.cs +++ b/AsbCloudWebApi/Controllers/FileController.cs @@ -1,15 +1,17 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using AsbCloudDb.Model; namespace AsbCloudWebApi.Controllers { +#nullable enable /// /// Хранение файлов /// @@ -18,10 +20,10 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class FileController : ControllerBase { - private readonly IFileService fileService; + private readonly FileService fileService; private readonly IWellService wellService; - public FileController(IFileService fileService, IWellService wellService) + public FileController(FileService fileService, IWellService wellService) { this.fileService = fileService; this.wellService = wellService; @@ -68,38 +70,27 @@ namespace AsbCloudWebApi.Controllers /// /// Возвращает информацию о файлах для скважины в выбраной категории /// - /// id скважины - /// id категории файла - /// id компаний для фильтрации возвращаемых файлов - /// часть имени файла для поиска - /// дата начала - /// дата окончания - /// для пагинации кол-во записей пропустить - /// для пагинации кол-во записей взять + /// /// Токен отмены задачи /// Список информации о файлах в этой категории [HttpGet] + [Route("/api/files")] [Permission] [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetFilesInfoAsync( - [FromRoute] int idWell, - int idCategory = default, - string companyName = default, - string fileName = default, - DateTime begin = default, - DateTime end = default, - int skip = 0, - int take = 32, + [FromQuery] FileRequest request, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); - if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) + if (request.IdCategory is null || idCompany is null) return Forbid(); - var filesInfo = await fileService.GetInfosAsync(idWell, idCategory, - companyName, fileName, begin, end, skip, take, token).ConfigureAwait(false); + if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, + request.IdWell, token).ConfigureAwait(false)) + return Forbid(); + + var filesInfo = await fileService.GetInfosPaginatedAsync(request, token).ConfigureAwait(false); return Ok(filesInfo); } @@ -108,36 +99,33 @@ namespace AsbCloudWebApi.Controllers /// Возвращает файл с диска на сервере /// /// id скважины - /// id запрашиваемого файла + /// id запрашиваемого файла /// Токен отмены задачи /// Запрашиваемый файл [HttpGet] - [Route("{fileId}")] + [Route("{idFile}")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public async Task GetFileAsync([FromRoute] int idWell, - int fileId, CancellationToken token = default) + int idFile, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token); + + if (fileInfo is null) + return NotFound(idFile); + if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) + fileInfo.IdWell, token).ConfigureAwait(false)) return Forbid(); - try - { - var fileInfo = await fileService.GetInfoAsync(fileId, token); + var fileStream = fileService.GetFileStream(fileInfo); - var relativePath = fileService.GetUrl(fileInfo); - return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); - } - catch (FileNotFoundException ex) - { - return NotFound(ex.FileName); - } + return File(fileStream, "application/octet-stream", fileInfo.Name); } /// @@ -159,13 +147,16 @@ namespace AsbCloudWebApi.Controllers int? idCompany = User.GetCompanyId(); - if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + if (idUser is null || idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); - var file = await fileService.GetInfoAsync((int)idFile, token); + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token); - if (!userService.HasPermission((int)idUser, $"File.edit{file.IdCategory}")) + if (fileInfo is null) + return NotFound(idFile); + + if (!userService.HasPermission((int)idUser, $"File.edit{fileInfo?.IdCategory}")) return Forbid(); var result = await fileService.MarkAsDeletedAsync(idFile, token); @@ -223,5 +214,34 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } + + /// + /// Возвращает информацию о файле + /// + /// id запрашиваемого файла + /// Токен отмены задачи + /// Запрашиваемый файл + [HttpGet] + [Route("/api/files/{idFile}")] + [Permission] + [ProducesResponseType(typeof(FileInfoDto), (int)System.Net.HttpStatusCode.OK)] + public async Task GetFileInfoAsync([FromRoute] int idFile, CancellationToken token = default) + { + int? idCompany = User.GetCompanyId(); + + if (idCompany is null) + return Forbid(); + + try + { + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token).ConfigureAwait(false); + return Ok(fileInfo); + } + catch (FileNotFoundException ex) + { + return NotFound(ex.FileName); + } + } } +#nullable disable } diff --git a/AsbCloudWebApi/Controllers/ReduceSamplingController.cs b/AsbCloudWebApi/Controllers/ReduceSamplingController.cs new file mode 100644 index 00000000..ddb99b2d --- /dev/null +++ b/AsbCloudWebApi/Controllers/ReduceSamplingController.cs @@ -0,0 +1,78 @@ +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using System.Linq; +using AsbCloudWebApi.SignalR; +using Microsoft.AspNetCore.SignalR; + +namespace AsbCloudWebApi.Controllers +{ + /// + /// Редактор кустов для админки + /// + [Route("api/admin/[controller]")] + [ApiController] + [Authorize] + public class ReduceSamplingController: ControllerBase + { + private readonly IReduceSamplingService service; + private readonly IHubContext telemetryHubContext; + private const string sirnalRGroupName = "ReduceSampling"; + private const string sirnalRMethodOnProgress = "OnProgress"; + + public ReduceSamplingController( + IReduceSamplingService service, + IHubContext telemetryHubContext ) + { + this.service = service; + this.telemetryHubContext = telemetryHubContext; + } + + /// + /// Получить все задания. Задания удаляются минимум через 10 сек после выполнения, возможно позднее. + /// + /// + /// + [HttpGet] + public virtual ActionResult> GetAll(int idTelemetry) + { + var result = service.GetJobs(); + if (result.Any()) + return Ok(result); + else + return NoContent(); + } + + /// + /// Получить состояние определенной задачи + /// + /// + /// + [HttpGet("{idTelemetry}")] + public virtual ActionResult GetOrDefault(int idTelemetry) + { + var result = service.GetOrDefaultState(idTelemetry); + return Ok(result); + } + + /// + /// Создать задачу прореживанию архива и добавить её в очередь на выполнение. + /// Если задача есть в очереди, она же и возвращается, но подписка не происходит. + /// + [HttpPost] + [Permission] + public virtual ActionResult Enqueue(int idTelemetry) + { + void onProgress(JobDto job) => + Task.Run(async () => + await telemetryHubContext.Clients.Group(sirnalRGroupName) + .SendAsync(sirnalRMethodOnProgress, job)); + + service.TryEnqueueRediceSamplingJob(idTelemetry, onProgress, out JobDto job); + return Ok(job); + } + } +} diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index 03897582..d3df1092 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -18,12 +18,12 @@ namespace AsbCloudWebApi.Controllers public class ReportController : ControllerBase { private readonly IReportService reportService; - private readonly IFileService fileService; + private readonly FileService fileService; private readonly IWellService wellService; private readonly IHubContext reportsHubContext; public ReportController(IReportService reportService, IWellService wellService, - IFileService fileService, IHubContext reportsHubContext) + FileService fileService, IHubContext reportsHubContext) { this.reportService = reportService; this.fileService = fileService; diff --git a/AsbCloudWebApi/Program.cs b/AsbCloudWebApi/Program.cs index 822d20be..b21fa05f 100644 --- a/AsbCloudWebApi/Program.cs +++ b/AsbCloudWebApi/Program.cs @@ -1,3 +1,4 @@ +using DocumentFormat.OpenXml.InkML; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -25,7 +26,10 @@ namespace AsbCloudWebApi { var connectionStringName = "DefaultConnection"; - AsbCloudInfrastructure.DependencyInjection.MakeContext(configuration.GetConnectionString(connectionStringName)); + var context = AsbCloudInfrastructure.DependencyInjection.MakeContext(configuration.GetConnectionString(connectionStringName)); + context.Database.SetCommandTimeout(TimeSpan.FromSeconds(5 * 60)); + context.Database.Migrate(); + Console.WriteLine(" ."); return; } diff --git a/AsbCloudWebApi/Properties/PublishProfiles/PubLinux.pubxml b/AsbCloudWebApi/Properties/PublishProfiles/PubLinux.pubxml new file mode 100644 index 00000000..9ca6d0f0 --- /dev/null +++ b/AsbCloudWebApi/Properties/PublishProfiles/PubLinux.pubxml @@ -0,0 +1,21 @@ + + + + + true + false + true + Release + Any CPU + FileSystem + bin\publishLinux\ + FileSystem + + net6.0 + a2768702-47cb-4127-941c-e339d5efcffe + true + linux-x64 + + \ No newline at end of file diff --git a/AsbCloudWebApi/ProtobufModel.cs b/AsbCloudWebApi/ProtobufModel.cs index 4bebb030..c193a1bf 100644 --- a/AsbCloudWebApi/ProtobufModel.cs +++ b/AsbCloudWebApi/ProtobufModel.cs @@ -296,69 +296,16 @@ namespace AsbCloudWebApi RuntimeTypeModel.Default.Add(type, false) .Add(1, nameof(TelemetryDataSpinDto.IdTelemetry)) .Add(2, nameof(TelemetryDataSpinDto.DateTime)) - .Add(3, nameof(TelemetryDataSpinDto.TopDriveSpeed)) - .Add(4, nameof(TelemetryDataSpinDto.TopDriveSpeedMin)) - .Add(5, nameof(TelemetryDataSpinDto.TopDriveSpeedMax)) - .Add(6, nameof(TelemetryDataSpinDto.TopDriveSpeedOffset)) - .Add(7, nameof(TelemetryDataSpinDto.TopDriveSpeedErr)) - .Add(8, nameof(TelemetryDataSpinDto.TopDriveTorque)) - .Add(9, nameof(TelemetryDataSpinDto.TopDriveTorqueMin)) - .Add(10, nameof(TelemetryDataSpinDto.TopDriveTorqueMax)) - .Add(11, nameof(TelemetryDataSpinDto.TopDriveTorqueOffset)) - .Add(12, nameof(TelemetryDataSpinDto.TopDriveTorqueErr)) - .Add(13, nameof(TelemetryDataSpinDto.TopDriveSpeedSpFrom)) - .Add(14, nameof(TelemetryDataSpinDto.TopDriveSpeedSpFromMin)) - .Add(15, nameof(TelemetryDataSpinDto.TopDriveSpeedSpFromMax)) - .Add(16, nameof(TelemetryDataSpinDto.TopDriveSpeedSpFromOffset)) - .Add(17, nameof(TelemetryDataSpinDto.TopDriveSpeedSpFromErr)) - .Add(18, nameof(TelemetryDataSpinDto.TopDriveTorqueSpFrom)) - .Add(19, nameof(TelemetryDataSpinDto.TopDriveTorqueSpFromMin)) - .Add(20, nameof(TelemetryDataSpinDto.TopDriveTorqueSpFromMax)) - .Add(21, nameof(TelemetryDataSpinDto.TopDriveTorqueSpFromOffset)) - .Add(22, nameof(TelemetryDataSpinDto.TopDriveTorqueSpFromErr)) - .Add(23, nameof(TelemetryDataSpinDto.TopDriveSpeedSpTo)) - .Add(24, nameof(TelemetryDataSpinDto.TopDriveSpeedSpToMin)) - .Add(25, nameof(TelemetryDataSpinDto.TopDriveSpeedSpToMax)) - .Add(26, nameof(TelemetryDataSpinDto.TopDriveSpeedSpToOffset)) - .Add(27, nameof(TelemetryDataSpinDto.TopDriveSpeedSpToErr)) - .Add(28, nameof(TelemetryDataSpinDto.TopDriveTorqueSpTo)) - .Add(29, nameof(TelemetryDataSpinDto.TopDriveTorqueSpToMin)) - .Add(30, nameof(TelemetryDataSpinDto.TopDriveTorqueSpToMax)) - .Add(31, nameof(TelemetryDataSpinDto.TopDriveTorqueSpToOffset)) - .Add(32, nameof(TelemetryDataSpinDto.TopDriveTorqueSpToErr)) - .Add(33, nameof(TelemetryDataSpinDto.W2800)) - .Add(34, nameof(TelemetryDataSpinDto.W2810)) .Add(35, nameof(TelemetryDataSpinDto.Mode)) - .Add(36, nameof(TelemetryDataSpinDto.W2808)) - .Add(37, nameof(TelemetryDataSpinDto.TorqueStarting)) - .Add(38, nameof(TelemetryDataSpinDto.RotorTorqueAvg)) - .Add(39, nameof(TelemetryDataSpinDto.EncoderResolution)) - .Add(40, nameof(TelemetryDataSpinDto.Ratio)) - .Add(41, nameof(TelemetryDataSpinDto.TorqueRightLimit)) - .Add(42, nameof(TelemetryDataSpinDto.TorqueLeftLimit)) .Add(43, nameof(TelemetryDataSpinDto.RevolsRightLimit)) .Add(44, nameof(TelemetryDataSpinDto.RevolsLeftLimit)) .Add(45, nameof(TelemetryDataSpinDto.SpeedRightSp)) .Add(46, nameof(TelemetryDataSpinDto.SpeedLeftSp)) .Add(47, nameof(TelemetryDataSpinDto.RevolsRightTotal)) .Add(48, nameof(TelemetryDataSpinDto.RevolsLeftTotal)) - .Add(49, nameof(TelemetryDataSpinDto.TurnRightOnceByTorque)) - .Add(50, nameof(TelemetryDataSpinDto.TurnLeftOnceByTorque)) - .Add(51, nameof(TelemetryDataSpinDto.TurnRightOnceByAngle)) - .Add(52, nameof(TelemetryDataSpinDto.TurnLeftOnceByAngle)) - .Add(53, nameof(TelemetryDataSpinDto.TurnRightOnceByRevols)) - .Add(54, nameof(TelemetryDataSpinDto.TurnLeftOnceByRevols)) - .Add(55, nameof(TelemetryDataSpinDto.BreakAngleK)) - .Add(56, nameof(TelemetryDataSpinDto.ReverseKTorque)) .Add(57, nameof(TelemetryDataSpinDto.PositionZero)) .Add(58, nameof(TelemetryDataSpinDto.PositionRight)) - .Add(59, nameof(TelemetryDataSpinDto.TorqueRampTime)) - .Add(60, nameof(TelemetryDataSpinDto.Ver)) - .Add(61, nameof(TelemetryDataSpinDto.ReverseSpeedSpZeroTime)) - .Add(62, nameof(TelemetryDataSpinDto.UnlockBySectorOut)) - .Add(63, nameof(TelemetryDataSpinDto.PidMuxTorqueLeftLimit)) - .Add(64, nameof(TelemetryDataSpinDto.State)) - .Add(65, nameof(TelemetryDataSpinDto.BreakAngleLeft)); + .Add(64, nameof(TelemetryDataSpinDto.State)); } static void EnshureRegisteredDataSaub() diff --git a/AsbCloudWebApi/wwwroot/asset-manifest.json b/AsbCloudWebApi/wwwroot/asset-manifest.json deleted file mode 100644 index cdaee685..00000000 --- a/AsbCloudWebApi/wwwroot/asset-manifest.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "files": { - "main.css": "/static/css/main.c2a82e71.chunk.css", - "main.js": "/static/js/main.01e9ada9.chunk.js", - "main.js.map": "/static/js/main.01e9ada9.chunk.js.map", - "runtime-main.js": "/static/js/runtime-main.8da12c69.js", - "runtime-main.js.map": "/static/js/runtime-main.8da12c69.js.map", - "static/js/2.f196b75b.chunk.js": "/static/js/2.f196b75b.chunk.js", - "static/js/2.f196b75b.chunk.js.map": "/static/js/2.f196b75b.chunk.js.map", - "static/css/3.f8ac3883.chunk.css": "/static/css/3.f8ac3883.chunk.css", - "static/js/3.31b66021.chunk.js": "/static/js/3.31b66021.chunk.js", - "static/js/3.31b66021.chunk.js.map": "/static/js/3.31b66021.chunk.js.map", - "static/css/4.f8ac3883.chunk.css": "/static/css/4.f8ac3883.chunk.css", - "static/js/4.1f09e89e.chunk.js": "/static/js/4.1f09e89e.chunk.js", - "static/js/4.1f09e89e.chunk.js.map": "/static/js/4.1f09e89e.chunk.js.map", - "static/js/5.ef929bfe.chunk.js": "/static/js/5.ef929bfe.chunk.js", - "static/js/5.ef929bfe.chunk.js.map": "/static/js/5.ef929bfe.chunk.js.map", - "static/js/6.88051835.chunk.js": "/static/js/6.88051835.chunk.js", - "static/js/6.88051835.chunk.js.map": "/static/js/6.88051835.chunk.js.map", - "static/js/7.4f3c315a.chunk.js": "/static/js/7.4f3c315a.chunk.js", - "static/js/7.4f3c315a.chunk.js.map": "/static/js/7.4f3c315a.chunk.js.map", - "static/js/8.8e9a1dc7.chunk.js": "/static/js/8.8e9a1dc7.chunk.js", - "static/js/8.8e9a1dc7.chunk.js.map": "/static/js/8.8e9a1dc7.chunk.js.map", - "static/js/9.71667cac.chunk.js": "/static/js/9.71667cac.chunk.js", - "static/js/9.71667cac.chunk.js.map": "/static/js/9.71667cac.chunk.js.map", - "static/js/10.e5247b1b.chunk.js": "/static/js/10.e5247b1b.chunk.js", - "static/js/10.e5247b1b.chunk.js.map": "/static/js/10.e5247b1b.chunk.js.map", - "static/js/11.70112c8f.chunk.js": "/static/js/11.70112c8f.chunk.js", - "static/js/11.70112c8f.chunk.js.map": "/static/js/11.70112c8f.chunk.js.map", - "static/js/12.2265b74f.chunk.js": "/static/js/12.2265b74f.chunk.js", - "static/js/12.2265b74f.chunk.js.map": "/static/js/12.2265b74f.chunk.js.map", - "static/js/13.063a16c9.chunk.js": "/static/js/13.063a16c9.chunk.js", - "static/js/13.063a16c9.chunk.js.map": "/static/js/13.063a16c9.chunk.js.map", - "static/js/14.50a284b1.chunk.js": "/static/js/14.50a284b1.chunk.js", - "static/js/14.50a284b1.chunk.js.map": "/static/js/14.50a284b1.chunk.js.map", - "index.html": "/index.html", - "static/css/3.f8ac3883.chunk.css.map": "/static/css/3.f8ac3883.chunk.css.map", - "static/css/4.f8ac3883.chunk.css.map": "/static/css/4.f8ac3883.chunk.css.map", - "static/css/main.c2a82e71.chunk.css.map": "/static/css/main.c2a82e71.chunk.css.map", - "static/js/2.f196b75b.chunk.js.LICENSE.txt": "/static/js/2.f196b75b.chunk.js.LICENSE.txt", - "static/media/ClusterIcon.f85713df.svg": "/static/media/ClusterIcon.f85713df.svg", - "static/media/DepositIcon.9688e406.svg": "/static/media/DepositIcon.9688e406.svg" - }, - "entrypoints": [ - "static/js/runtime-main.8da12c69.js", - "static/js/2.f196b75b.chunk.js", - "static/css/main.c2a82e71.chunk.css", - "static/js/main.01e9ada9.chunk.js" - ] -} \ No newline at end of file diff --git a/AsbCloudWebApi/wwwroot/favicon.ico b/AsbCloudWebApi/wwwroot/favicon.ico deleted file mode 100644 index 0427b291..00000000 Binary files a/AsbCloudWebApi/wwwroot/favicon.ico and /dev/null differ diff --git a/AsbCloudWebApi/wwwroot/index.html b/AsbCloudWebApi/wwwroot/index.html index d2c883f8..80927d26 100644 --- a/AsbCloudWebApi/wwwroot/index.html +++ b/AsbCloudWebApi/wwwroot/index.html @@ -1 +1 @@ -АСБ Vision
\ No newline at end of file +DDrilling
\ No newline at end of file diff --git a/AsbCloudWebApi/wwwroot/manifest.json b/AsbCloudWebApi/wwwroot/manifest.json deleted file mode 100644 index 1f2f141f..00000000 --- a/AsbCloudWebApi/wwwroot/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/AsbCloudWebApi/wwwroot/robots.txt b/AsbCloudWebApi/wwwroot/robots.txt deleted file mode 100644 index e9e57dc4..00000000 --- a/AsbCloudWebApi/wwwroot/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj index da0e1e97..c0c5ae85 100644 --- a/ConsoleApp1/ConsoleApp1.csproj +++ b/ConsoleApp1/ConsoleApp1.csproj @@ -4,6 +4,7 @@ Exe net6.0 ConsoleApp1.Program + enable diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 5b345220..b3d1d6fb 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,72 +1,39 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.DailyReport; +using AsbCloudDb; +using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.DailyReport; using ClosedXML.Excel; +using DocumentFormat.OpenXml.Wordprocessing; +using Microsoft.EntityFrameworkCore; +using Org.BouncyCastle.Utilities.Collections; using System; +using System.Collections; +using System.Collections.Generic; using System.IO; - +using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace ConsoleApp1 { class Program { + private static AsbCloudDbContext db = ServiceFactory.Context; + // use ServiceFactory to make services static void Main(/*string[] args*/) { - + var h = new Hashtable(); + h.Add("name", 1); + h.Add("name2", "66"); + var v = h["v"]; - var block = new HeadDto() - { - AzimuthAngle = 12, - WellName = "WellName", - ClusterName = "clusterName", - Customer = "customer", - Contractor = "Contractor", - ReportDate = DateTime.Now, - WellDepthIntervalFinishDate = 27.5, - WellDepthIntervalStartDate = 26.5, - BottomholeDepth = 66.6 - }; - var block2 = new BhaDto() - { - BHADescription = "sadasdasdasdasdasdjlaskjdaksjdlasdlalskdklj" - }; - var block3 = new SaubDto(); - var bloks = new DailyReportDto() - { - Head = block, - Saub = block3 - }; + var s = System.Text.Json.JsonSerializer.Serialize(h); - - - var service = new DailyReportMakerExcel(); - var stream = service.MakeReportFromBlocks(bloks); - var filename = "____.xlsx"; - if (File.Exists(filename)) - File.Delete(filename); - using var fileStream = File.OpenWrite(filename); - stream.CopyTo(fileStream); - - return; - - - - - - - //var ms = MakeReportFromBlocks(block,block3); - ////File.Create("", MakeReportFromBlocks(block)); - //using var file = new FileStream("file.xlsx", FileMode.Create, System.IO.FileAccess.Write); - //byte[] bytes = new byte[ms.Length]; - //ms.Read(bytes, 0, (int)ms.Length); - //file.Write(bytes, 0, bytes.Length); - //ms.Close(); + Console.WriteLine($"total time: ms"); + Console.ReadLine(); } - - - - } }