forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/email_notifications
This commit is contained in:
commit
4511eb239f
33
AsbCloudApp/Data/Manuals/ManualDirectoryDto.cs
Normal file
33
AsbCloudApp/Data/Manuals/ManualDirectoryDto.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AsbCloudApp.Data.Manuals;
|
||||
|
||||
/// <summary>
|
||||
/// Директория для хранения инструкций
|
||||
/// </summary>
|
||||
public class ManualDirectoryDto : IId
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Id родительской директории
|
||||
/// </summary>
|
||||
public int? IdParent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Вложенные директории
|
||||
/// </summary>
|
||||
public IEnumerable<ManualDirectoryDto> Children { get; set; } = Enumerable.Empty<ManualDirectoryDto>();
|
||||
|
||||
/// <summary>
|
||||
/// Хранимые инструкции
|
||||
/// </summary>
|
||||
public IEnumerable<ManualDto> Manuals { get; set; } = Enumerable.Empty<ManualDto>();
|
||||
}
|
37
AsbCloudApp/Data/Manuals/ManualDto.cs
Normal file
37
AsbCloudApp/Data/Manuals/ManualDto.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.Manuals;
|
||||
|
||||
/// <summary>
|
||||
/// Инструкция
|
||||
/// </summary>
|
||||
public class ManualDto : IId
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Дата загрузки
|
||||
/// </summary>
|
||||
public DateTime DateDownload { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id автора
|
||||
/// </summary>
|
||||
public int IdAuthor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id директории
|
||||
/// </summary>
|
||||
public int IdDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id категории файла
|
||||
/// </summary>
|
||||
public int IdCategory { get; set; }
|
||||
}
|
@ -87,10 +87,5 @@ namespace AsbCloudApp.Data.ProcessMap
|
||||
/// Плановый процент использования spin master
|
||||
/// </summary>
|
||||
public double UsageSpin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DTO типа секции
|
||||
/// </summary>
|
||||
public WellSectionTypeDto WellSectionType { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
@ -33,16 +33,6 @@ public abstract class TrajectoryGeoDto
|
||||
/// Глубина вертикальная
|
||||
/// </summary>
|
||||
public double? VerticalDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Север отн- но устья
|
||||
/// </summary>
|
||||
public double? NorthOrifice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Восток отн- но устья
|
||||
/// </summary>
|
||||
public double? EastOrifice { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -21,41 +21,6 @@ namespace AsbCloudApp.Data
|
||||
/// </summary>
|
||||
public int IdUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Абсолютная отметка
|
||||
/// </summary>
|
||||
public double AbsoluteMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Восток картографический
|
||||
/// </summary>
|
||||
public double EastCartographic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Север картографический
|
||||
/// </summary>
|
||||
public double NorthCartographic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Пространственная интенсивность
|
||||
/// </summary>
|
||||
public double SpatialIntensity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Интенсивность по углу
|
||||
/// </summary>
|
||||
public double AngleIntensity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Интенсивность по азимуту
|
||||
/// </summary>
|
||||
public double AzimuthIntensity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Смещение от устья
|
||||
/// </summary>
|
||||
public double OrificeOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Радиус цели
|
||||
/// </summary>
|
||||
|
@ -5,6 +5,23 @@ using System.Linq;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// базовая информация о скважине
|
||||
/// </summary>
|
||||
public class WellWithTimezoneDto : WellInfoDto
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[Required]
|
||||
public SimpleTimezoneDto Timezone { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 0 - неизвестно,
|
||||
/// 1 - в работе,
|
||||
/// 2 - завершена
|
||||
/// </summary>
|
||||
public int IdState { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Скважина
|
||||
/// </summary>
|
||||
|
41
AsbCloudApp/Data/WellboreDto.cs
Normal file
41
AsbCloudApp/Data/WellboreDto.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Ствол скважины
|
||||
/// </summary>
|
||||
public class WellboreDto
|
||||
{
|
||||
public WellWithTimezoneDto Well { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Начальная глубина ствола
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Конечная глубина скважины
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата начала первой операции
|
||||
/// </summary>
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата завершения последней операции
|
||||
/// </summary>
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
}
|
@ -47,6 +47,13 @@ namespace AsbCloudApp.Repositories
|
||||
/// <param name="fileName"></param>
|
||||
void DeleteFile(string fileName);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление директории
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="isRecursive"></param>
|
||||
void DeleteDirectory(string path, bool isRecursive);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление всех файлов с диска о которых нет информации в базе
|
||||
/// </summary>
|
||||
|
37
AsbCloudApp/Repositories/IManualDirectoryRepository.cs
Normal file
37
AsbCloudApp/Repositories/IManualDirectoryRepository.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Services;
|
||||
|
||||
namespace AsbCloudApp.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Репозиторий для работы с директориямиы хранящими инструкциями
|
||||
/// </summary>
|
||||
public interface IManualDirectoryRepository : ICrudRepository<ManualDirectoryDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение дерева директорий
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ManualDirectoryDto>> GetTreeAsync(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение одной директории по параметрам
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="idParent"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<ManualDirectoryDto?> GetOrDefaultAsync(string name, int? idParent, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка директории на существование
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> IsExistsAsync(int id, CancellationToken cancellationToken);
|
||||
}
|
59
AsbCloudApp/Requests/TelemetryRequest.cs
Normal file
59
AsbCloudApp/Requests/TelemetryRequest.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры запроса телеметрии
|
||||
/// </summary>
|
||||
public class TelemetryDataRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Максимально допустимое кол-во строк данных
|
||||
/// </summary>
|
||||
public const int MaxTake = 3072;
|
||||
|
||||
/// <summary>
|
||||
/// greater or equal then Date
|
||||
/// </summary>
|
||||
public DateTimeOffset? GeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// less or equal then Date
|
||||
/// </summary>
|
||||
public DateTimeOffset? LeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Делитель для прореживания выборки.
|
||||
/// <list type="bullet">
|
||||
/// <item>1 - без прореживания (default); </item>
|
||||
/// <item>2 - каждое 2-е значение; </item>
|
||||
/// <item>10 - каждое 10-е значение; </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
[Range(0, 300)]
|
||||
public int Divider { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// сортировка/выравнивание данных в запросе по дате
|
||||
/// <list type="bullet">
|
||||
/// <item>0 - более ранние данные вперед; </item>
|
||||
/// <item>1 - более поздние данные вперед; </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
[Range(0, 1)]
|
||||
public int Order { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Пропустить с начала
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int Skip { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Кол-во возвращаемых, но не больше MaxTake
|
||||
/// </summary>
|
||||
[Range(1, MaxTake)]
|
||||
public int Take { get; set; } = 1024;
|
||||
|
||||
}
|
14
AsbCloudApp/Requests/WellboreRequest.cs
Normal file
14
AsbCloudApp/Requests/WellboreRequest.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры запроса для ствола скважины
|
||||
/// </summary>
|
||||
public class WellboreRequest : RequestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Пары идентификаторов скважины и секции
|
||||
/// </summary>
|
||||
public IEnumerable<(int idWell, int? idSection)> Ids { get; set; } = null!;
|
||||
}
|
@ -31,6 +31,14 @@ public interface IAutoGeneratedDailyReportService
|
||||
/// <param name="reportDate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<(string fileName, Stream stream)> GenerateReportAsync(int idWell, DateOnly reportDate,
|
||||
Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение диапазона дат
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken);
|
||||
}
|
64
AsbCloudApp/Services/IManualCatalogService.cs
Normal file
64
AsbCloudApp/Services/IManualCatalogService.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис для работы c каталогом инструкций
|
||||
/// </summary>
|
||||
public interface IManualCatalogService
|
||||
{
|
||||
/// <summary>
|
||||
/// Сохранение файла
|
||||
/// </summary>
|
||||
/// <param name="idDirectory"></param>
|
||||
/// <param name="idAuthor"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> SaveFileAsync(int idDirectory, int idAuthor, string name, Stream stream, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление директории
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="idParent"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddDirectoryAsync(string name, int? idParent, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Обновление директории
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task UpdateDirectoryAsync(int id, string name, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление директории
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteDirectoryAsync(int id, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление файла
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteFileAsync(int id, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение файла
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<(Stream stream, string fileName)?> GetFileAsync(int id, CancellationToken cancellationToken);
|
||||
}
|
@ -6,9 +6,9 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис формирования РТК
|
||||
/// Сервис РТК
|
||||
/// </summary>
|
||||
public interface IProcessMapReportService
|
||||
public interface IProcessMapService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение моделей РТК
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@ -25,6 +26,17 @@ namespace AsbCloudApp.Services
|
||||
Task<IEnumerable<TDto>> GetAsync(int idWell,
|
||||
DateTime dateBegin = default, double intervalSec = 600d,
|
||||
int approxPointsCount = 1024, CancellationToken token = default);
|
||||
Task<IEnumerable<TDto>> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение статистики за период
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetRangeAsync(int idWell, DateTimeOffset start, DateTimeOffset end, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// добавить/изменить данные тех. процесса (используется панелью)
|
||||
|
30
AsbCloudApp/Services/IWellboreService.cs
Normal file
30
AsbCloudApp/Services/IWellboreService.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис для ствола скважины
|
||||
/// </summary>
|
||||
public interface IWellboreService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение ствола скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idSection"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<WellboreDto?> GetWellboreAsync(int idWell, int idSection, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение стволов скважин
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WellboreDto>> GetWellboresAsync(WellboreRequest request, CancellationToken cancellationToken);
|
||||
}
|
8346
AsbCloudDb/Migrations/20230821110455_Update_PlannedTrajectory.Designer.cs
generated
Normal file
8346
AsbCloudDb/Migrations/20230821110455_Update_PlannedTrajectory.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
123
AsbCloudDb/Migrations/20230821110455_Update_PlannedTrajectory.cs
Normal file
123
AsbCloudDb/Migrations/20230821110455_Update_PlannedTrajectory.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Update_PlannedTrajectory : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "absolute_mark",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "angle_intensity",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "azimuth_intensity",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "east_cartographic",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "east_orifice",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "north_cartographic",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "north_orifice",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "orifice_offset",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "spatial_intensity",
|
||||
table: "t_planned_trajectory");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "absolute_mark",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Абсолютная отметка");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "angle_intensity",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Интенсивность по углу");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "azimuth_intensity",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Интенсивность по азимуту");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "east_cartographic",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Восток картографический");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "east_orifice",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Восток отн-но устья");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "north_cartographic",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Север картографический");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "north_orifice",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Север отн-но устья");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "orifice_offset",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Смещение от устья");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "spatial_intensity",
|
||||
table: "t_planned_trajectory",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "Пространственная интенсивность");
|
||||
}
|
||||
}
|
||||
}
|
8539
AsbCloudDb/Migrations/20230907070954_Add_Manuals.Designer.cs
generated
Normal file
8539
AsbCloudDb/Migrations/20230907070954_Add_Manuals.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
148
AsbCloudDb/Migrations/20230907070954_Add_Manuals.cs
Normal file
148
AsbCloudDb/Migrations/20230907070954_Add_Manuals.cs
Normal file
@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_Manuals : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_manual_directory",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
name = table.Column<string>(type: "text", nullable: false, comment: "Название"),
|
||||
id_parent = table.Column<int>(type: "integer", nullable: true, comment: "Id родительской директории")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_manual_directory", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_manual_directory_t_manual_directory_id_parent",
|
||||
column: x => x.id_parent,
|
||||
principalTable: "t_manual_directory",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Директория для инструкций");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_manual",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
name = table.Column<string>(type: "text", nullable: false, comment: "Название"),
|
||||
date_download = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, comment: "Дата загрузки"),
|
||||
id_directory = table.Column<int>(type: "integer", nullable: false, comment: "Id директории"),
|
||||
id_category = table.Column<int>(type: "integer", nullable: false, comment: "Id категории файла"),
|
||||
id_author = table.Column<int>(type: "integer", nullable: false, comment: "Id автора")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_manual", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_manual_t_file_category_id_category",
|
||||
column: x => x.id_category,
|
||||
principalTable: "t_file_category",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_manual_t_manual_directory_id_directory",
|
||||
column: x => x.id_directory,
|
||||
principalTable: "t_manual_directory",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_manual_t_user_id_author",
|
||||
column: x => x.id_author,
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Инструкции");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_file_category",
|
||||
columns: new[] { "id", "name", "short_name" },
|
||||
values: new object[] { 30000, "Инструкции", null });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_permission",
|
||||
columns: new[] { "id", "description", "name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 523, "Разрешить редактирование инструкций", "Manual.edit" },
|
||||
{ 524, "Разрешить получение инструкций", "Manual.get" }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_relation_user_role_permission",
|
||||
columns: new[] { "id_permission", "id_user_role" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 523, 1 },
|
||||
{ 524, 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_manual_id_author",
|
||||
table: "t_manual",
|
||||
column: "id_author");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_manual_id_category",
|
||||
table: "t_manual",
|
||||
column: "id_category");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_manual_id_directory",
|
||||
table: "t_manual",
|
||||
column: "id_directory");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_manual_directory_id_parent",
|
||||
table: "t_manual_directory",
|
||||
column: "id_parent");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_manual");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_manual_directory");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_file_category",
|
||||
keyColumn: "id",
|
||||
keyValue: 30000);
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 523, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 524, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 523);
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 524);
|
||||
}
|
||||
}
|
||||
}
|
8413
AsbCloudDb/Migrations/20230913063219_Add_New_Permissions.Designer.cs
generated
Normal file
8413
AsbCloudDb/Migrations/20230913063219_Add_New_Permissions.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
53
AsbCloudDb/Migrations/20230913063219_Add_New_Permissions.cs
Normal file
53
AsbCloudDb/Migrations/20230913063219_Add_New_Permissions.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_New_Permissions : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_permission",
|
||||
columns: new[] { "id", "description", "name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 525, "Разрешение на редактирование РТК у завершенной скважины", "ProcessMap.editCompletedWell" },
|
||||
{ 526, "Разрешение на редактирование операций у завершенной скважины", "WellOperation.editCompletedWell" }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_relation_user_role_permission",
|
||||
columns: new[] { "id_permission", "id_user_role" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 525, 1 },
|
||||
{ 526, 1 }
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 525, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 526, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 525);
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 526);
|
||||
}
|
||||
}
|
||||
}
|
@ -785,6 +785,11 @@ namespace AsbCloudDb.Migrations
|
||||
{
|
||||
Id = 20000,
|
||||
Name = "Справки по страницам"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 30000,
|
||||
Name = "Инструкции"
|
||||
});
|
||||
});
|
||||
|
||||
@ -1066,6 +1071,83 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasComment("Ограничения по параметрам телеметрии");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("DateDownload")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_download")
|
||||
.HasComment("Дата загрузки");
|
||||
|
||||
b.Property<int>("IdAuthor")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_author")
|
||||
.HasComment("Id автора");
|
||||
|
||||
b.Property<int>("IdCategory")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_category")
|
||||
.HasComment("Id категории файла");
|
||||
|
||||
b.Property<int>("IdDirectory")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_directory")
|
||||
.HasComment("Id директории");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("name")
|
||||
.HasComment("Название");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdAuthor");
|
||||
|
||||
b.HasIndex("IdCategory");
|
||||
|
||||
b.HasIndex("IdDirectory");
|
||||
|
||||
b.ToTable("t_manual");
|
||||
|
||||
b.HasComment("Инструкции");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("IdParent")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_parent")
|
||||
.HasComment("Id родительской директории");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("name")
|
||||
.HasComment("Название");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdParent");
|
||||
|
||||
b.ToTable("t_manual_directory");
|
||||
|
||||
b.HasComment("Директория для инструкций");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Measure", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -2168,6 +2250,30 @@ namespace AsbCloudDb.Migrations
|
||||
Id = 522,
|
||||
Description = "Разрешить удаление всех настроек пользователя",
|
||||
Name = "UserSettings.delete"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 523,
|
||||
Description = "Разрешить редактирование инструкций",
|
||||
Name = "Manual.edit"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 524,
|
||||
Description = "Разрешить получение инструкций",
|
||||
Name = "Manual.get"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 525,
|
||||
Description = "Разрешение на редактирование РТК у завершенной скважины",
|
||||
Name = "ProcessMap.editCompletedWell"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 526,
|
||||
Description = "Разрешение на редактирование операций у завершенной скважины",
|
||||
Name = "WellOperation.editCompletedWell"
|
||||
});
|
||||
});
|
||||
|
||||
@ -2180,26 +2286,11 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<double>("AbsoluteMark")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("absolute_mark")
|
||||
.HasComment("Абсолютная отметка");
|
||||
|
||||
b.Property<double>("AngleIntensity")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("angle_intensity")
|
||||
.HasComment("Интенсивность по углу");
|
||||
|
||||
b.Property<double>("AzimuthGeo")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_geo")
|
||||
.HasComment("Азимут Географ.");
|
||||
|
||||
b.Property<double>("AzimuthIntensity")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_intensity")
|
||||
.HasComment("Интенсивность по азимуту");
|
||||
|
||||
b.Property<double>("AzimuthMagnetic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_magnetic")
|
||||
@ -2210,16 +2301,6 @@ namespace AsbCloudDb.Migrations
|
||||
.HasColumnName("comment")
|
||||
.HasComment("Комментарии");
|
||||
|
||||
b.Property<double>("EastCartographic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("east_cartographic")
|
||||
.HasComment("Восток картографический");
|
||||
|
||||
b.Property<double>("EastOrifice")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("east_orifice")
|
||||
.HasComment("Восток отн-но устья");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
@ -2230,31 +2311,11 @@ namespace AsbCloudDb.Migrations
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<double>("NorthCartographic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("north_cartographic")
|
||||
.HasComment("Север картографический");
|
||||
|
||||
b.Property<double>("NorthOrifice")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("north_orifice")
|
||||
.HasComment("Север отн-но устья");
|
||||
|
||||
b.Property<double>("OrificeOffset")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("orifice_offset")
|
||||
.HasComment("Смещение от устья");
|
||||
|
||||
b.Property<double?>("Radius")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("radius")
|
||||
.HasComment("Радиус цели");
|
||||
|
||||
b.Property<double>("SpatialIntensity")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("spatial_intensity")
|
||||
.HasComment("Пространственная интенсивность");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdateDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("update_date")
|
||||
@ -3755,6 +3816,26 @@ namespace AsbCloudDb.Migrations
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 522
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 523
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 524
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 525
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 526
|
||||
});
|
||||
});
|
||||
|
||||
@ -7687,6 +7768,43 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Telemetry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "Author")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdAuthor")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.FileCategory", "Category")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdCategory")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Directory")
|
||||
.WithMany("Manuals")
|
||||
.HasForeignKey("IdDirectory")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Author");
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("Directory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Parent")
|
||||
.WithMany("Children")
|
||||
.HasForeignKey("IdParent")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Measure", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.MeasureCategory", "Category")
|
||||
@ -8312,6 +8430,13 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("FileMarks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
|
||||
b.Navigation("Manuals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b =>
|
||||
{
|
||||
b.Navigation("Measures");
|
||||
|
@ -3,6 +3,7 @@ using AsbCloudDb.Model.Subsystems;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -77,6 +78,9 @@ namespace AsbCloudDb.Model
|
||||
public DbSet<HelpPage> HelpPages => Set<HelpPage>();
|
||||
public DbSet<Notification> Notifications => Set<Notification>();
|
||||
public DbSet<NotificationCategory> NotificationCategories => Set<NotificationCategory>();
|
||||
public DbSet<Manual> Manuals => Set<Manual>();
|
||||
public DbSet<ManualDirectory> ManualDirectories => Set<ManualDirectory>();
|
||||
|
||||
|
||||
public AsbCloudDbContext() : base()
|
||||
{
|
||||
@ -388,6 +392,18 @@ namespace AsbCloudDb.Model
|
||||
entity.HasKey(x => new { x.IdWell, x.IdUser });
|
||||
});
|
||||
|
||||
modelBuilder.Entity<ManualDirectory>()
|
||||
.HasOne(mf => mf.Parent)
|
||||
.WithMany(mf => mf.Children)
|
||||
.HasForeignKey(mf => mf.IdParent)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Manual>()
|
||||
.HasOne(m => m.Directory)
|
||||
.WithMany(f => f.Manuals)
|
||||
.HasForeignKey(m => m.IdDirectory)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
DefaultData.DefaultContextData.Fill(modelBuilder);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,9 @@
|
||||
new () {Id = 10042, Name = "Паспорт скважины (заполняется геологами)"},
|
||||
new () {Id = 10043, Name = "Фактические данные бурения (вставляются в паспорт скважины)"},
|
||||
|
||||
new () {Id = 20000, Name = "Справки по страницам"}
|
||||
new () {Id = 20000, Name = "Справки по страницам"},
|
||||
|
||||
new() { Id = 30000, Name = "Инструкции"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +156,12 @@
|
||||
new() { Id = 521, Name = "HelpPage.edit", Description = "Разрешить создание справок по страницам"},
|
||||
|
||||
new() { Id = 522, Name = "UserSettings.delete", Description = "Разрешить удаление всех настроек пользователя"},
|
||||
|
||||
new() { Id = 523, Name = "Manual.edit", Description = "Разрешить редактирование инструкций" },
|
||||
new() { Id = 524, Name = "Manual.get", Description = "Разрешить получение инструкций"},
|
||||
|
||||
new (){ Id = 525, Name = "ProcessMap.editCompletedWell", Description = "Разрешение на редактирование РТК у завершенной скважины"},
|
||||
new (){ Id = 526, Name = "WellOperation.editCompletedWell", Description = "Разрешение на редактирование операций у завершенной скважины"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ namespace AsbCloudDb.Model.DefaultData
|
||||
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}, new (){ IdUserRole = 1, IdPermission = 506}, new (){ IdUserRole = 1, IdPermission = 510}, new (){ IdUserRole = 1, IdPermission = 511}, new (){ IdUserRole = 1, IdPermission = 512}, new (){ IdUserRole = 1, IdPermission = 513}, new (){ IdUserRole = 1, IdPermission = 514}, new (){ IdUserRole = 1, IdPermission = 515},
|
||||
};
|
||||
var allPermissions = (new EntityFillerPermission()).GetData();
|
||||
foreach ( var permission in allPermissions)
|
||||
|
@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -70,6 +71,8 @@ namespace AsbCloudDb.Model
|
||||
DbSet<HelpPage> HelpPages { get; }
|
||||
DbSet<Notification> Notifications { get; }
|
||||
DbSet<NotificationCategory> NotificationCategories { get; }
|
||||
DbSet<Manual> Manuals { get; }
|
||||
DbSet<ManualDirectory> ManualDirectories { get; }
|
||||
DatabaseFacade Database { get; }
|
||||
|
||||
Task<int> RefreshMaterializedViewAsync(string mwName, CancellationToken token);
|
||||
|
38
AsbCloudDb/Model/Manuals/Manual.cs
Normal file
38
AsbCloudDb/Model/Manuals/Manual.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudDb.Model.Manuals;
|
||||
|
||||
[Table("t_manual"), Comment("Инструкции")]
|
||||
public class Manual : IId
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name"), Comment("Название")]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
[Column("date_download"), Comment("Дата загрузки")]
|
||||
public DateTime DateDownload { get; set; }
|
||||
|
||||
[Column("id_directory"), Comment("Id директории")]
|
||||
public int IdDirectory { get; set; }
|
||||
|
||||
[Column("id_category"), Comment("Id категории файла")]
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
[Column("id_author"), Comment("Id автора")]
|
||||
public int IdAuthor { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdDirectory))]
|
||||
public virtual ManualDirectory Directory { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdCategory))]
|
||||
public virtual FileCategory Category { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdAuthor))]
|
||||
public virtual User Author { get; set; } = null!;
|
||||
}
|
27
AsbCloudDb/Model/Manuals/ManualDirectory.cs
Normal file
27
AsbCloudDb/Model/Manuals/ManualDirectory.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudDb.Model.Manuals;
|
||||
|
||||
[Table("t_manual_directory"), Comment("Директория для инструкций")]
|
||||
public class ManualDirectory : IId
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name"), Comment("Название")]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
[Column("id_parent"), Comment("Id родительской директории")]
|
||||
public int? IdParent { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdParent))]
|
||||
public virtual ManualDirectory? Parent { get; set; }
|
||||
|
||||
public virtual ICollection<ManualDirectory>? Children { get; set; }
|
||||
|
||||
public virtual ICollection<Manual>? Manuals { get; set; }
|
||||
}
|
@ -35,33 +35,6 @@ namespace AsbCloudDb.Model
|
||||
[Column("vertical_depth"), Comment("Глубина вертикальная")]
|
||||
public double VerticalDepth { get; set; }
|
||||
|
||||
[Column("absolute_mark"), Comment("Абсолютная отметка")]
|
||||
public double AbsoluteMark { get; set; }
|
||||
|
||||
[Column("north_orifice"), Comment("Север отн-но устья")]
|
||||
public double NorthOrifice { get; set; }
|
||||
|
||||
[Column("east_orifice"), Comment("Восток отн-но устья")]
|
||||
public double EastOrifice { get; set; }
|
||||
|
||||
[Column("east_cartographic"), Comment("Восток картографический")]
|
||||
public double EastCartographic { get; set; }
|
||||
|
||||
[Column("north_cartographic"), Comment("Север картографический")]
|
||||
public double NorthCartographic { get; set; }
|
||||
|
||||
[Column("spatial_intensity"), Comment("Пространственная интенсивность")]
|
||||
public double SpatialIntensity { get; set; }
|
||||
|
||||
[Column("angle_intensity"), Comment("Интенсивность по углу")]
|
||||
public double AngleIntensity { get; set; }
|
||||
|
||||
[Column("azimuth_intensity"), Comment("Интенсивность по азимуту")]
|
||||
public double AzimuthIntensity { get; set; }
|
||||
|
||||
[Column("orifice_offset"), Comment("Смещение от устья")]
|
||||
public double OrificeOffset { get; set; }
|
||||
|
||||
[Column("comment"), Comment("Комментарии")]
|
||||
public string? Comment { get; set; }
|
||||
|
||||
|
@ -23,8 +23,10 @@ using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudApp.Services.Notifications;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
||||
|
||||
namespace AsbCloudInfrastructure
|
||||
@ -144,7 +146,7 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
||||
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
||||
services.AddTransient<IProcessMapReportMakerService, ProcessMapReportMakerService>();
|
||||
services.AddTransient<IProcessMapReportService, ProcessMapReportService>();
|
||||
services.AddTransient<IProcessMapService, ProcessMapService>();
|
||||
services.AddTransient<WellInfoService>();
|
||||
services.AddTransient<IHelpPageService, HelpPageService>();
|
||||
|
||||
@ -222,6 +224,12 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>();
|
||||
services.AddTransient<IAutoGeneratedDailyReportMakerService, AutoGeneratedDailyReportMakerService>();
|
||||
|
||||
services.AddTransient<IManualDirectoryRepository, ManualDirectoryRepository>();
|
||||
services.AddTransient<IManualCatalogService, ManualCatalogService>();
|
||||
services.AddTransient<ICrudRepository<ManualDto>, CrudRepositoryBase<ManualDto, Manual>>();
|
||||
|
||||
services.AddTransient<IWellboreService, WellboreService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -34,6 +35,23 @@ public class FileStorageRepository : IFileStorageRepository
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path, bool isRecursive)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
return;
|
||||
|
||||
if (!isRecursive)
|
||||
{
|
||||
var files = Directory.GetFiles(path);
|
||||
var directories = Directory.GetDirectories(path);
|
||||
|
||||
if (files.Length != 0 || directories.Length != 0)
|
||||
throw new InvalidOperationException("Директория не пуста и не может быть удалена");
|
||||
}
|
||||
|
||||
Directory.Delete(path, isRecursive);
|
||||
}
|
||||
|
||||
public void DeleteFile(string fileName)
|
||||
{
|
||||
if (File.Exists(fileName))
|
||||
|
@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository;
|
||||
|
||||
public class ManualDirectoryRepository : CrudRepositoryBase<ManualDirectoryDto, ManualDirectory>, IManualDirectoryRepository
|
||||
{
|
||||
public ManualDirectoryRepository(IAsbCloudDbContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ManualDirectoryDto>> GetTreeAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var directories = await dbContext.ManualDirectories
|
||||
.Include(m => m.Manuals)
|
||||
.Include(m => m.Parent)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
return BuildTree(directories).Select(x => x.Adapt<ManualDirectoryDto>());
|
||||
}
|
||||
|
||||
public async Task<ManualDirectoryDto?> GetOrDefaultAsync(string name, int? idParent, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await dbContext.ManualDirectories
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(m => m.Name == name &&
|
||||
m.IdParent == idParent, cancellationToken);
|
||||
|
||||
if (entity is null)
|
||||
return null;
|
||||
|
||||
return Convert(entity);
|
||||
}
|
||||
|
||||
public Task<bool> IsExistsAsync(int id, CancellationToken cancellationToken) =>
|
||||
dbContext.ManualDirectories.AnyAsync(d => d.Id == id, cancellationToken);
|
||||
|
||||
private static IEnumerable<ManualDirectory> BuildTree(IEnumerable<ManualDirectory> directories)
|
||||
{
|
||||
var directoryDict = directories.ToDictionary(f => f.Id);
|
||||
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
if (directory.IdParent.HasValue && directoryDict.TryGetValue(directory.IdParent.Value, out var parent))
|
||||
{
|
||||
parent.Children ??= new List<ManualDirectory>();
|
||||
parent.Children.Add(directory);
|
||||
}
|
||||
}
|
||||
|
||||
return directories.Where(f => f.IdParent == null);
|
||||
}
|
||||
}
|
@ -41,8 +41,6 @@ namespace AsbCloudInfrastructure.Repository
|
||||
IdWell = idWell,
|
||||
AzimuthMagnetic = coord.Svymtf,
|
||||
VerticalDepth = coord.Deptsvyv,
|
||||
NorthOrifice = coord.Svyns,
|
||||
EastOrifice = coord.Svyew,
|
||||
WellboreDepth = coord.Deptsvym!.Value,
|
||||
ZenithAngle = coord.Svyinc!.Value,
|
||||
AzimuthGeo = coord.Svyazc!.Value
|
||||
|
@ -6,7 +6,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
@ -15,7 +14,6 @@ using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudApp.Services.Subsystems;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.SAUB;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
||||
|
||||
@ -25,7 +23,6 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
private readonly TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache;
|
||||
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
||||
private readonly ICrudRepository<SubsystemDto> subsystemRepository;
|
||||
private readonly ILimitingParameterService limitingParameterService;
|
||||
@ -33,7 +30,6 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
|
||||
public AutoGeneratedDailyReportService(IWellService wellService,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache,
|
||||
ISubsystemOperationTimeService subsystemOperationTimeService,
|
||||
ICrudRepository<SubsystemDto> subsystemRepository,
|
||||
ILimitingParameterService limitingParameterService,
|
||||
@ -41,7 +37,6 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
{
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
this.wellService = wellService;
|
||||
this.telemetryDataCache = telemetryDataCache;
|
||||
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
||||
this.subsystemRepository = subsystemRepository;
|
||||
this.limitingParameterService = limitingParameterService;
|
||||
@ -67,13 +62,11 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
if (!well.IdTelemetry.HasValue)
|
||||
throw new ArgumentInvalidException("Телеметрия для скважины отсутствует", nameof(idWell));
|
||||
|
||||
var datesRange = telemetryDataCache.GetOrDefaultDataDateRange(well.IdTelemetry.Value);
|
||||
var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
|
||||
|
||||
if (datesRange is null)
|
||||
return result;
|
||||
|
||||
result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
|
||||
|
||||
if (request.StartDate.HasValue)
|
||||
{
|
||||
var startDate = new DateTime(request.StartDate.Value.Year, request.StartDate.Value.Month,
|
||||
@ -92,6 +85,9 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
datesRange.To = finishDate;
|
||||
}
|
||||
|
||||
if (datesRange.From.AddDays(result.Skip) <= datesRange.To)
|
||||
result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
|
||||
|
||||
for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++)
|
||||
{
|
||||
var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day));
|
||||
@ -109,7 +105,7 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<(string fileName, Stream stream)> GenerateReportAsync(int idWell, DateOnly reportDate,
|
||||
public async Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var startDate = new DateTime(reportDate.Year, reportDate.Month, reportDate.Day);
|
||||
@ -144,6 +140,21 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
return (report.FileName, stream);
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var factOperations = await GetFactOperationsAsync(idWell, null, null,
|
||||
cancellationToken);
|
||||
|
||||
if (!factOperations.Any())
|
||||
return null;
|
||||
|
||||
return new DatesRangeDto
|
||||
{
|
||||
From = factOperations.Min(o => o.DateStart).Date,
|
||||
To = factOperations.Max(o => o.DateStart).Date
|
||||
};
|
||||
}
|
||||
|
||||
private HeadBlockDto CreateHeadBlock(WellDto well, IEnumerable<WellOperationDto> factOperations)
|
||||
{
|
||||
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
|
||||
@ -199,8 +210,8 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
});
|
||||
}
|
||||
|
||||
private Task<IEnumerable<WellOperationDto>> GetFactOperationsAsync(int idWell, DateTime startDate,
|
||||
DateTime finishDate, CancellationToken cancellationToken)
|
||||
private async Task<IOrderedEnumerable<WellOperationDto>> GetFactOperationsAsync(int idWell, DateTime? startDate,
|
||||
DateTime? finishDate, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new WellOperationRequest
|
||||
{
|
||||
@ -211,7 +222,8 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
||||
SortFields = new[] { "DateStart asc" },
|
||||
};
|
||||
|
||||
return wellOperationRepository.GetAsync(request, cancellationToken);
|
||||
return (await wellOperationRepository.GetAsync(request, cancellationToken))
|
||||
.OrderBy(w => w.DateStart);
|
||||
}
|
||||
|
||||
private Task<IEnumerable<SubsystemStatDto>?> GetSubsystemStatsAsync(int idWell, DateTime startDate,
|
||||
|
180
AsbCloudInfrastructure/Services/ManualCatalogService.cs
Normal file
180
AsbCloudInfrastructure/Services/ManualCatalogService.cs
Normal file
@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services;
|
||||
|
||||
public class ManualCatalogService : IManualCatalogService
|
||||
{
|
||||
private const int IdFileCategory = 30000;
|
||||
|
||||
private readonly IEnumerable<string> validExtensions = new[]
|
||||
{
|
||||
".pdf",
|
||||
".mp4"
|
||||
};
|
||||
|
||||
private readonly string directoryFiles;
|
||||
private readonly IFileStorageRepository fileStorageRepository;
|
||||
private readonly IManualDirectoryRepository manualDirectoryRepository;
|
||||
private readonly ICrudRepository<ManualDto> manualRepository;
|
||||
|
||||
public ManualCatalogService(IFileStorageRepository fileStorageRepository,
|
||||
IManualDirectoryRepository manualDirectoryRepository,
|
||||
ICrudRepository<ManualDto> manualRepository,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
this.fileStorageRepository = fileStorageRepository;
|
||||
this.manualDirectoryRepository = manualDirectoryRepository;
|
||||
this.manualRepository = manualRepository;
|
||||
directoryFiles = configuration.GetValue<string>("DirectoryManualFiles");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(directoryFiles))
|
||||
directoryFiles = "manuals";
|
||||
}
|
||||
|
||||
public async Task<int> SaveFileAsync(int idDirectory, int idAuthor, string name, Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
var extension = Path.GetExtension(name);
|
||||
|
||||
if (!validExtensions.Contains(extension))
|
||||
throw new ArgumentInvalidException(
|
||||
$"Невозможно загрузить файл с расширением '{extension}'. Допустимые форматы файлов: {string.Join(", ", validExtensions)}",
|
||||
extension);
|
||||
|
||||
var path = await BuildFilePathAsync(idDirectory, name, cancellationToken);
|
||||
|
||||
await fileStorageRepository.SaveFileAsync(path, stream, cancellationToken);
|
||||
|
||||
var manual = new ManualDto
|
||||
{
|
||||
Name = name,
|
||||
DateDownload = DateTime.UtcNow,
|
||||
IdDirectory = idDirectory,
|
||||
IdCategory = IdFileCategory,
|
||||
IdAuthor = idAuthor
|
||||
};
|
||||
|
||||
return await manualRepository.InsertAsync(manual, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> AddDirectoryAsync(string name, int? idParent, CancellationToken cancellationToken)
|
||||
{
|
||||
if (idParent.HasValue && !await manualDirectoryRepository.IsExistsAsync(idParent.Value, cancellationToken))
|
||||
throw new ArgumentInvalidException("Родительской директории не существует", nameof(idParent));
|
||||
|
||||
var directory = new ManualDirectoryDto
|
||||
{
|
||||
Name = name,
|
||||
IdParent = idParent,
|
||||
};
|
||||
|
||||
if (await IsExistDirectoryAsync(directory, cancellationToken))
|
||||
throw new ArgumentInvalidException("Директория с таким названием уже существует", name);
|
||||
|
||||
return await manualDirectoryRepository.InsertAsync(directory, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task UpdateDirectoryAsync(int id, string name, CancellationToken cancellationToken)
|
||||
{
|
||||
var directory = await manualDirectoryRepository.GetOrDefaultAsync(id, cancellationToken)
|
||||
?? throw new ArgumentInvalidException($"Директории с Id: {id} не существует", nameof(id));
|
||||
|
||||
directory.Name = name;
|
||||
|
||||
if (await IsExistDirectoryAsync(directory, cancellationToken))
|
||||
throw new ArgumentInvalidException("Директория с таким названием уже существует", name);
|
||||
|
||||
await manualDirectoryRepository.UpdateAsync(directory, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteDirectoryAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
var directory = await manualDirectoryRepository.GetOrDefaultAsync(id, cancellationToken);
|
||||
|
||||
if (directory is null)
|
||||
return 0;
|
||||
|
||||
var path = fileStorageRepository.MakeFilePath(directoryFiles, IdFileCategory.ToString(),
|
||||
await BuildDirectoryPathAsync(id, cancellationToken));
|
||||
|
||||
try
|
||||
{
|
||||
fileStorageRepository.DeleteDirectory(path, true);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
throw new ArgumentInvalidException(ex.Message, nameof(id));
|
||||
}
|
||||
|
||||
return await manualDirectoryRepository.DeleteAsync(directory.Id, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteFileAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
var manual = await manualRepository.GetOrDefaultAsync(id, cancellationToken);
|
||||
|
||||
if (manual is null)
|
||||
return 0;
|
||||
|
||||
var filePath = await BuildFilePathAsync(manual.IdDirectory, manual.Name, cancellationToken);
|
||||
|
||||
fileStorageRepository.DeleteFile(filePath);
|
||||
|
||||
return await manualRepository.DeleteAsync(manual.Id, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<(Stream stream, string fileName)?> GetFileAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
var manual = await manualRepository.GetOrDefaultAsync(id, cancellationToken);
|
||||
|
||||
if (manual is null)
|
||||
return null;
|
||||
|
||||
var path = await BuildFilePathAsync(manual.IdDirectory, manual.Name, cancellationToken);
|
||||
var fileStream = new FileStream(path, FileMode.Open);
|
||||
return (fileStream, manual.Name);
|
||||
}
|
||||
|
||||
private async Task<bool> IsExistDirectoryAsync(ManualDirectoryDto directory, CancellationToken cancellationToken)
|
||||
{
|
||||
var existingDirectory = await manualDirectoryRepository.GetOrDefaultAsync(directory.Name, directory.IdParent,
|
||||
cancellationToken);
|
||||
|
||||
return existingDirectory is not null && directory.Id != existingDirectory.Id;
|
||||
}
|
||||
|
||||
private async Task<string> BuildDirectoryPathAsync(int idDirectory, CancellationToken cancellationToken)
|
||||
{
|
||||
var directiories = await manualDirectoryRepository.GetAllAsync(cancellationToken);
|
||||
|
||||
var directory = directiories.FirstOrDefault(d => d.Id == idDirectory)
|
||||
?? throw new ArgumentInvalidException($"Директории с Id: {idDirectory} не существует", nameof(idDirectory));
|
||||
|
||||
var pathSegments = new List<int> { directory.Id };
|
||||
|
||||
while (directory.IdParent.HasValue)
|
||||
{
|
||||
directory = directiories.FirstOrDefault(d => d.Id == directory.IdParent.Value);
|
||||
|
||||
pathSegments.Insert(0, directory.Id);
|
||||
}
|
||||
|
||||
return string.Join("/", pathSegments);
|
||||
}
|
||||
|
||||
private async Task<string> BuildFilePathAsync(int idDirectory, string name, CancellationToken cancellationToken)
|
||||
{
|
||||
var directoryPath = await BuildDirectoryPathAsync(idDirectory, cancellationToken);
|
||||
|
||||
return fileStorageRepository.MakeFilePath(directoryFiles, IdFileCategory.ToString(), Path.Combine(directoryPath, name));
|
||||
}
|
||||
}
|
@ -75,6 +75,8 @@ public class ProcessMapPlanImportService : IProcessMapPlanImportService
|
||||
|
||||
public async Task<Stream> ExportAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
|
||||
|
||||
var processMapPlans = (await processMapPlanRepository.GetByIdWellAsync(idWell,
|
||||
cancellationToken)).ToArray();
|
||||
|
||||
@ -120,7 +122,7 @@ public class ProcessMapPlanImportService : IProcessMapPlanImportService
|
||||
|
||||
private void AddToRow(IXLRow row, ProcessMapPlanDto processMap)
|
||||
{
|
||||
row.Cell(columnWellSectionType).Value = processMap.WellSectionType.Caption;
|
||||
row.Cell(columnWellSectionType).Value = sections.First(x => x.Id == processMap.IdWellSectionType).Caption;
|
||||
row.Cell(columnMode).Value = GetModeCaption(processMap.IdMode);
|
||||
row.Cell(columnDepthStart).Value = processMap.DepthStart;
|
||||
row.Cell(columnDepthEnd).Value = processMap.DepthEnd;
|
||||
|
@ -13,13 +13,13 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
public class ProcessMapReportMakerService : IProcessMapReportMakerService
|
||||
{
|
||||
const int firstColumn = 2;
|
||||
const int lastColumn = 49;
|
||||
const int lastColumn = 42;
|
||||
|
||||
const int headerRowsCount = 5;
|
||||
|
||||
private readonly IProcessMapReportService processMapService;
|
||||
private readonly IProcessMapService processMapService;
|
||||
|
||||
public ProcessMapReportMakerService(IProcessMapReportService processMapService)
|
||||
public ProcessMapReportMakerService(IProcessMapService processMapService)
|
||||
{
|
||||
this.processMapService = processMapService;
|
||||
}
|
||||
|
Binary file not shown.
@ -12,14 +12,14 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
{
|
||||
|
||||
public partial class ProcessMapReportService : IProcessMapReportService
|
||||
public partial class ProcessMapService : IProcessMapService
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||
|
||||
public ProcessMapReportService(
|
||||
public ProcessMapService(
|
||||
IWellService wellService,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
IProcessMapPlanRepository processMapPlanRepository,
|
@ -1,4 +1,6 @@
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb;
|
||||
using AsbCloudDb.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -13,7 +15,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
{
|
||||
public abstract class TelemetryDataBaseService<TDto, TEntity> : ITelemetryDataService<TDto>
|
||||
where TDto : AsbCloudApp.Data.ITelemetryData
|
||||
where TEntity : class, ITelemetryData
|
||||
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||
{
|
||||
protected readonly IAsbCloudDbContext db;
|
||||
protected readonly ITelemetryService telemetryService;
|
||||
@ -136,16 +138,111 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
}
|
||||
|
||||
var entities = await query
|
||||
.OrderBy(d => d.DateTime)
|
||||
.AsNoTracking()
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var dtos = entities.Select(e => Convert(e, timezone.Hours));
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell, AsbCloudApp.Requests.TelemetryDataRequest request, CancellationToken token)
|
||||
{
|
||||
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
|
||||
if (telemetry is null)
|
||||
return Enumerable.Empty<TDto>();
|
||||
|
||||
var timezone = telemetryService.GetTimezone(telemetry.Id);
|
||||
|
||||
var cache = telemetryDataCache.GetOrDefault(telemetry.Id, request);
|
||||
if(cache is not null)
|
||||
return cache;
|
||||
|
||||
var dbSet = db.Set<TEntity>();
|
||||
|
||||
var query = dbSet
|
||||
.Where(d => d.IdTelemetry == telemetry.Id)
|
||||
.AsNoTracking();
|
||||
|
||||
if (request.GeDate.HasValue)
|
||||
{
|
||||
var geDate = request.GeDate.Value.UtcDateTime;
|
||||
query = query.Where(d => d.DateTime >= geDate);
|
||||
}
|
||||
|
||||
if (request.LeDate.HasValue)
|
||||
{
|
||||
var leDate = request.LeDate.Value.UtcDateTime;
|
||||
query = query.Where(d => d.DateTime <= leDate);
|
||||
}
|
||||
|
||||
if (request.Divider > 1)
|
||||
query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0);
|
||||
|
||||
switch (request.Order)
|
||||
{
|
||||
case 1:// Поздние вперед
|
||||
query = query
|
||||
.OrderByDescending(d => d.DateTime)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take)
|
||||
.OrderBy(d => d.DateTime);
|
||||
break;
|
||||
default:// Ранние вперед
|
||||
query = query
|
||||
.OrderBy(d => d.DateTime)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take);
|
||||
break;
|
||||
}
|
||||
|
||||
var entities = await query
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var dtos = entities.Select(e => Convert(e, timezone.Hours));
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<DatesRangeDto?> GetRangeAsync(
|
||||
int idWell,
|
||||
DateTimeOffset start,
|
||||
DateTimeOffset end,
|
||||
CancellationToken token)
|
||||
{
|
||||
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
|
||||
if (telemetry is null)
|
||||
return default;
|
||||
|
||||
var timezone = telemetryService.GetTimezone(telemetry.Id);
|
||||
var startUtc = start.ToOffset(TimeSpan.Zero);
|
||||
var endUtc = end.ToOffset(TimeSpan.Zero);
|
||||
|
||||
var dbSet = db.Set<TEntity>();
|
||||
var query = dbSet
|
||||
.Where(i => i.IdTelemetry == telemetry.Id)
|
||||
.Where(i => i.DateTime >= startUtc)
|
||||
.Where(i => i.DateTime <= endUtc)
|
||||
.GroupBy(i => i.IdTelemetry)
|
||||
.Select(g => new
|
||||
{
|
||||
DateStart = g.Min(i => i.DateTime),
|
||||
DateEnd = g.Max(i => i.DateTime),
|
||||
});
|
||||
|
||||
var data = await query.FirstOrDefaultAsync(token);
|
||||
if (data is null)
|
||||
return default;
|
||||
|
||||
return new DatesRangeDto
|
||||
{
|
||||
From = data.DateStart.ToRemoteDateTime(timezone.Hours),
|
||||
To = data.DateEnd.ToRemoteDateTime(timezone.Hours),
|
||||
};
|
||||
}
|
||||
|
||||
public abstract TDto Convert(TEntity src, double timezoneOffset);
|
||||
|
||||
public abstract TEntity Convert(TDto src, double timezoneOffset);
|
||||
|
@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using System.Threading;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.SAUB
|
||||
{
|
||||
@ -21,6 +22,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
{
|
||||
public TDto? FirstByDate { get; init; }
|
||||
public CyclycArray<TDto> LastData { get; init; } = null!;
|
||||
public double TimezoneHours { get; init; } = 5;
|
||||
}
|
||||
|
||||
private IServiceProvider provider = null!;
|
||||
@ -225,8 +227,62 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
{
|
||||
FirstByDate = first,
|
||||
LastData = cacheItem,
|
||||
TimezoneHours = hoursOffset,
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
public IEnumerable<TDto>? GetOrDefault(int idTelemetry, TelemetryDataRequest request)
|
||||
{
|
||||
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
||||
return null;
|
||||
|
||||
IEnumerable<TDto> data = cacheItem.LastData;
|
||||
|
||||
if (!data.Any())
|
||||
return null;
|
||||
|
||||
if (request.GeDate.HasValue)
|
||||
{
|
||||
var geDate = request.GeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours);
|
||||
if (data.First().DateTime > geDate)
|
||||
return null;
|
||||
|
||||
data = data.Where(d => d.DateTime >= geDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (request.Order == 0)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (request.LeDate.HasValue)
|
||||
{
|
||||
var leDate = request.LeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours);
|
||||
data = data.Where(d => d.DateTime >= request.LeDate);
|
||||
}
|
||||
|
||||
if (request.Divider > 1)
|
||||
data = data.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0);
|
||||
|
||||
switch (request.Order)
|
||||
{
|
||||
case 1: // Поздние вперед
|
||||
data = data
|
||||
.OrderByDescending(d => d.DateTime)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take)
|
||||
.OrderBy(d => d.DateTime);
|
||||
break;
|
||||
default: // Ранние вперед
|
||||
data = data
|
||||
.OrderBy(d => d.DateTime)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take);
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,8 @@ namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
private const int ColumnAzimuthGeo = 3;
|
||||
private const int ColumnAzimuthMagnetic = 4;
|
||||
private const int ColumnVerticalDepth = 5;
|
||||
private const int ColumnAbsoluteMark = 6;
|
||||
private const int ColumnNorthOrifice = 7;
|
||||
private const int ColumnEastOrifice = 8;
|
||||
private const int ColumnEastCartographic = 9;
|
||||
private const int ColumnNorthCartographic = 10;
|
||||
private const int ColumnSpatialIntensity = 11;
|
||||
private const int ColumnAngleIntensity = 12;
|
||||
private const int ColumnAzimuthIntensity = 13;
|
||||
private const int ColumnOrificeOffset = 14;
|
||||
private const int ColumnComment = 15;
|
||||
private const int ColumnRadius = 6;
|
||||
private const int ColumnComment = 7;
|
||||
|
||||
public PlannedTrajectoryImportService(IWellService wellService, ITrajectoryPlanRepository plannedTrajectoryService)
|
||||
{
|
||||
@ -107,15 +99,7 @@ namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
row.Cell(ColumnAzimuthGeo).Value = trajectory.AzimuthGeo;
|
||||
row.Cell(ColumnAzimuthMagnetic).Value = trajectory.AzimuthMagnetic;
|
||||
row.Cell(ColumnVerticalDepth).Value = trajectory.VerticalDepth;
|
||||
row.Cell(ColumnAbsoluteMark).Value = trajectory.AbsoluteMark;
|
||||
row.Cell(ColumnNorthOrifice).Value = trajectory.NorthOrifice;
|
||||
row.Cell(ColumnEastOrifice).Value = trajectory.EastOrifice;
|
||||
row.Cell(ColumnEastCartographic).Value = trajectory.EastCartographic;
|
||||
row.Cell(ColumnNorthCartographic).Value = trajectory.NorthCartographic;
|
||||
row.Cell(ColumnSpatialIntensity).Value = trajectory.SpatialIntensity;
|
||||
row.Cell(ColumnAngleIntensity).Value = trajectory.AngleIntensity;
|
||||
row.Cell(ColumnAzimuthIntensity).Value = trajectory.AzimuthIntensity;
|
||||
row.Cell(ColumnOrificeOffset).Value = trajectory.OrificeOffset;
|
||||
row.Cell(ColumnRadius).Value = trajectory.Radius;
|
||||
row.Cell(ColumnComment).Value = trajectory.Comment;
|
||||
}
|
||||
|
||||
@ -158,7 +142,7 @@ namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
|
||||
private IEnumerable<TrajectoryGeoPlanDto> ParseSheet(IXLWorksheet sheet)
|
||||
{
|
||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 15)
|
||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
|
||||
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
||||
|
||||
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
||||
@ -194,15 +178,7 @@ namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
var _azimuthGeo = row.Cell(ColumnAzimuthGeo).Value;
|
||||
var _azimuthMagnetic = row.Cell(ColumnAzimuthMagnetic).Value;
|
||||
var _verticalDepth = row.Cell(ColumnVerticalDepth).Value;
|
||||
var _absoluteMark = row.Cell(ColumnAbsoluteMark).Value;
|
||||
var _northOrifice = row.Cell(ColumnNorthOrifice).Value;
|
||||
var _eastOrifice = row.Cell(ColumnEastOrifice).Value;
|
||||
var _eastCartographic = row.Cell(ColumnEastCartographic).Value;
|
||||
var _northCartographic = row.Cell(ColumnNorthCartographic).Value;
|
||||
var _spatialIntensity = row.Cell(ColumnSpatialIntensity).Value;
|
||||
var _angleIntensity = row.Cell(ColumnAngleIntensity).Value;
|
||||
var _azimuthIntensity = row.Cell(ColumnAzimuthIntensity).Value;
|
||||
var _orificeOffset = row.Cell(ColumnOrificeOffset).Value;
|
||||
var _radius = row.Cell(ColumnRadius).Value;
|
||||
var _comment = row.Cell(ColumnComment).Value;
|
||||
|
||||
var trajectoryRow = new TrajectoryGeoPlanDto();
|
||||
@ -219,15 +195,8 @@ namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
trajectoryRow.AzimuthGeo = getDoubleValue(_azimuthGeo, "Азимут географический", row);
|
||||
trajectoryRow.AzimuthMagnetic = getDoubleValue(_azimuthMagnetic, "Азимут магнитный", row);
|
||||
trajectoryRow.VerticalDepth = getDoubleValue(_verticalDepth, "Глубина вертикальная", row);
|
||||
trajectoryRow.AbsoluteMark = getDoubleValue(_absoluteMark, "Абсолютная отметка", row);
|
||||
trajectoryRow.NorthOrifice = getDoubleValue(_northOrifice, "Север относительно устья", row);
|
||||
trajectoryRow.EastOrifice = getDoubleValue(_eastOrifice, "Восток относительно устья", row);
|
||||
trajectoryRow.EastCartographic = getDoubleValue(_eastCartographic, "Восток картографический", row);
|
||||
trajectoryRow.NorthCartographic = getDoubleValue(_northCartographic, "Север картографический", row);
|
||||
trajectoryRow.SpatialIntensity = getDoubleValue(_spatialIntensity, "Простр. интенсивность", row);
|
||||
trajectoryRow.AngleIntensity = getDoubleValue(_angleIntensity, "Интенсивность по углу", row);
|
||||
trajectoryRow.AzimuthIntensity = getDoubleValue(_azimuthIntensity, "Интенсивность по азимуту", row);
|
||||
trajectoryRow.OrificeOffset = getDoubleValue(_orificeOffset, "Смещение от устья", row);
|
||||
trajectoryRow.Radius = getDoubleValue(_radius, "Радиус цели", row);
|
||||
|
||||
if (_comment is not null)
|
||||
trajectoryRow.Comment = _comment.ToString();
|
||||
return trajectoryRow;
|
||||
|
Binary file not shown.
@ -29,7 +29,10 @@ namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
Caption = c.Caption,
|
||||
Id = c.Id,
|
||||
Users = c.Users.Select(u => new UserContactDto()
|
||||
Users = c.Users
|
||||
.Where(u => u.IdState == 1)
|
||||
.OrderBy(u => u.Surname)
|
||||
.Select(u => new UserContactDto()
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
|
92
AsbCloudInfrastructure/Services/WellboreService.cs
Normal file
92
AsbCloudInfrastructure/Services/WellboreService.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services;
|
||||
|
||||
public class WellboreService : IWellboreService
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
|
||||
public WellboreService(IWellService wellService, IWellOperationRepository wellOperationRepository)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
}
|
||||
|
||||
public async Task<WellboreDto?> GetWellboreAsync(int idWell, int idSection, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new WellboreRequest
|
||||
{
|
||||
Ids = new (int, int?)[] { (idWell, idSection) },
|
||||
Take = 1,
|
||||
};
|
||||
var data = await GetWellboresAsync(request, cancellationToken);
|
||||
return data.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellboreDto>> GetWellboresAsync(WellboreRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var wellbores = new List<WellboreDto>(request.Ids.Count());
|
||||
var skip = request.Skip ?? 0;
|
||||
var take = request.Take ?? 10;
|
||||
|
||||
var sections = wellOperationRepository.GetSectionTypes()
|
||||
.ToDictionary(w => w.Id, w => w);
|
||||
|
||||
var ids = request.Ids.GroupBy(i => i.idWell);
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(id.Key, cancellationToken);
|
||||
|
||||
if (well is null)
|
||||
continue;
|
||||
|
||||
var wellOperations = await GetFactOperationsAsync(well.Id, id.Select(i => i.idSection), cancellationToken);
|
||||
var groupedOperations = wellOperations.GroupBy(o => o.IdWellSectionType);
|
||||
var wellWellbores = groupedOperations.Select(group => new WellboreDto {
|
||||
Id = group.Key,
|
||||
Name = sections[group.Key].Caption,
|
||||
Well = well.Adapt<WellWithTimezoneDto>(),
|
||||
DateStart = group.Min(operation => operation.DateStart).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)),
|
||||
DateEnd = group.Max(operation => operation.DateStart.AddHours(operation.DurationHours)).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)),
|
||||
DepthStart = group.Min(operation => operation.DepthStart),
|
||||
DepthEnd = group.Max(operation => operation.DepthEnd),
|
||||
});
|
||||
wellbores.AddRange(wellWellbores);
|
||||
}
|
||||
|
||||
return wellbores
|
||||
.OrderBy(w => w.Well.Id).ThenBy(w => w.Id)
|
||||
.Skip(skip).Take(take);
|
||||
}
|
||||
|
||||
private async Task<IOrderedEnumerable<WellOperationDto>> GetFactOperationsAsync(int idWell, IEnumerable<int?> idsSections,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new WellOperationRequest
|
||||
{
|
||||
IdWell = idWell,
|
||||
OperationType = WellOperation.IdOperationTypeFact,
|
||||
SortFields = new[] { "DateStart asc" },
|
||||
};
|
||||
|
||||
request.SectionTypeIds = idsSections.All(i => i.HasValue)
|
||||
? idsSections.Select(i => i!.Value)
|
||||
: null;
|
||||
|
||||
return (await wellOperationRepository.GetAsync(request, cancellationToken))
|
||||
.OrderBy(o => o.DateStart);
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ public class AutoGeneratedDailyReportController : ControllerBase
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
var reportFile = await autoGeneratedDailyReportService.GenerateReportAsync(idWell,
|
||||
var reportFile = await autoGeneratedDailyReportService.GenerateAsync(idWell,
|
||||
reportDate,
|
||||
cancellationToken);
|
||||
|
||||
@ -79,6 +79,22 @@ public class AutoGeneratedDailyReportController : ControllerBase
|
||||
return Ok(reports);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон дат для формирования суточных отчётов
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("datesRange")]
|
||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
return Ok(await autoGeneratedDailyReportService.GetDatesRangeAsync(idWell, cancellationToken));
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
|
105
AsbCloudWebApi/Controllers/ManualController.cs
Normal file
105
AsbCloudWebApi/Controllers/ManualController.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
public class ManualController : ControllerBase
|
||||
{
|
||||
private readonly IManualCatalogService manualCatalogService;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
public ManualController(IManualCatalogService manualCatalogService,
|
||||
IUserRepository userRepository)
|
||||
{
|
||||
this.manualCatalogService = manualCatalogService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение файла
|
||||
/// </summary>
|
||||
/// <param name="idDirectory">Id директории</param>
|
||||
/// <param name="file">Загружаемый файл</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> SaveFileAsync(int idDirectory,
|
||||
[Required] IFormFile file,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if(!idUser.HasValue)
|
||||
throw new ForbidException("Не удается вас опознать");
|
||||
|
||||
AssertUserHasAccessToManual("Manual.edit");
|
||||
|
||||
using var fileStream = file.OpenReadStream();
|
||||
|
||||
var id = await manualCatalogService.SaveFileAsync(idDirectory, idUser.Value, file.FileName, fileStream, cancellationToken);
|
||||
|
||||
return Ok(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение файла
|
||||
/// </summary>
|
||||
/// <param name="id">Id инструкции</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id:int}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> GetFileAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManual("Manual.get");
|
||||
|
||||
var file = await manualCatalogService.GetFileAsync(id, cancellationToken);
|
||||
|
||||
if (!file.HasValue)
|
||||
return NoContent();
|
||||
|
||||
return File(file.Value.stream, "application/octet-stream", file.Value.fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление файла
|
||||
/// </summary>
|
||||
/// <param name="id">Id инструкции</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> DeleteFileAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManual("Manual.edit");
|
||||
|
||||
return Ok(await manualCatalogService.DeleteFileAsync(id, cancellationToken));
|
||||
}
|
||||
|
||||
private void AssertUserHasAccessToManual(string permissionName)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue || !userRepository.HasPermission(idUser.Value, permissionName))
|
||||
throw new ForbidException("У вас недостаточно прав");
|
||||
}
|
||||
}
|
110
AsbCloudWebApi/Controllers/ManualDirectoryController.cs
Normal file
110
AsbCloudWebApi/Controllers/ManualDirectoryController.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
public class ManualDirectoryController : ControllerBase
|
||||
{
|
||||
private readonly IManualDirectoryRepository manualDirectoryRepository;
|
||||
private readonly IManualCatalogService manualCatalogService;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
public ManualDirectoryController(IManualDirectoryRepository manualDirectoryRepository,
|
||||
IManualCatalogService manualCatalogService,
|
||||
IUserRepository userRepository)
|
||||
{
|
||||
this.manualDirectoryRepository = manualDirectoryRepository;
|
||||
this.manualCatalogService = manualCatalogService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание директории
|
||||
/// </summary>
|
||||
/// <param name="name">Название</param>
|
||||
/// <param name="idParent">Необязательный параметр. Id родительской директории</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> AddDirectoryAsync(string name, int? idParent, CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManualDirectory("Manual.edit");
|
||||
|
||||
return Ok(await manualCatalogService.AddDirectoryAsync(name, idParent, cancellationToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновление директории
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="name">Новое название директории</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[Permission]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> UpdateDirectoryAsync(int id, string name, CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManualDirectory("Manual.edit");
|
||||
|
||||
await manualCatalogService.UpdateDirectoryAsync(id, name, cancellationToken);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление директории
|
||||
/// </summary>
|
||||
/// <param name="id">Идентификатор директории</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> DeleteDirectoryAsync(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManualDirectory("Manual.edit");
|
||||
|
||||
return Ok(await manualCatalogService.DeleteDirectoryAsync(id, cancellationToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение дерева категорий
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<ManualDirectoryDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
AssertUserHasAccessToManualDirectory("Manual.get");
|
||||
|
||||
return Ok(await manualDirectoryRepository.GetTreeAsync(cancellationToken));
|
||||
}
|
||||
|
||||
private void AssertUserHasAccessToManualDirectory(string permissionName)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue || !userRepository.HasPermission(idUser.Value, permissionName))
|
||||
throw new ForbidException("У вас недостаточно прав");
|
||||
}
|
||||
}
|
@ -27,8 +27,9 @@ namespace AsbCloudWebApi.Controllers
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly IHubContext<TelemetryHub> telemetryHubContext;
|
||||
private readonly IProcessMapReportMakerService processMapReportService;
|
||||
private readonly IProcessMapReportService processMapService;
|
||||
private readonly IProcessMapService processMapService;
|
||||
private readonly IProcessMapPlanImportService processMapPlanImportService;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
private const string SirnalRMethodGetDataName = "UpdateProcessMap";
|
||||
|
||||
@ -36,10 +37,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
IWellService wellService,
|
||||
IProcessMapPlanRepository repository,
|
||||
IProcessMapReportMakerService processMapReportService,
|
||||
IProcessMapReportService processMapService,
|
||||
IProcessMapService processMapService,
|
||||
ITelemetryService telemetryService,
|
||||
IHubContext<TelemetryHub> telemetryHubContext,
|
||||
IProcessMapPlanImportService processMapPlanImportService)
|
||||
IProcessMapPlanImportService processMapPlanImportService,
|
||||
IUserRepository userRepository)
|
||||
: base(wellService, repository)
|
||||
{
|
||||
this.telemetryService = telemetryService;
|
||||
@ -47,6 +49,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
this.processMapReportService = processMapReportService;
|
||||
this.processMapService = processMapService;
|
||||
this.processMapPlanImportService = processMapPlanImportService;
|
||||
this.userRepository = userRepository;
|
||||
|
||||
}
|
||||
|
||||
@ -110,7 +113,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
return NoContent();
|
||||
|
||||
var fileName = $"РТК по скважине {well.Caption} куст {well.Cluster}.xlsx";
|
||||
return File(stream, fileName);
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
@ -139,6 +142,9 @@ namespace AsbCloudWebApi.Controllers
|
||||
[HttpPost]
|
||||
public override async Task<ActionResult<int>> InsertAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserEditProcessMapAsync(value.IdWell, token))
|
||||
return Forbid();
|
||||
|
||||
value.IdUser = User.GetUserId() ?? -1;
|
||||
var result = await base.InsertAsync(value, token);
|
||||
await NotifyUsersBySignalR(value.IdWell, token);
|
||||
@ -154,6 +160,9 @@ namespace AsbCloudWebApi.Controllers
|
||||
[HttpPut]
|
||||
public override async Task<ActionResult<int>> UpdateAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserEditProcessMapAsync(value.IdWell, token))
|
||||
return Forbid();
|
||||
|
||||
value.IdUser = User.GetUserId() ?? -1;
|
||||
var result = await base.UpdateAsync(value, token);
|
||||
await NotifyUsersBySignalR(value.IdWell, token);
|
||||
@ -192,6 +201,9 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (idUser is null)
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditProcessMapAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
|
||||
return BadRequest("Требуется xlsx файл.");
|
||||
|
||||
@ -239,6 +251,21 @@ namespace AsbCloudWebApi.Controllers
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserEditProcessMapAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
return false;
|
||||
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
||||
|
||||
if (well is null)
|
||||
return false;
|
||||
|
||||
return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell");
|
||||
}
|
||||
|
||||
private async Task NotifyUsersBySignalR(int idWell, CancellationToken token)
|
||||
{
|
||||
var dtos = await service.GetAllAsync(idWell, null, token);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -6,6 +7,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -95,6 +97,67 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
||||
return Ok(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Новая версия. Возвращает данные САУБ по скважине.
|
||||
/// По умолчанию за последние 10 минут.
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token">Токен завершения задачи</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{idWell}/data")]
|
||||
[Permission]
|
||||
public virtual async Task<ActionResult<IEnumerable<TDto>>> GetData2Async(int idWell,
|
||||
[FromQuery]TelemetryDataRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
|
||||
bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
|
||||
if (!isCompanyOwnsWell)
|
||||
return Forbid();
|
||||
|
||||
var content = await telemetryDataService.GetAsync(idWell, request, token);
|
||||
|
||||
return Ok(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает диапазон дат за которые есть телеметрия за период времени
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{idWell}/dateRange")]
|
||||
public virtual async Task<ActionResult<DatesRangeDto?>> GetRangeAsync(
|
||||
[FromRoute] int idWell,
|
||||
[Required] DateTimeOffset start,
|
||||
[Required] DateTimeOffset end,
|
||||
CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
|
||||
bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
|
||||
if (!isCompanyOwnsWell)
|
||||
return Forbid();
|
||||
|
||||
var content = await telemetryDataService.GetRangeAsync(idWell, start, end, token);
|
||||
|
||||
return Ok(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает диапазон дат сохраненных данных.
|
||||
/// </summary>
|
||||
|
@ -26,12 +26,16 @@ namespace AsbCloudWebApi.Controllers
|
||||
private readonly IWellOperationRepository operationRepository;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationImportService wellOperationImportService;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
public WellOperationController(IWellOperationRepository operationService, IWellService wellService, IWellOperationImportService wellOperationImportService)
|
||||
public WellOperationController(IWellOperationRepository operationService, IWellService wellService,
|
||||
IWellOperationImportService wellOperationImportService,
|
||||
IUserRepository userRepository)
|
||||
{
|
||||
this.operationRepository = operationService;
|
||||
this.wellService = wellService;
|
||||
this.wellOperationImportService = wellOperationImportService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -199,7 +203,10 @@ namespace AsbCloudWebApi.Controllers
|
||||
[FromBody] IEnumerable<WellOperationDto> values,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
foreach (var value in values)
|
||||
@ -229,7 +236,10 @@ namespace AsbCloudWebApi.Controllers
|
||||
public async Task<IActionResult> UpdateAsync(int idWell, int idOperation,
|
||||
[FromBody] WellOperationDto value, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
value.IdWell = idWell;
|
||||
@ -254,8 +264,10 @@ namespace AsbCloudWebApi.Controllers
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> DeleteAsync(int idWell, int idOperation, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
var result = await operationRepository.DeleteAsync(new int[] { idOperation }, token)
|
||||
@ -286,6 +298,12 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (idCompany is null || idUser is null)
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
@ -376,6 +394,21 @@ namespace AsbCloudWebApi.Controllers
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserEditWellOperationsAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
return false;
|
||||
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
||||
|
||||
if (well is null)
|
||||
return false;
|
||||
|
||||
return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "WellOperation.editCompletedWell");
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
|
91
AsbCloudWebApi/Controllers/WellboreController.cs
Normal file
91
AsbCloudWebApi/Controllers/WellboreController.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Ствол скважины
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class WellboreController : ControllerBase
|
||||
{
|
||||
private readonly IWellboreService wellboreService;
|
||||
|
||||
public WellboreController(IWellboreService wellboreService)
|
||||
{
|
||||
this.wellboreService = wellboreService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение ствола скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="idSection">Id типа секции скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpGet("{idWell:int}/{idSection:int}")]
|
||||
[ProducesResponseType(typeof(WellboreDto), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> GetAsync(int idWell, int idSection, CancellationToken cancellationToken)
|
||||
{
|
||||
var wellbore = await wellboreService.GetWellboreAsync(idWell, idSection, cancellationToken);
|
||||
|
||||
if (wellbore is null)
|
||||
return NoContent();
|
||||
|
||||
return Ok(wellbore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка стволов скважин
|
||||
/// </summary>
|
||||
/// <param name="ids">Пары идентификаторов скважины и секции</param>
|
||||
/// <param name="skip">Опциональный параметр. Количество пропускаемых записей</param>
|
||||
/// <param name="take">Опциональный параметр. Количество получаемых записей</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellboreDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetAllAsync([FromQuery] IEnumerable<string> ids,
|
||||
int? skip,
|
||||
int? take,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new WellboreRequest
|
||||
{
|
||||
Ids = ids.Select(id => ParseId(id)),
|
||||
Skip = skip,
|
||||
Take = take
|
||||
};
|
||||
|
||||
return Ok(await wellboreService.GetWellboresAsync(request, cancellationToken));
|
||||
}
|
||||
|
||||
private static (int, int?) ParseId(string id)
|
||||
{
|
||||
var idPair = id.Split(',');
|
||||
if (!int.TryParse(idPair[0], out var idWell))
|
||||
throw new ArgumentInvalidException($"Не удалось получить Id скважины \"{idPair[0]}\"", nameof(id));
|
||||
|
||||
if (idPair.Length > 1)
|
||||
{
|
||||
if (int.TryParse(idPair[1], out int idWellSectionType))
|
||||
return (idWell, idWellSectionType);
|
||||
else
|
||||
throw new ArgumentInvalidException($"Не удалось получить Id ствола \"{idPair[1]}\"", nameof(id));
|
||||
}
|
||||
return (idWell, null);
|
||||
}
|
||||
}
|
15
AsbCloudWebApi/Rest/wellbore.http
Normal file
15
AsbCloudWebApi/Rest/wellbore.http
Normal file
@ -0,0 +1,15 @@
|
||||
@baseUrl = http://127.0.0.1:5000
|
||||
@contentType = application/json
|
||||
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE
|
||||
|
||||
@uid = 20210101_000000000
|
||||
@idCluster = 1
|
||||
@idWell = 1
|
||||
|
||||
# https://marketplace.visualstudio.com/items?itemName=humao.rest-client
|
||||
|
||||
###
|
||||
GET {{baseUrl}}/api/well/wellbore?ids=1,2
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
@ -27,6 +27,7 @@
|
||||
"supportMail": "support@digitaldrilling.ru"
|
||||
},
|
||||
"DirectoryNameHelpPageFiles": "helpPages",
|
||||
"DirectoryManualFiles": "manuals",
|
||||
"Urls": "http://0.0.0.0:5000" //;https://0.0.0.0:5001" //,
|
||||
// See https man: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0
|
||||
//"Kestrel": {
|
||||
|
Loading…
Reference in New Issue
Block a user