Merge pull request 'uat' (#55) from uat into master

Reviewed-on: http://192.168.80.50:3000/Dotnet/SJZY.Track.Api/pulls/55
This commit is contained in:
dingenwen 2024-03-08 09:23:30 +08:00
commit 0bf073ede2
229 changed files with 10519 additions and 1506 deletions

View File

@ -12,10 +12,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0E2537C3-6
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJZY.Track.Repository", "src\SJZY.Track.Repository\SJZY.Track.Repository.csproj", "{D9CF5706-1972-414F-821E-AA32C13B8570}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJZY.Track.HttpApi", "src\SJZY.Track.HttpApi\SJZY.Track.HttpApi.csproj", "{390A44FB-0DB5-4B66-86AB-7712DC3030F5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJZY.Track.Application.Contract", "src\SJZY.Track.Application.Contract\SJZY.Track.Application.Contract.csproj", "{390A44FB-0DB5-4B66-86AB-7712DC3030F5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJZY.Track.Test", "test\SJZY.Track.Test\SJZY.Track.Test.csproj", "{3A53539C-4A85-4E5D-A071-7B4B193AB0E0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SJZY.Track.Domain", "src\SJZY.Track.Domain\SJZY.Track.Domain.csproj", "{073EB297-E752-49AC-BED8-B4AEBAB518F6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution items", "solution items", "{086C7812-46F9-49FD-B490-A769E2C0729E}"
ProjectSection(SolutionItems) = preProject
common.props = common.props
NuGet.Config = NuGet.Config
.gitignore = .gitignore
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -42,6 +51,10 @@ Global
{3A53539C-4A85-4E5D-A071-7B4B193AB0E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A53539C-4A85-4E5D-A071-7B4B193AB0E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A53539C-4A85-4E5D-A071-7B4B193AB0E0}.Release|Any CPU.Build.0 = Release|Any CPU
{073EB297-E752-49AC-BED8-B4AEBAB518F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{073EB297-E752-49AC-BED8-B4AEBAB518F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{073EB297-E752-49AC-BED8-B4AEBAB518F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{073EB297-E752-49AC-BED8-B4AEBAB518F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -52,9 +65,10 @@ Global
{D9CF5706-1972-414F-821E-AA32C13B8570} = {DAC93270-5A25-40E5-B851-E7CA398DBC31}
{390A44FB-0DB5-4B66-86AB-7712DC3030F5} = {DAC93270-5A25-40E5-B851-E7CA398DBC31}
{3A53539C-4A85-4E5D-A071-7B4B193AB0E0} = {0E2537C3-6EF3-4085-9BD2-CF923E53F82A}
{073EB297-E752-49AC-BED8-B4AEBAB518F6} = {DAC93270-5A25-40E5-B851-E7CA398DBC31}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = { 8289A516 - 787C - 4D9D - B972 - E7047BDD206B}
SolutionGuid = { 8289A516 - 787C - 4D9D - B972 - E7047BDD206B}
SolutionGuid = {C8AD8123-683D-406E-A8FB-1D0184C19472}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=SJZY/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

9
common.props Normal file
View File

@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>$(NoWarn);CS1591;CS0436;NU1803</NoWarn>
<!-- <WarningsAsErrors>Nullable</WarningsAsErrors>-->
</PropertyGroup>
</Project>

View File

@ -10,10 +10,10 @@ try
.AddConfigurationContainer()
.AddOptionsFromConfiguration()
.UseSerilogDefault()
.Host.AddAppSettingsSecretsJson()
.Host.AddAppSettingsSecretsJson()
.UseAutofac();
await builder.AddApplicationAsync<ApiModule>();
await builder.AddApplicationAsync<SjzyTrackApiModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
@ -21,5 +21,5 @@ try
}
catch (Exception ex)
{
Console.WriteLine($"项目启动失败,异常信息:{ex}");
Console.WriteLine($"项目启动失败,异常信息:{ex}");
}

View File

@ -1,32 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
</PropertyGroup>
<Import Project="../../common.props" />
<ItemGroup>
<Compile Remove="logs\**" />
<Content Remove="logs\**" />
<EmbeddedResource Remove="logs\**" />
<None Remove="logs\**" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="7.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SJZY.Track.Application\SJZY.Track.Application.csproj" />
<ProjectReference Include="..\SJZY.Track.Repository\SJZY.Track.Repository.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SJZY.Track.Application\SJZY.Track.Application.csproj" />
</ItemGroup>
</Project>

View File

@ -9,6 +9,7 @@ using SJZY.Expand.ABP.Core.Prometheus;
using SJZY.Expand.ABP.Core.Redis;
using SJZY.Expand.ABP.Core.Swagger;
using SJZY.Track.Application;
using SJZY.Track.Repository;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
@ -17,23 +18,26 @@ using Volo.Abp.Autofac;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
[assembly: HostingStartup(typeof(SJZY.Expand.ABP.Core.HostingStartup))]
[assembly: HostingStartup(typeof(HostingStartup))]
namespace SJZY.Track.Api
{
[DependsOn(
typeof(AbpAutofacModule),
typeof(SjzyAbpCodeModule),
typeof(ApplicationModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAspNetCoreSerilogModule)
typeof(AbpAspNetCoreSerilogModule),
typeof(SjzyTrackApplicationModule),
typeof(SjzyTrackRepositoryModule)
)]
public class ApiModule : AbpModule
public class SjzyTrackApiModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var environment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
context.Services.AddSwagger();
//过滤器相关配置
context.Services.AddMvc(options =>
{
@ -47,7 +51,9 @@ namespace SJZY.Track.Api
//Json格式化全局处理
context.Services.Configure<MvcNewtonsoftJsonOptions>(options =>
{
options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();//.DefaultContractResolver();
options.SerializerSettings.ContractResolver =
new Newtonsoft.Json.Serialization.
CamelCasePropertyNamesContractResolver(); //.DefaultContractResolver();
options.SerializerSettings.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
options.SerializerSettings.Converters.Add(new LongJsonConverter());
});
@ -55,9 +61,7 @@ namespace SJZY.Track.Api
Configure<AbpJsonOptions>(options => options.OutputDateTimeFormat = "yyyy-MM-dd HH:mm:ss");
Configure<AbpAuditingOptions>(options => { options.IsEnabled = false; });
context.Services.AddRedis();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -77,6 +81,7 @@ namespace SJZY.Track.Api
app.UsePrometheus();
#region 启动提示
Console.WriteLine($@"
+-------------------------------------------------------+
| |
@ -87,8 +92,8 @@ namespace SJZY.Track.Api
| |
+-------------------------------------------------------+
");
#endregion
}
}
}
}

View File

@ -2,13 +2,12 @@
"Environment": "Dev",
"Logging": {
"LogLevel": {
"Default": "Information",
"Default": "Debug",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "server=mysql-dev.default.svc.cluster.local;Database=sjzy_openapi;Uid=sjzy_dev_user;Pwd=818f83e5;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;",
"BICenterConnection": "server=mysql-test.default.svc.cluster.local;Database=sjzy_bi_center;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;"
"DefaultConnection": "server=mysql-dev.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_dev_user;Pwd=818f83e5;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;",
},
"Redis": {
"Host": "redis-dev.default.svc.cluster.local:6379",
@ -60,9 +59,20 @@
"BucketName": "cams3",
"ReturnHttpsUrl": true
},
"ElasticSearch": {
"NodeUrls": [ "http://elasticsearch-dev.default.svc.cluster.local:9200" ],
"LoginName": "elastic",
"Password": "afyTgmVb8jq6",
"Base64PassPassword": "Basic ZWxhc3RpYzphZnlUZ21WYjhqcTY="
},
"RemoteServices": {
"UserCenter": {
"BaseUrl": "http://192.168.80.55:5020/"
},
"InterfaceForward": {
"BaseUrl": "http://192.168.80.55:5041/", //开发环境80.55,测试环境80.57
"AppKey": "从接口通应用获取",
"AppSecret": "从接口通应用获取"
}
}
}

View File

@ -7,8 +7,8 @@
}
},
"ConnectionStrings": {
"DefaultConnection": "server=192.168.80.84;Database=sjzy_package_setting;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;",
"canalView": "server=192.168.80.84;Database=sjzy_data_center;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;"
"DefaultConnection": "server=mysql-test.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;",
"canalView": "server=mysql-test.default.svc.cluster.local;Database=sjzy_track;Uid=sjzy_test_user;Pwd=848c1c31;AllowLoadLocalInfile=true;SslMode=None;Charset=utf8mb4;"
},
"Redis": {
"ConnectionString": "192.168.80.58:6379,abortConnect=false",

View File

@ -1,20 +1,20 @@
{
"Configuration": {
"UseLocalConfiguration": true, // 是否使用本地配置文件
"ConfiguraFileName": "appsettings.Development.json", //指定配置文件名称,开启 UseLocalConfiguration 时生效
"UseLocalConfiguration": false, //是否使用本地配置文件
"ConfiguraFileName": "appsettings.Development.json", //指定配置文件名称,开启UseLocalConfiguration时生效
"Apollo": {
"AppId": "SJZY.Track.Configuration",
"Env": "DEV",
"Namespace": "Dev",
"Namespace": "Test",
"MetaServer": "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080",
"ConfigServer": [ "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080" ]
}
},
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://*:5056"
}
},
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://*:5056"
}
}
}
}

View File

@ -0,0 +1,13 @@
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class DeleteOrderInput : OrderNoInfo
{
}
public class DeleteTrackInput : OrderNoInfo
{
/// <summary>
/// 轨迹code
/// </summary>
public List<string> TrackCodes { get; set; } = new();
}

View File

@ -0,0 +1,90 @@
using System.Reflection.Metadata.Ecma335;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices
{
public class GetOrderDetailsInput
{
/// <summary>
/// 轨迹订单id
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 轨迹模板Id
/// </summary>
public List<int>? TrackTemplateIds { get; set; } = new List<int>();
}
public class TrackOrderDetailDto
{
/// <summary>
/// Id es主键
/// </summary>
public int Id { get; set; }
/// <summary>
/// 轨迹订单id
/// </summary>
public int OrderId { set; get; }
/// <summary>
/// 轨迹代码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 轨迹内容
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string? EnContent { get; set; }
/// <summary>
/// 轨迹发生地
/// </summary>
public string? TrackPlace { get; set; }
/// <summary>
/// 轨迹发生时间
/// </summary>
public DateTime? TrackTime { get; set; }
/// <summary>
/// 轨迹发生时区
/// </summary>
public string? TrackTimeZone { get; set; }
/// <summary>
/// 时区的值
/// </summary>
public float TrackTimeZoneValue { get; set; }
/// <summary>
/// 是否可删
/// </summary>
public bool IsCanDelete { get; set; }
/// <summary>
/// 是否对外
/// </summary>
public bool IsExternal { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreateUser { get; set; }
}
}

View File

@ -0,0 +1,117 @@
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class GetPageTrackOrderInput : PageInfoInput
{
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
///// <summary>
///// 单号
///// </summary>
//public List<string>? OrderNos { get; set; }
/// <summary>
/// 单号
/// </summary>
public string? OrderNos { get; set; }
/// <summary>
/// 创建时间开始
/// </summary>
public DateTime? CreateTimeStart { get; set; }
/// <summary>
/// 创建时间截止
/// </summary>
public DateTime? CreateTimeEnd { get; set; }
}
/// <summary>
/// 轨迹订单Dto
/// </summary>
public class TrackOrderDto
{
/// <summary>
/// 轨迹订单id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 订单类型id
/// </summary>
public int OrderType { get; set; }
/// <summary>
/// 订单名称
/// </summary>
public string? OrderTypeName { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string? OrderNumber { get; set; }
/// <summary>
/// 轨迹模版
/// </summary>
public string? TrackTemplateNames { get; set; }
/// <summary>
/// 轨迹模板Id数组
/// </summary>
public List<int>? TrackTemplateIds { get; set; }
/// <summary>
/// 客户简称
/// </summary>
public string? CustomerShortName { get; set; }
/// <summary>
/// 客户代码
/// </summary>
public string? CustomerCode { get; set; }
/// <summary>
/// 订单明细(json)
/// </summary>
public string? OrderDetails { get; set; }
/// <summary>
/// 最新轨迹内容
/// </summary>
public string? NewestTrackContent { get; set; }
/// <summary>
/// 最新轨迹内容英文
/// </summary>
public string? NewestTrackEnContent { get; set; }
/// <summary>
/// 最新轨迹发生地
/// </summary>
public string? NewestTrackPlace { get; set; }
/// <summary>
/// 最新轨迹时间
/// </summary>
public DateTime? NewestTrackTime { get; set; }
/// <summary>
/// 是否完结
/// </summary>
public bool IsFinish { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? CreateTime { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
public int SubSystemId { get; set; }
}

View File

@ -0,0 +1,54 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class GetTrackInput
{
/// <summary>
/// 订单类型
/// </summary>
[Required]
[Range(1, int.MaxValue)]
public int OrderType { get; set; }
/// <summary>
/// 订单号
/// </summary>
public List<string> OrderNos { get; set; } = new();
/// <summary>
/// 时区 +8 +8.25 -8.5 -9
/// 不传默认+8
/// </summary>
private float? _timeZone;
public float? TimeZone
{
get => _timeZone ?? 8;
set => _timeZone = value;
}
/// <summary>
/// 排序方式
/// </summary>
[Required]
public SortMethod SortMethod { get; set; }
}
public enum SortMethod
{
/// <summary>
/// 按轨迹发生时间排序
/// </summary>
ByTrackTime,
/// <summary>
/// 按轨迹发生时间降序
/// </summary>
ByTrackTimeDesc,
/// <summary>
/// 按订单模板排序
/// </summary>
ByTemplate
}

View File

@ -0,0 +1,21 @@
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class GetTrackOutput
{
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; }
public List<TrackDetail> TrackDetails { get; set; }
}
public class TrackDetail
{
public string Code { get; set; }
public string Status { get; set; }
public string Content { get; set; }
public string Location { get; set; }
public DateTime Time { get; set; }
public float TimeZone { get; set; }
}

View File

@ -0,0 +1,31 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class LinkOrderInput
{
/// <summary>
/// false解绑,true关联
/// </summary>
[Required]
public bool IsLink { get; set; }
/// <summary>
/// 订单类型,必填
/// </summary>
[Required]
public int OrderType { get; set; }
/// <summary>
/// 订单号,必填
/// </summary>
[Required]
public string OrderNo { get; set; }
[Required] public int LinkOrderType { get; set; }
/// <summary>
/// 关联的单号
/// </summary>
public List<string> LinkOrderNos { get; set; } = new();
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class OrderNoInfo
{
/// <summary>
/// 订单类型,必填
/// </summary>
[Required]
[Range(1, int.MaxValue)]
public int OrderType { get; set; }
/// <summary>
/// 订单号,必填
/// </summary>
[Required]
[MaxLength(100)]
public string OrderNo { get; set; } = null!;
}

View File

@ -0,0 +1,9 @@
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class RefreshTrackInput
{
/// <summary>
/// 订单号
/// </summary>
public List<string> OrderNos { get; set; } = new();
}

View File

@ -0,0 +1,54 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class UpdateOrderInput : OrderNoInfo
{
/// <summary>
/// 目的港口
/// </summary>
public string? ArrivalPort { get; set; }
/// <summary>
/// 起运港口
/// </summary>
public string? LeavePort { get; set; }
/// <summary>
/// 目的国家,必填
/// </summary>
[Required]
[MaxLength(200)]
public string ArrivalCountry { get; set; } = null!;
/// <summary>
/// 起运国家,必填
/// </summary>
[Required]
[MaxLength(200)]
public string LeaveCountry { get; set; } = null!;
/// <summary>
/// 目的城市,必填
/// </summary>
[Required]
[MaxLength(200)]
public string ArrivalCity { get; set; } = null!;
/// <summary>
/// 起运城市,必填
/// </summary>
[Required]
[MaxLength(200)]
public string LeaveCity { get; set; } = null!;
/// <summary>
/// 订单模板(传全量)
/// </summary>
public List<OrderTemplateInfo>? Templates { get; set; } = new();
/// <summary>
/// 订单航班信息
/// </summary>
public List<OrderFlightInfo>? FlightInfos { get; set; } = new();
}

View File

@ -0,0 +1,42 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class UpsertOrderInput : UpdateOrderInput
{
/// <summary>
/// 客户id
/// </summary>
[Required]
public int CustomId { get; set; }
}
public class OrderTemplateInfo
{
/// <summary>
/// 模板id
/// </summary>
[Required]
public int TemplateId { get; set; }
/// <summary>
/// 服务商id
/// </summary>
public int? ServiceProviderId { get; set; }
}
public class OrderFlightInfo
{
/// <summary>
/// 航班号
/// </summary>
[Required]
[MaxLength(50)]
public string FlightNo { get; set; }
/// <summary>
/// 班期
/// </summary>
[Required]
public DateTime FlightDate { get; set; }
}

View File

@ -0,0 +1,47 @@
using System.ComponentModel.DataAnnotations;
namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
public class UpsertTrackInput : OrderNoInfo
{
/// <summary>
/// 轨迹内容代码
/// </summary>
[Required]
[MaxLength(50)]
public string TrackCode { get; set; } = null!;
/// <summary>
/// 轨迹发生地
/// </summary>
[Required]
[MaxLength(200)]
public string TrackPlace { get; set; } = null!;
/// <summary>
/// 轨迹发生时间
/// </summary>
[Required]
public DateTime? TrackTime { get; set; }
/// <summary>
/// 轨迹发生时区
/// </summary>
[Required]
[Range(-12, 12)]
public float? TrackTimeZone { get; set; }
}
public class NotNullAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
return new ValidationResult(ErrorMessage ?? "The field is required.",
new[] { validationContext.MemberName });
}
return ValidationResult.Success;
}
}

View File

@ -0,0 +1,108 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackContents
{
public class EditTrackContentInput
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionType Options { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 所属轨迹状态id
/// </summary>
public int TrackStatusId { get; set; }
/// <summary>
/// 轨迹内容代码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 轨迹内容
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string? EnContent { get; set; }
/// <summary>
/// 轨迹标记id
/// </summary>
public int TrackFlagId { get; set; }
/// <summary>
/// 是否完结
/// </summary>
public bool IsFinish { get; set; }
}
public class GetTrackContentDetailDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 所属轨迹状态id
/// </summary>
public int TrackStatusId { get; set; }
/// <summary>
/// 所属轨迹状态
/// </summary>
public string TrackStatus { get; set; }
/// <summary>
/// 轨迹内容代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 轨迹内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string EnContent { get; set; }
/// <summary>
/// 轨迹标记id
/// </summary>
public int TrackFlagId { get; set; }
/// <summary>
/// 轨迹标记
/// </summary>
public string TrackFlag { get; set; }
/// <summary>
/// 是否完结
/// </summary>
public bool IsFinish { get; set; }
}
}

View File

@ -0,0 +1,41 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackContents;
public class EditTrackContentMapInput
{
public int? Id { get; set; }
/// <summary>
/// 映射子系统id
/// </summary>
public int? MapSubSystemId { get; set; }
/// <summary>
/// 映射轨迹内容代码
/// </summary>
public string? MapTrackContentCode { get; set; }
/// <summary>
/// 映射轨迹内容id
/// </summary>
public int? MapTrackContentId { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionTypeNoNull Options { get; set; }
/// <summary>
/// 源子系统id
/// </summary>
public int? SubSystemId { get; set; }
/// <summary>
/// 源轨迹内容代码
/// </summary>
public string? TrackContentCode { get; set; }
/// <summary>
/// 源轨迹内容id
/// </summary>
public int? TrackContentId { get; set; }
}

View File

@ -0,0 +1,93 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackContents
{
public class GetPageTrackContentInput : PageInfoInput
{
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 关键字
/// </summary>
public string? Keywords { get; set; }
/// <summary>
/// 轨迹状态id
/// </summary>
public int TrackStatusId { get; set; }
/// <summary>
/// 选中的轨迹内容id
/// </summary>
public List<int>? SelectIds { get; set; }
}
public class GetTrackContentListDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 轨迹内容代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 轨迹内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string EnContent { get; set; }
/// <summary>
/// 所属状态
/// </summary>
public string TrackStatus { get; set; }
/// <summary>
/// 所属节点
/// </summary>
public string Node { get; set; }
/// <summary>
/// 轨迹标记
/// </summary>
public string TrackFlag { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? CreateTime { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string CreateUser { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string UpdateUser { get; set; }
/// <summary>
/// 是否完结
/// </summary>
public bool IsFinish { get; set; }
}
}

View File

@ -0,0 +1,68 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackFlags
{
public class EditTrackFlagInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionType Options { get; set; }
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 标记
/// </summary>
public string? Flag { get; set; }
/// <summary>
/// 代码
/// </summary>
public string? Code { get; set; }
///// <summary>
///// 是否完结
///// </summary>
//public bool IsFinish { get; set; }
}
public class GetTrackFlagDetailDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 代码
/// </summary>
public string Code { get; set; }
/// <summary>
///
/// </summary>
public string Flag { get; set; }
///// <summary>
///// 是否完结
///// </summary>
//public bool IsFinish { get; set; }
}
}

View File

@ -0,0 +1,68 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackFlags
{
public class GetTrackFlagListDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 标记
/// </summary>
public string Flag { get; set; }
///// <summary>
///// 是否完结
///// </summary>
//public bool IsFinish { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? CreateTime { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string CreateUser { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string UpdateUser { get; set; }
}
public class GetPageTrackFlagInput : PageInfoInput
{
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 选中的轨迹标记id
/// </summary>
public List<int>? SelectIds { get; set; }
///// <summary>
///// 关键字
///// </summary>
//public string Keywords { get; set; }
}
}

View File

@ -0,0 +1,71 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackPull;
public class EditTrackPullConfigInput
{
public int? Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionTypeNoNull Options { get; set; }
/// <summary>
/// 拉取轨迹订单号
/// </summary>
public string? OrderNoName { get; set; }
/// <summary>
/// 返参解析对象
/// </summary>
public int? ParseMethod { get; set; }
/// <summary>
/// 定时任务(分钟)
/// </summary>
public int? PullInterval { get; set; }
/// <summary>
/// 服务商id
/// </summary>
public int? ServiceProviderId { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int? SubSystemId { get; set; }
/// <summary>
/// 拉取轨迹时区
/// </summary>
public string? TackTimeZoneName { get; set; }
/// <summary>
/// 拉取轨迹内容代码
/// </summary>
public string? TrackContentCodeName { get; set; }
/// <summary>
/// 拉取轨迹内容
/// </summary>
public string? TrackContentName { get; set; }
/// <summary>
/// 拉取轨迹发生地
/// </summary>
public string? TrackPlaceName { get; set; }
/// <summary>
/// 拉取轨迹状态
/// </summary>
public string? TrackStatusName { get; set; }
/// <summary>
/// 轨迹模板id
/// </summary>
public int? TrackTemplateId { get; set; }
/// <summary>
/// 拉取轨迹发生时间
/// </summary>
public string? TrackTimeName { get; set; }
}

View File

@ -0,0 +1,51 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackPull;
public class UpdateTrackPullContentInput
{
public int Id { get; set; }
/// <summary>
/// 服务商轨迹代码参数值
/// </summary>
public string? TrackContentCodeValue { get; set; }
/// <summary>
/// 轨迹内容id
/// </summary>
public int TrackContentId { get; set; }
/// <summary>
/// 服务商轨迹内容参数值
/// </summary>
public string? TrackContentValue { get; set; }
/// <summary>
/// 拉取轨迹关键字(正向)
/// </summary>
public List<string>? TrackKeywords { get; set; }
/// <summary>
/// 拉取轨迹关键字(反向)
/// </summary>
public List<string>? TrackKeywordReverses { get; set; }
/// <summary>
/// 轨迹发生地参数值
/// </summary>
public int? TrackPlaceValue { get; set; }
/// <summary>
/// 轨迹拉取配置id
/// </summary>
public int TrackPullConfigId { get; set; }
/// <summary>
/// 服务商轨迹状态参数值
/// </summary>
public string? TrackStatusValue { get; set; }
/// <summary>
/// 轨迹时区GMT
/// </summary>
public double? TrackTimeZone { get; set; }
}

View File

@ -0,0 +1,81 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackPush;
public class EditTrackPushConfigInput
{
/// <summary>
/// 客户id
/// </summary>
public int CustomId { get; set; }
/// <summary>
/// 推送扩展字段
/// </summary>
public string? ExpandFieldsName { get; set; }
public int? Id { get; set; }
/// <summary>
/// 是否自动推送
/// </summary>
public bool IsAutoPush { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionTypeNoNull Options { get; set; }
/// <summary>
/// 推送轨迹订单号
/// </summary>
public string? OrderNoName { get; set; }
/// <summary>
/// 服务商id
/// </summary>
public int ServiceProviderId { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 推送轨迹时区
/// </summary>
public string? TackTimeZoneName { get; set; }
/// <summary>
/// 推送轨迹内容代码
/// </summary>
public string? TrackContentCodeName { get; set; }
/// <summary>
/// 推送轨迹内容
/// </summary>
public string? TrackContentName { get; set; }
/// <summary>
/// 推送轨迹内容英文
/// </summary>
public string? TrackEnContentName { get; set; }
/// <summary>
/// 推送轨迹发生地
/// </summary>
public string? TrackPlaceName { get; set; }
/// <summary>
/// 推送轨迹状态
/// </summary>
public string? TrackStatusName { get; set; }
/// <summary>
/// 轨迹模板id
/// </summary>
public List<int>? TrackTemplateIds { get; set; }
/// <summary>
/// 推送轨迹发生时间
/// </summary>
public string? TrackTimeName { get; set; }
}

View File

@ -0,0 +1,61 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackPush;
public class EditTrackPushContentInput
{
/// <summary>
/// 扩展字段参数值
/// </summary>
public string? ExpandFieldsValue { get; set; }
public int? Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionTypeNoNull Options { get; set; }
/// <summary>
/// 推送单号类型
/// </summary>
public int OrderNoType { get; set; }
/// <summary>
/// 推送轨迹排序
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 轨迹代码参数值
/// </summary>
public string? TrackContentCodeValue { get; set; }
/// <summary>
/// 轨迹内容id
/// </summary>
public int TrackContentId { get; set; }
/// <summary>
/// 轨迹内容参数值
/// </summary>
public string? TrackContentValue { get; set; }
/// <summary>
/// 轨迹内容英文参数值
/// </summary>
public string? TrackEnContentValue { get; set; }
/// <summary>
/// 轨迹推送配置id
/// </summary>
public int TrackPushConfigId { get; set; }
/// <summary>
/// 轨迹状态参数值
/// </summary>
public string? TrackStatusValue { get; set; }
/// <summary>
/// 轨迹时区GMT
/// </summary>
public double? TrackTimeZone { get; set; }
}

View File

@ -0,0 +1,11 @@
using SJZY.Expand.ABP.Core.PublicMethords;
namespace SJZY.Track.Application.Contract.Dtos.TrackPush;
public class SortTrackPushContentInput
{
/// <summary>
/// 排序信息
/// </summary>
public List<DropdownListDataDto> SortInfo { get; set; }
}

View File

@ -0,0 +1,40 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackStatus
{
public class EditTrackStatusInput
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionType Options { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 所属节点id
/// </summary>
public int NodeId { get; set; }
/// <summary>
/// 轨迹状态代码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 轨迹状态
/// </summary>
public string? TrackStatus { get; set; }
/// <summary>
/// 轨迹状态英文
/// </summary>
public string? EntrackStatus { get; set; }
}
}

View File

@ -0,0 +1,40 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackStatus
{
public class GetTrackStatusDetailDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 节点id
/// </summary>
public int NodeId { get; set; }
/// <summary>
/// 所属轨迹状态
/// </summary>
public string TrackStatus { get; set; }
/// <summary>
/// 轨迹状态代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string EntrackStatus { get; set; }
}
}

View File

@ -0,0 +1,74 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackStatus
{
public class GetTrackStatusListDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 所属节点
/// </summary>
public string Node { get; set; }
/// <summary>
/// 所属轨迹状态
/// </summary>
public string TrackStatus { get; set; }
/// <summary>
/// 轨迹状态代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 轨迹内容英文
/// </summary>
public string EntrackStatus { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string CreateUser { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? CreateTime { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string UpdateUser { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdateTime { get; set; }
}
public class GetPageTrackStatusInput : PageInfoInput
{
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 关键字
/// </summary>
public string? Keywords { get; set; }
/// <summary>
/// 选中的轨迹状态id
/// </summary>
public List<int>? SelectIds { get; set;}
}
}

View File

@ -0,0 +1,33 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackTemplates;
/// <inheritdoc/>
public class EditTrackTemplateContentInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionTypeNoNull Options { get; set; }
/// <inheritdoc/>
public int? Id { get; set; }
/// <summary>
/// 是否可删
/// </summary>
public bool? IsCanDelete { get; set; }
/// <summary>
/// 是否对外
/// </summary>
public bool? IsExternal { get; set; }
/// <summary>
/// 轨迹内容id
/// </summary>
public int? TrackContentId { get; set; }
/// <summary>
/// 轨迹模板id
/// </summary>
public int? TrackTemplateId { get; set; }
}

View File

@ -0,0 +1,28 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackTemplates
{
/// <summary>
/// 获取轨迹模版分页输入
/// </summary>
public class GetPageTrackTemplateInput : PageInfoInput
{
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 关键字
/// </summary>
public string? Keywords { get; set; }
///// <summary>
///// 轨迹模版id,轨迹映射的查询使用
///// </summary>
//public int TrackTemplateId { get; set; }
/// <summary>
/// 选中的轨迹模版id
/// </summary>
public List<int>? SelectIds { get; set; }
}
}

View File

@ -0,0 +1,100 @@
namespace SJZY.Track.Application.Contract.Dtos.TrackTemplates
{
/// <summary>
/// 获取轨迹模版详情
/// </summary>
public class GetTrackTemplateDetailDto
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 子系统
/// </summary>
public string SubSystem { get; set; }
/// <summary>
/// 模版名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 模版代码
/// </summary>
public string Code { get; set; }
}
/// <summary>
/// 获取轨迹模版列表
/// </summary>
public class GetTrackTemplateListDto
{
/// <summary>
/// 轨迹模版id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 模板名称
/// </summary>
public string Name { set; get; }
/// <summary>
/// 模版代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 所属子系统
/// </summary>
public string SubSystem { set; get; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { set; get; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
}
/// <summary>
/// 编辑轨迹模版
/// </summary>
public class EditTrackTemplateInput
{
/// <summary>
/// Id
/// </summary>
public int Id { set; get; }
/// <summary>
/// 操作类型
/// </summary>
public OptionType Options { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { set; get; }
/// <summary>
/// 模板名称
/// </summary>
public string? Name { set; get; }
/// <summary>
/// 模板代码
/// </summary>
public string? Code { set; get; }
}
}

View File

@ -0,0 +1,11 @@
using SJZY.Expand.ABP.Core.PublicMethords;
namespace SJZY.Track.Application.Contract.Dtos.TrackTemplates;
public class SortTrackTemplateContentInput
{
/// <summary>
/// 排序信息
/// </summary>
public List<DropdownListDataDto> SortInfo { get; set; }
}

View File

@ -0,0 +1,29 @@
namespace SJZY.Track.Application.Contract.Events;
public class TrackDeleteEvent
{
/// <summary>
/// 订单id
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 轨迹代码
/// </summary>
public List<string> TrackCodes { get; set; } = null!;
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 上游子系统id
/// </summary>
public int UpSubSystemId { get; set; }
/// <summary>
/// 已经处理过的订单
/// </summary>
public List<int> Visited { get; set; } = new();
}

View File

@ -0,0 +1,36 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
namespace SJZY.Track.Application.Contract.Events;
public class TrackUpsertEvent : UpsertTrackInput
{
/// <summary>
/// 订单id
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 客户id
/// </summary>
public int CustomId { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 订单是否推送完成(异步维护)
/// </summary>
public bool IsPushCompleted { get; set; }
/// <summary>
/// 上游子系统id
/// </summary>
public int UpSubSystemId { get; set; }
/// <summary>
/// 已经处理过的订单
/// </summary>
public List<int> Visited { get; set; } = new();
}

View File

@ -0,0 +1,39 @@
namespace SJZY.Track.Application.Contract.Events;
public class UpdateOrderTrackEvent
{
/// <summary>
/// 订单Id
/// </summary>
public int OrderId { get; set; }
/// <summary>
/// 此次发生的轨迹是否意味完成
/// </summary>
public bool IsCompleted { get; set; }
/// <summary>
/// 轨迹内容
/// </summary>
public string TrackContent { get; set; } = null!;
/// <summary>
/// 轨迹内容英文
/// </summary>
public string TrackEnContent { get; set; } = null!;
/// <summary>
/// 轨迹发生地
/// </summary>
public string TrackPlace { get; set; } = null!;
/// <summary>
/// 轨迹发生时间
/// </summary>
public DateTime TrackTime { get; set; }
/// <summary>
/// 轨迹时区
/// </summary>
public float TrackTimeZone { get; set; }
}

View File

@ -0,0 +1,4 @@
// Global using directives
global using SJZY.Expand.ABP.Common.Enums;
global using SJZY.Expand.ABP.Core.Common.Dto;

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>0.0.2</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -0,0 +1,5 @@
namespace SJZY.Track.Application.Contract.Services;
public interface ITrackContentService
{
}

View File

@ -0,0 +1,5 @@
namespace SJZY.Track.Application.Contract.Services;
public interface ITrackFlagService
{
}

View File

@ -0,0 +1,18 @@
namespace SJZY.Track.Application.Contract.Services;
public interface ITrackPushCacheService
{
/// <summary>
/// 判断客户是否需要推送
/// </summary>
/// <param name="customId"></param>
/// <returns></returns>
Task<bool> IsPushAsync(int customId);
/// <summary>
/// 更新缓存
/// </summary>
/// <param name="customId"></param>
/// <param name="isPush"></param>
Task UpdateAsync(int customId, bool isPush);
}

View File

@ -0,0 +1,5 @@
namespace SJZY.Track.Application.Contract.Services;
public interface ITrackStatusService
{
}

View File

@ -0,0 +1,10 @@
using Volo.Abp.Modularity;
namespace SJZY.Track.Application.Contract;
public class SjzyTrackApplicationContractModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
}
}

View File

@ -1,81 +0,0 @@
using SJZY.Expand.ABP.Core.Localization;
using SJZY.LoggerCenter.HttpApi;
using SJZY.Track.Application.Localization;
using SJZY.UserCenter.Contracts;
using SJZY.UserCenter.SharedModel;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AutoMapper;
using Volo.Abp.FluentValidation;
using Volo.Abp.Http.Client;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace SJZY.Track.Application
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(RepositoryModule),
typeof(AbpFluentValidationModule),
typeof(AbpLocalizationModule),
typeof(AbpVirtualFileSystemModule),
typeof(AbpHttpClientModule),
typeof(LoggerCenterHttpApiModule)
)]
public class ApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<ApplicationModule>(true);
});
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(ApplicationModule).Assembly);//创建动态api
});
//添加虚拟文件系统
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<ApplicationModule>("SJZY.Track.Application");
});
//添加多语言
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TrackLocalizationResource>("zh")
.AddBaseTypes(typeof(SjzyBasicLocalization))
.AddVirtualJson("/Localization/Resources");
});
//日志中心
context.Services.AddHttpClientProxies(typeof(LoggerCenterHttpApiModule).Assembly, "LoggerCenter", false);
//用户中心
context.Services.AddHttpClientProxies(typeof(SjzyUserCenterHttpApiModule).Assembly, "UserCenter", false);
}
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientActions.Add(async (remoteName, serviceProvider, httpClient) =>
{
//如果设置Token,前端需要传入Token 否则引发异常
httpClient.SetTokenHeader();
httpClient.Timeout = TimeSpan.FromMinutes(3);
await Task.CompletedTask;
});
});
}
}
}

View File

@ -1,33 +0,0 @@
using AutoMapper;
using SJZY.Track.Application.Dtos.Demo;
using SJZY.Track.Repository.Demo.ValueObjects;
namespace SJZY.Track.Application.AutoMapper
{
internal class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<UnifyPageResultDto<DemoEntity>, UnifyPageResultDto<GetDemoListByPageOutput>>(MemberList.None);
CreateMap<GetDemoListByPageInput, DemoValueObject>(MemberList.None).ReverseMap();
CreateMap<UnifyPageResultDto<GetDemoListByPageInput>, UnifyPageResultDto<DemoValueObject>>(MemberList.None).ReverseMap();
/*
代码说明:
MemberList.None的意思是,忽略源对象和目标对象的属性匹配检查,其他可选值:MemberList.Source(检查是否映射了所有源成员)、MemberList.Destination(检查是否映射了所有目标成员)
.ReverseMap()的意思是配置双向调用关系,既一行代码既支持从 GetDemoListByPageInput -> DemoValueObject 的映射,同时也支持从 DemoValueObject -> GetDemoListByPageInput 的映射
如果对一对模型多次配置规则,会以最后一次为准,配置了这样规则后,最终执行结果是 Name + 444
CreateMap<DemoInput, DemoEntity>().ForMember(dest => dest.Description, opt => opt.MapFrom(m => m.Name + "22"));
CreateMap<DemoInput, DemoEntity>().ForMember(dest => dest.Description, opt => opt.MapFrom(m => m.Name + "444"));
*/
CreateMap<DemoEntity, DemoInput>(MemberList.None).ReverseMap();
CreateMap<DemoEntity, GetDemoListByPageOutput>(MemberList.None);
CreateMap<DemoEntity, DemoDetailSaveInput>(MemberList.None).ReverseMap();
}
}
}

View File

@ -1,43 +0,0 @@
using AutoMapper;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Dtos.Demo;
namespace SJZY.Track.Application.AutoMapper
{
/// <summary>
/// 稍复杂的配置类
/// </summary>
internal class DemoAutoMapperProfile : Profile
{
public DemoAutoMapperProfile()
{
CreateMap<ComplexAutomapperDemoInput, ComplexAutomapperDemoOutput>(MemberList.None)
//层级不一致的场景
.ForMember(dest => dest.QQ, opt => opt.MapFrom(source => source.UserInfo.QQ))
//数据类型不一致的场景,这里如果不指定映射规则会直接取枚举的key值
.ForMember(dest => dest.Gender, opt => opt.MapFrom(source => source.Gender.GetDescription()))
//一些简单计算的场景,酌情使用...
.ForMember(dest => dest.Age, opt => opt.MapFrom(source => GetAgeByBirthdate(source.UserInfo.BirthDay)))
//结构不一致的场景
.ForMember(dest => dest.RoleIds, opt => opt.MapFrom(source => source.UserRoleInputList.Select(m => m.Id).ToArray()))
//条件映射(这里只是举例,日常开发时sqlsugar在新增时会避开自增主键)
.ForMember(dest => dest.Id, opt =>
{
opt.Condition(src => src.OptionType == OptionType.删除 || src.OptionType == OptionType.修改);
});
}
public int GetAgeByBirthdate(DateTime birthdate)
{
DateTime now = DateTime.Now;
int age = now.Year - birthdate.Year;
if (now.Month < birthdate.Month || (now.Month == birthdate.Month && now.Day < birthdate.Day))
{
age--;
}
return age < 0 ? 0 : age;
}
}
}

View File

@ -0,0 +1,32 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Dtos.Order;
using Volo.Abp.AutoMapper;
namespace SJZY.Track.Application.AutoMapper;
public class OrderAutoMapperProfile : Profile
{
public OrderAutoMapperProfile()
{
CreateMap<UpsertOrderInput, OrderEntity>(MemberList.None);
CreateMap<UpdateOrderInput, OrderEntity>(MemberList.None);
CreateMap<OrderTemplateInfo, OrderTemplateEntity>(MemberList.None)
.ForMember(dest => dest.ServiceProviderId, opt => opt.MapFrom(m => m.ServiceProviderId ?? 0))
.ForMember(dest => dest.TrackTemplateId, opt => opt.MapFrom(m => m.TemplateId));
CreateMap<OrderFlightInfo, OrderFlightEntity>(MemberList.None);
CreateMap<GetPageTrackOrderInput, GetPageTrackOrderInputVO>(MemberList.None);
CreateMap<TrackOrderVO, TrackOrderDto>(MemberList.None);
CreateMap<UnifyPageResultDto<TrackOrderVO>, UnifyPageResultDto<TrackOrderDto>>(MemberList.None);
CreateMap<TrackDetailsIndex, TrackOrderDetailDto>(MemberList.None).Ignore(dest => dest.TrackTimeZone)
.ForMember(dest => dest.Id, opt => opt.Ignore())
.ForMember(dest => dest.Code, opt => opt.MapFrom(m => m.TrackCode))
.ForMember(dest => dest.Content, opt => opt.MapFrom(m => m.TrackContent))
.ForMember(dest => dest.EnContent, opt => opt.MapFrom(m => m.TrackEnContent))
.ForMember(dest => dest.TrackTimeZoneValue, opt => opt.MapFrom(m => m.TrackTimeZone));
}
}

View File

@ -0,0 +1,13 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
namespace SJZY.Track.Application.AutoMapper;
public class TrackAutoMapperProfile:Profile
{
public TrackAutoMapperProfile()
{
CreateMap<UpsertTrackInput, TrackUpsertEvent>(MemberList.None);
}
}

View File

@ -0,0 +1,22 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackContents;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Dtos.TrackContents;
namespace SJZY.Track.Application.AutoMapper
{
public class TrackContentAutoMapperProfile : Profile
{
public TrackContentAutoMapperProfile()
{
CreateMap<EditTrackContentInput, TrackContentEntity>(MemberList.None)
.ForMember(dest => dest.IsCompleted, opt => opt.MapFrom(source => source.IsFinish));
CreateMap<GetTrackContentDetailVO, GetTrackContentDetailDto>(MemberList.None);
CreateMap<GetPageTrackContentInput, GetPageTrackContentVO>(MemberList.None);
CreateMap<GetTrackContentListVO, GetTrackContentListDto>(MemberList.None);
CreateMap<UnifyPageResultDto<GetTrackContentListVO>, UnifyPageResultDto<GetTrackContentListDto>>(
MemberList.None);
CreateMap<EditTrackContentMapInput, TrackContentMapEntity>(MemberList.None);
}
}
}

View File

@ -0,0 +1,21 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackFlags;
using SJZY.Track.Domain.Aggregates.TrackFlagAggregate;
using SJZY.Track.Domain.Dtos.TrackFlags;
namespace SJZY.Track.Application.AutoMapper
{
public class TrackFlagAutoMapperProfile : Profile
{
public TrackFlagAutoMapperProfile()
{
CreateMap<EditTrackFlagInput, TrackFlagEntity>(MemberList.None)
.ForMember(dest => dest.Name, opt => opt.MapFrom(source => source.Flag));
//.ForMember(dest => dest.IsCompleted, opt => opt.MapFrom(source => source.IsFinish));
CreateMap<GetTrackFlagDetailVO, GetTrackFlagDetailDto>(MemberList.None);
CreateMap<GetTrackFlagListVO, GetTrackFlagListDto>(MemberList.None);
CreateMap<UnifyPageResultDto<GetTrackFlagListVO>, UnifyPageResultDto<GetTrackFlagListDto>>(MemberList.None);
CreateMap<GetPageTrackFlagInput, GetPageTrackFlagVO>(MemberList.None);
}
}
}

View File

@ -0,0 +1,19 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackPull;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using Volo.Abp.AutoMapper;
namespace SJZY.Track.Application.AutoMapper;
public class TrackPullAutoMapperProfile : Profile
{
public TrackPullAutoMapperProfile()
{
CreateMap<EditTrackPullConfigInput, TrackPullConfigEntity>(MemberList.None);
CreateMap<EditTrackPullConfigInput, TrackPushPullParamsConfigEntity>(MemberList.None).Ignore(dest => dest.Id)
.ForMember(dest => dest.IsPush, opt => opt.MapFrom(source => false));
CreateMap<UpdateTrackPullContentInput, TrackPullContentConfigEntity>(MemberList.None)
.ForMember(dest => dest.TrackKeyword, opt => opt.MapFrom(src => string.Join(',', src.TrackKeywords)))
.ForMember(dest => dest.TrackKeywordReverse, opt => opt.MapFrom(src => string.Join(',', src.TrackKeywordReverses)));
}
}

View File

@ -0,0 +1,19 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using Volo.Abp.AutoMapper;
namespace SJZY.Track.Application.AutoMapper;
public class TrackPushAutoMapperProfile : Profile
{
public TrackPushAutoMapperProfile()
{
CreateMap<EditTrackPushConfigInput, TrackPushConfigEntity>(MemberList.None)
.ForMember(dest => dest.TrackTemplateId, opt => opt.MapFrom(source => string.Join(',', source.TrackTemplateIds)));
CreateMap<EditTrackPushConfigInput, TrackPushPullParamsConfigEntity>(MemberList.None).Ignore(dest => dest.Id)
.ForMember(dest => dest.IsPush, opt => opt.MapFrom(source => true));
CreateMap<EditTrackPushContentInput, TrackPushContentConfigEntity>(MemberList.None);
}
}

View File

@ -0,0 +1,24 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackStatus;
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.TrackStatus;
namespace SJZY.Track.Application.AutoMapper
{
public class TrackStatusAutoMapperProfile : Profile
{
public TrackStatusAutoMapperProfile()
{
CreateMap<EditTrackStatusInput, TrackStatusEntity>(MemberList.None)
//层级不一致的场景
.ForMember(dest => dest.Status, opt => opt.MapFrom(source => source.TrackStatus))
.ForMember(dest => dest.EnStatus, opt => opt.MapFrom(source => source.EntrackStatus))
.ForMember(dest => dest.Node, opt => opt.MapFrom(source => source.NodeId));
CreateMap<GetTrackStatusDetailVO, GetTrackStatusDetailDto>(MemberList.None);
CreateMap<GetPageTrackStatusInput, GetPageTrackStatusVO>(MemberList.None);
CreateMap<GetTrackStatusListVO, GetTrackStatusListDto>(MemberList.None);
CreateMap<UnifyPageResultDto<GetTrackStatusListVO>, UnifyPageResultDto<GetTrackStatusListDto>>(MemberList
.None);
}
}
}

View File

@ -0,0 +1,23 @@
using AutoMapper;
using SJZY.Track.Application.Contract.Dtos.TrackTemplates;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.TrackTemplate;
namespace SJZY.Track.Application.AutoMapper;
/// <summary>
/// 轨迹模版自动映射
/// </summary>
public class TrackTemplateAutoMapperProfile : Profile
{
public TrackTemplateAutoMapperProfile()
{
CreateMap<GetTrackTemplateDetailVO, GetTrackTemplateDetailDto>(MemberList.None);
CreateMap<EditTrackTemplateContentInput, TrackTemplateContentEntity>(MemberList.None);
CreateMap<EditTrackTemplateInput, TrackTemplateEntity>(MemberList.None);
CreateMap<GetPageTrackTemplateInput, GetPageTrackTemplateVO>(MemberList.None);
CreateMap<GetTrackTemplateListVO, GetTrackTemplateListDto>(MemberList.None);
CreateMap<UnifyPageResultDto<GetTrackTemplateListVO>, UnifyPageResultDto<GetTrackTemplateListDto>>(MemberList
.None);
}
}

View File

@ -1,89 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
/// <summary>
/// automapper 复杂转换样例
/// </summary>
public class ComplexAutomapperDemoInput
{
/// <summary>
/// 编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public OptionType OptionType { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 性别
/// </summary>
public Gender Gender { get; set; }
/// <summary>
/// 用户信息
/// </summary>
public UserInfoInput UserInfo { get; set; }
/// <summary>
/// 用户角色
/// </summary>
public List<UserRoleInput> UserRoleInputList { get; set; }
/// <summary>
/// 拓展演示,目前大家共同约定,暂时不使用充血模型
/// </summary>
/// <returns></returns>
public string GetAddress()
{
return "辽宁省沈阳市...";
}
}
public class ComplexAutomapperDemoOutput
{
/// <summary>
/// 编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 性别
/// </summary>
public string Gender { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// qq号码
/// </summary>
public string QQ { get; set; }
/// <summary>
/// 地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 角色编号
/// </summary>
public int[] RoleIds { get; set; }
}
}

View File

@ -1,48 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class DemoDetailSaveInput
{
/// <summary>
///
/// </summary>
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 详情合集
/// </summary>
public List<DemoDetailInput> DemoDetailList { get; set; }
}
public class DemoDetailInput
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// t_demo.id
/// </summary>
public int DemoId { get; set; }
/// <summary>
/// 一些说明..
/// </summary>
public string OtherInfo { get; set; }
}
}

View File

@ -1,42 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class DemoInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionType Option { get; set; }
/// <summary>
///
/// </summary>
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
//以下两个属性用来说明类型转换
/// <summary>
/// 创建人id
/// </summary>
public string CreateUserId { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public string CreateTime { get; set; }
}
}

View File

@ -1,11 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class ExcelImportOuput
{
[MiniExcelLibs.Attributes.ExcelColumnName("姓名")]
public string Name { get; set; }
[MiniExcelLibs.Attributes.ExcelColumnName("年龄")]
public int Age { get; set; }
}
}

View File

@ -1,10 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class GetDemoListByPageInput : PageInfoInput
{
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
}
}

View File

@ -1,27 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class GetDemoListByPageOutput
{
/// <summary>
///
/// </summary>
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
public DateTime CreateTime { get; set; }
}
}

View File

@ -1,9 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class MyCustomerResultOutput
{
public string Code { get; set; }
public string Message { get; set; }
}
}

View File

@ -1,15 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class OssUploadOutput
{
/// <summary>
/// 文件key
/// </summary>
public string Key { get; set; }
/// <summary>
/// 文件路径
/// </summary>
public string Url { get; set; }
}
}

View File

@ -1,42 +0,0 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
namespace SJZY.Track.Application.Dtos.Demo
{
public class SwaggerDemoInput
{
/// <summary>
/// 年龄
/// </summary>
/// <example>18</example> 这里可以写一些初始值
public int Age { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别(枚举的展示样例)
/// </summary>
public Gender Gender { get; set; }
/// <summary>
/// 隐藏属性
/// </summary>
[JsonIgnore]
public int MyProperty { get; set; }
}
public enum Gender
{
[Description("纯爷们")]
男 = 2,
[Description("大姑娘")]
女 = 5,
[Description("你憋问")]
未知 = 8
}
}

View File

@ -1,98 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class ValidateExecuteInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionType Option { get; set; }
/// <summary>
/// 主键编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 雪花ID
/// </summary>
public long SnowId { get; set; }
/// <summary>
/// 登录账号
/// </summary>
public string LoginName { get; set; }
/// <summary>
/// 登录密码
/// </summary>
public string? PassWord { get; set; }
/// <summary>
/// 登录密码确认
/// </summary>
public string PassWordAgain { get; set; }
/// <summary>
/// 最大金额额度
/// </summary>
public decimal TotalQuota { get; set; }
/// <summary>
/// 最大数量
/// </summary>
public int MaxCount { get; set; }
/// <summary>
/// 最小数量
/// </summary>
public int MiniCount { get; set; }
/// <summary>
/// 用户信息
/// </summary>
public UserInfoInput UserInfoInput { get; set; }
/// <summary>
/// 用户角色
/// </summary>
public List<UserRoleInput> UserRoleInputList { get; set; }
}
public class UserInfoInput
{
/// <summary>
/// 生日
/// </summary>
public DateTime BirthDay { get; set; }
/// <summary>
/// qq号码
/// </summary>
public string QQ { get; set; }
/// <summary>
/// 电子邮箱
/// </summary>
public string Email { get; set; }
/// <summary>
/// 用户姓名
/// </summary>
public string UserName { get; set; }
}
public class UserRoleInput
{
/// <summary>
/// 角色编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string Name { get; set; }
}
}

View File

@ -1,6 +0,0 @@
namespace SJZY.Track.Application.Dtos.Demo
{
public class ValidateExecuteOutput
{
}
}

View File

@ -0,0 +1,35 @@
using DotNetCore.CAP;
using Newtonsoft.Json;
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.EventHandlers;
public class InterfaceRelayTrackRefreshEventHandler : ITransientDependency, ICapSubscribe
{
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
public InterfaceRelayTrackRefreshEventHandler(IOrderRepository orderRepository, IProvideQueries provideQueries)
{
_orderRepository = orderRepository;
_provideQueries = provideQueries;
}
[CapSubscribe(GlobalConst.InterfaceRelayTrackRefreshSubscribe)]
public async Task ConsumerAsync(InterfaceRelayTrackRefreshEvent @event)
{
if (@event.RequestParams is List<OrderNoInfo> requestParams)
{
var orderNos = requestParams.Select(x => x.OrderNo).ToList();
// tips:attach返回的是服务商id,必有
var pullContentConfigs = await _provideQueries.GetPullContentConfigsAsync(int.Parse(@event.Attach));
// 轨迹清洗入库
}
}
}

View File

@ -0,0 +1,76 @@
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.EventHandlers;
public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
{
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly ICapPublisher _capPublisher;
public TrackDeleteEventHandler(IProvideQueries provideQueries, ITrackDetailsRepository trackDetailsRepository,
IOrderRepository orderRepository, ICapPublisher capPublisher)
{
_provideQueries = provideQueries;
_trackDetailsRepository = trackDetailsRepository;
_orderRepository = orderRepository;
_capPublisher = capPublisher;
}
[CapSubscribe(GlobalConst.TrackDeleteSubscribe)]
public async Task ConsumerAsync(TrackDeleteEvent @event)
{
if (@event.Visited.Contains(@event.OrderId))
{
LogHelper.Error($"轨迹订单循环依赖预警:{@event.Visited.JoinAsString(",")}");
return;
}
@event.Visited.Add(@event.OrderId);
// 不同子系统需要做内容映射
if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
var mapCodes = await _provideQueries
.MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCodes.ToArray());
if (mapCodes.Count == 0)
{
//throw new BusinessException(message: "订单跨子系统,未配置内容映射,请联系管理员");
return;
}
@event.TrackCodes = mapCodes;
}
await DeleteTrackAsync(@event);
}
private async Task DeleteTrackAsync(TrackDeleteEvent @event)
{
// 删除轨迹
await _trackDetailsRepository.DeleteTrackAsync(@event.OrderId, @event.TrackCodes);
// 根据订单关联关系异步向下刷
var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId);
foreach (var linkedOrder in linkedOrders)
{
var nextEvent = new TrackDeleteEvent
{
OrderId = linkedOrder.OrderId,
TrackCodes = @event.TrackCodes,
SubSystemId = linkedOrder.SubSystemId,
UpSubSystemId = @event.SubSystemId
};
await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, nextEvent);
}
}
}

View File

@ -0,0 +1,143 @@
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Queries;
using SJZY.UserCenter.HttpApi.Services;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.EventHandlers;
public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly ITrackPushCacheService _trackPushCacheService;
private readonly ICapPublisher _capPublisher;
public TrackUpsertEventHandler(IOrderRepository orderRepository, ICapPublisher capPublisher,
IProvideQueries provideQueries, ITrackDetailsRepository trackDetailsRepository,
ITrackPushCacheService trackPushCacheService)
{
_orderRepository = orderRepository;
_capPublisher = capPublisher;
_provideQueries = provideQueries;
_trackDetailsRepository = trackDetailsRepository;
_trackPushCacheService = trackPushCacheService;
}
[CapSubscribe(GlobalConst.TrackUpsertSubscribe)]
public async Task ConsumerAsync(TrackUpsertEvent @event)
{
if (@event.Visited.Contains(@event.OrderId))
{
LogHelper.Error($"轨迹订单循环依赖预警:{@event.Visited.JoinAsString(",")}");
return;
}
@event.Visited.Add(@event.OrderId);
// 不同子系统需要做内容映射
if (@event.UpSubSystemId != 0 && @event.UpSubSystemId != @event.SubSystemId)
{
var mapCode = (await _provideQueries
.MapTrackCodesAsync(@event.UpSubSystemId, @event.SubSystemId, @event.TrackCode))
.FirstOrDefault();
if (mapCode == default)
{
// 跨子系统没做映射的轨迹不处理
return;
}
@event.TrackCode = mapCode;
}
await UpsertTrackAsync(@event);
}
private async Task UpsertTrackAsync(TrackUpsertEvent @event)
{
// 不存在则新增轨迹,存在则更新
var track = await _trackDetailsRepository.GetFirstOrDefaultAsync(@event.OrderId, @event.TrackCode);
var orderIsCompleted = false;
if (track == default)
{
// 根据轨迹code在订单模板内容中寻找匹配的
var trackContent = await _provideQueries.MatchTrackContentAsync(@event.OrderId, @event.TrackCode);
if (trackContent == default)
{
//throw new BusinessException(message: $"订单:{@event.OrderNo} 所绑定的模板,没有一条内容可以匹配轨迹代码:{@event.TrackCode}");
return;
}
orderIsCompleted = trackContent.IsCompleted;
track = new TrackDetailsIndex
{
IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}",
OrderId = @event.OrderId,
OrderNo = @event.OrderNo,
OrderType = @event.OrderType,
TrackStatus = trackContent.Status,
TrackCode = @event.TrackCode,
TrackContent = trackContent.Content,
TrackEnContent = trackContent.EnContent,
TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime!.Value,
TrackTimeZone = @event.TrackTimeZone!.Value,
IsCanDelete = trackContent.IsCanDelete,
CreateUser = CurrentUserRequest.CurrentUser.Name,
CreateTime = DateTime.Now
};
// todo:推送只做新增的,更新和删除的不做先
if (!@event.IsPushCompleted && await _trackPushCacheService.IsPushAsync(@event.CustomId))
{
//await PushTrack();
}
}
else
{
track.TrackPlace = @event.TrackPlace;
track.TrackTime = @event.TrackTime!.Value;
track.TrackTimeZone = @event.TrackTimeZone!.Value;
track.UpdateUser = CurrentUserRequest.CurrentUser.Name;
track.UpdateTime = DateTime.Now;
}
await _trackDetailsRepository.UpsertAsync(track);
// 触发订单主表更新事件
await _capPublisher.PublishAsync(GlobalConst.UpdateOrderTrackSubscribe, new UpdateOrderTrackEvent
{
OrderId = track.OrderId,
IsCompleted = orderIsCompleted,
TrackContent = track.TrackContent,
TrackEnContent = track.TrackEnContent,
TrackPlace = track.TrackPlace,
TrackTime = track.TrackTime,
TrackTimeZone = track.TrackTimeZone
});
// 根据订单关联关系异步向下刷
var linkedOrders = await _orderRepository.GetLinkedOrdersAsync(@event.OrderId);
foreach (var linkedOrder in linkedOrders)
{
var nextEvent = @event.DeepCopy();
nextEvent.OrderId = linkedOrder.OrderId;
nextEvent.OrderType = linkedOrder.OrderType;
nextEvent.OrderNo = linkedOrder.OrderNo;
nextEvent.SubSystemId = linkedOrder.SubSystemId;
nextEvent.IsPushCompleted = linkedOrder.IsPushCompleted;
nextEvent.CustomId = linkedOrder.CustomId;
nextEvent.UpSubSystemId = @event.SubSystemId;
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, nextEvent);
}
}
}

View File

@ -0,0 +1,40 @@
using DotNetCore.CAP;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.EventHandlers;
public class UpdateOrderTrackEventHandler : ITransientDependency, ICapSubscribe
{
private readonly IOrderRepository _orderRepository;
public UpdateOrderTrackEventHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
[CapSubscribe(GlobalConst.UpdateOrderTrackSubscribe)]
public async Task ConsumerAsync(UpdateOrderTrackEvent @event)
{
var order = await _orderRepository.GetFirstAsync(x => x.Id == @event.OrderId);
if (order == default) return;
if (order.IsCompleted) return;
order.LatestTrackContent = @event.TrackContent;
order.LatestTrackEnContent = @event.TrackEnContent;
order.LatestTrackPlace = @event.TrackPlace;
order.LatestTrackTime = @event.TrackTime;
order.LatestTrackTimeZone = @event.TrackTimeZone;
if (@event.IsCompleted) order.IsCompleted = true;
else if (order.LatestTrackTime != null &&
order.LatestTrackTime.Value.Subtract(TimeSpan.FromHours(order.LatestTrackTimeZone ?? 0)) >
@event.TrackTime.Subtract(TimeSpan.FromHours(@event.TrackTimeZone))) return;
await _orderRepository.UpdateColumnAsync(order, x => new
{
x.IsCompleted, x.LatestTrackContent, x.LatestTrackEnContent, x.LatestTrackPlace, x.LatestTrackTime,
x.LatestTrackTimeZone
});
}
}

View File

@ -2,8 +2,7 @@
global using Microsoft.Extensions.DependencyInjection;
global using SJZY.Expand.ABP.Common.Enums;
global using SJZY.Expand.ABP.Core.Common.Dto;
global using SJZY.Track.Repository;
global using SJZY.Track.Repository.Demo.Entitys;
global using Volo.Abp;
global using Volo.Abp.Application.Services;
global using Volo.Abp.Validation;
global using SJZY.Track.Domain;

View File

@ -3,6 +3,13 @@
"texts": {
"NotNull1": "{0} is not null",
"NotFindData": "No data found under the specified number",
"ParameterDemo1": "{0} in {1} to do {2}"
"ParameterDemo1": "{0} in {1} to do {2}",
"TemplateExist": "The template code already exists under the currently selected subsystem",
"TrackContentExist": "The trace code or trace content or trace content in the current subsystem is repeated in English",
"TrackStatusExist": "The trajectory status code or trajectory status or trajectory status in English is repeated under the current subsystem",
"TrackFlagExist": "Duplicate code or flag in the current subsystem",
"IsExistTrackPullConfig": "Track Pull The template has been bound. Delete the track pull before deleting the template",
"IsExistTrackStatus": "The trajectory content has been bound to the trajectory status. Delete the trajectory content before deleting the trajectory status",
"IsExistTrackFlag": "The track content has been bound to the track mark. Delete the track content before deleting the track mark"
}
}

View File

@ -3,6 +3,13 @@
"texts": {
"NotFindData": "未找到指定编号下的任何数据!",
"ParameterDemo": "{0}在{1}地方做了{2}动作",
"ParameterDemo1": "{0}在{1}地方做了{2}动作"
"ParameterDemo1": "{0}在{1}地方做了{2}动作",
"TemplateExist": "模板代码已存在于当前选择的子系统下",
"TrackContentExist": "当前子系统下轨迹代码或轨迹内容或轨迹内容英文重复",
"TrackStatusExist": "当前子系统下轨迹状态代码或轨迹状态或轨迹状态英文重复",
"TrackFlagExist": "当前子系统下代码或标记重复",
"IsExistTrackPullConfig": "轨迹拉取已绑定了该模版,请先删除轨迹拉取再删除该模版",
"IsExistTrackStatus": "轨迹内容已经绑定了该轨迹状态,请先删除轨迹内容后再删除该轨迹状态",
"IsExistTrackFlag": "轨迹内容已经绑定了该轨迹标记,请先删除轨迹内容后再删除该轨迹标记"
}
}

View File

@ -1,33 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<!--<Nullable>enable</Nullable>-->
</PropertyGroup>
<Import Project="../../common.props" />
<ItemGroup>
<Compile Remove="Validations\Docuai\**" />
<EmbeddedResource Remove="Validations\Docuai\**" />
<None Remove="Validations\Docuai\**" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SJZY.Expand.AliyunOSS" Version="7.0.8" />
<PackageReference Include="SJZY.Expand.Excel" Version="7.0.4" />
<PackageReference Include="SJZY.UserCenter.HttpApi" Version="1.3.3" />
<PackageReference Include="SJZY.UserCenter.SharedModel" Version="2.3.3" />
<PackageReference Include="Volo.Abp.Http.Client" Version="7.0.2" />
<PackageReference Include="Volo.Abp.FluentValidation" Version="7.0.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SJZY.InterfaceRelay.Application.Contracts" Version="7.1.2" />
<PackageReference Include="Volo.Abp.Http.Client" Version="7.0.2" />
<PackageReference Include="Volo.Abp.FluentValidation" Version="7.0.2" />
<PackageReference Include="SJZY.UserCenter.HttpApi" Version="3.0.3-alpha8" />
<PackageReference Include="SJZY.Expand.CAP" Version="7.8.0" />
<PackageReference Include="DotNetCore.CAP" Version="8.0.1" />
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="8.0.1" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="8.0.1" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SJZY.Track.HttpApi\SJZY.Track.HttpApi.csproj" />
<ProjectReference Include="..\SJZY.Track.Repository\SJZY.Track.Repository.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Interfaces\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" />
<ProjectReference Include="..\SJZY.Track.Application.Contract\SJZY.Track.Application.Contract.csproj" />
</ItemGroup>
</Project>

View File

@ -1,234 +0,0 @@
using SJZY.Expand.ABP.Core.Common;
using SJZY.Track.Application.Dtos.Demo;
using SJZY.Track.Repository.Demo.Services;
using SJZY.Track.Repository.Demo.ValueObjects;
using Volo.Abp.Http.Client.DynamicProxying;
namespace SJZY.Track.Application.Services.Demo
{
/// <summary>
/// 接口请求完整样例
/// </summary>
[ApiExplorerSettings(GroupName = "Demo")]
public class InterFaceDemoService : ApplicationService
{
#region 构造函数
private readonly IDemoRepository _demoRepository;
public InterFaceDemoService(IDemoRepository demoRepository)
{
_demoRepository = demoRepository;
}
#endregion
#region 增删改
/// <summary>
/// 增删改
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("InterFace/Edit")]
public async Task<LongIdBaseDto> Edit(DemoInput input)
{
var res = new LongIdBaseDto();
if (input.Option == OptionType.新增)
{
var entity = ObjectMapper.Map<DemoInput, DemoEntity>(input);
res.Id = await _demoRepository.InsertReturnIdentityAsync(entity);
}
else if (input.Option == OptionType.修改 || input.Option == OptionType.删除)
{
var demoInfo = await _demoRepository.GetById1(input.Id);
if (demoInfo == null)
{
//校验数据是否存在...
throw new BusinessException(message: "未找到指定编号下的数据");
}
res.Id = demoInfo.Id;
if (input.Option == OptionType.删除)
{
//await _demoRepository.DeleteAsync(demoInfo); //真删除
//软删除
demoInfo.IsDeleted = true;
await _demoRepository.UpdateAsync(demoInfo);
}
else
{
var entity = ObjectMapper.Map(input, demoInfo);
await _demoRepository.UpdateAsync(entity);
}
}
return res;
}
#endregion
#region 局部更新最佳实践
/// <summary>
/// 局部更新最佳实践
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("InterFace/UpdatePartColumns")]
public async Task<IdBaseDto> UpdatePartColumns(DemoInput input)
{
var demoInfo = await _demoRepository.GetById1(input.Id);
if (demoInfo == null)
{
//校验数据是否存在...
throw new BusinessException(message: "未找到指定编号下的数据");
}
//更新同时忽略某几项参数
await _demoRepository.UpdatePartColumns(demoInfo);
return new IdBaseDto() { Id = input.Id };
}
#endregion
#region 分页查询接口
/// <summary>
/// 分页查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("InterFace/GetListByPage")]
public async Task<UnifyPageResultDto<GetDemoListByPageOutput>> GetListByPage(GetDemoListByPageInput input)
{
//分页时返回值统一用 PageResultDto<> 类型
var list = await _demoRepository.GetListByPage(input.PageSize, input.PageIndex, input.Name);
var res = ObjectMapper.Map<UnifyPageResultDto<DemoEntity>, UnifyPageResultDto<GetDemoListByPageOutput>>(list);
return res;
}
#endregion
#region 入参转换
/// <summary>
/// 入参转换
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("InterFace/InputToValueObject")]
public async Task<List<GetDemoListByPageOutput>> InputToValueObject(GetDemoListByPageInput input)
{
var obj = ObjectMapper.Map<GetDemoListByPageInput, DemoValueObject>(input);
var list = await _demoRepository.InputToValueObject(obj);
var res = ObjectMapper.Map<List<DemoEntity>, List<GetDemoListByPageOutput>>(list);
return res;
}
#endregion
#region 原生sql
/// <summary>
/// 原生sql
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
[HttpPost("InterFace/OriginalSql")]
public async Task<UnifyPageResultDto<DemoValueObject>> OriginalSql(DemoValueObject obj)
{
var list = await _demoRepository.OriginalSql(obj);
return list;
}
#endregion
#region 自定义返回结果格式
/// <summary>
/// 自定义返回结果格式
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Demo/CustomerResult")]
[CustomerResult]
public async Task<MyCustomerResultOutput> GetListAsync()
{
/*
说明:
理论上我们有全公司级别的返回值约定,不管是前端调后端,还是后端微服务间的调用,都应完全遵循该规范。
但不排除有些特殊情况下,必须要返回自定义格式的场景。
*/
var res = new MyCustomerResultOutput();
res.Code = "200";
res.Message = "这是一个自定义返回结果";
return res;
}
#endregion
#region 约定类型下返回null
/// <summary>
/// 约定类型下返回null
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Demo/ReturnNull")]
public async Task<MyCustomerResultOutput> ReturnNull()
{
MyCustomerResultOutput res = null;
return res;
}
#endregion
#region
/// <summary>
/// 没有返回值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Demo/WithoutReturnObject")]
public async Task<UnifyResultDto> WithoutReturnObject()
{
return null;
}
#endregion
#region 主从关系实体存储
/// <summary>
/// 主从关系实体存储
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
[HttpPost("InterFace/EntityRelationSave")]
public async Task<UnifyResultDto> EntityRelationSave(DemoDetailSaveInput input)
{
var obj = ObjectMapper.Map<DemoDetailSaveInput, DemoEntity>(input);
var res = await _demoRepository.EntityRelationSave(obj);
return new UnifyResultDto(res);
}
#endregion
#region 数据缓存
/// <summary>
/// 数据缓存
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("InterFace/GetDataCache")]
public async Task<DemoEntity> GetDataCache(IdBaseDto input)
{
var res = await _demoRepository.GetDataCache(input.Id);
return res;
}
#endregion
//[HttpPost("InterFace/AAAA")]
//public async Task<UnifyResultDto> AAAA()
//{
// var result = await _httpClientProxy.Service.GetSystemTokenAsync("Track");
// return result;
//}
}
}

View File

@ -0,0 +1,100 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 订单关联服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class OrderLinkService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly IBasicQuery<OrderLinkEntity> _orderLinkQuery;
public OrderLinkService(IBasicQuery<OrderLinkEntity> orderLinkQuery, IOrderRepository orderRepository)
{
_orderLinkQuery = orderLinkQuery;
_orderRepository = orderRepository;
}
/// <summary>
/// 关联订单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Order/Link")]
public async Task<bool> LinkOrderAsync(LinkOrderInput input)
{
var orderId = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => x.Id);
if (orderId == default)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
//todo:循环关联?
if (input.OrderType == input.LinkOrderType)
{
throw new BusinessException(message: "不能同级关联");
}
if (input.LinkOrderNos.Count < 1 || input.LinkOrderType == 0) return true;
// 单号去重,去空,去自己
input.LinkOrderNos = input.LinkOrderNos
.Where(x => !x.IsNullOrWhiteSpace() && x != input.OrderNo)
.Distinct().ToList();
// 解绑
if (!input.IsLink) return await UnLinkOrderAsync(input);
// 关联订单
return await DoLinkOrderAsync(input, orderId);
}
private async Task<bool> DoLinkOrderAsync(LinkOrderInput input, int orderId)
{
// 获取已关联的订单
var linkOrderNos = await _orderLinkQuery.GetListAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo && x.LinkOrderType == input.LinkOrderType,
x => x.LinkOrderNo);
// 计算出未关联的订单
var noLinkOrderNos = input.LinkOrderNos.Except(linkOrderNos);
// 过滤掉不存在的订单
var canLinkOrders = await _orderRepository.GetListAsync(x =>
x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo),
x => new { x.Id, x.OrderNo });
await _orderRepository.LinkOrderAsync(canLinkOrders.Select(x => new OrderLinkEntity
{
OrderId = orderId,
OrderNo = input.OrderNo,
OrderType = input.OrderType,
LinkOrderId = x.Id,
LinkOrderNo = x.OrderNo,
LinkOrderType = input.LinkOrderType
}).ToList());
// todo:补轨迹
return true;
}
private async Task<bool> UnLinkOrderAsync(LinkOrderInput input)
{
var unLinkIds = await _orderLinkQuery.GetListAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo &&
x.LinkOrderType == input.LinkOrderType && input.LinkOrderNos.Contains(x.LinkOrderNo),
x => x.Id);
// real del
await _orderRepository.UnLinkByIdsAsync(unLinkIds);
return true;
}
}

View File

@ -0,0 +1,82 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Dtos.Order;
using SJZY.UserCenter.HttpApi.Services;
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 订单服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class OrderService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly ITrackDetailsRepository _trackDetailsRepository;
public OrderService(IOrderRepository orderRepository,
ITrackDetailsRepository trackDetailsRepository
)
{
_orderRepository = orderRepository;
_trackDetailsRepository = trackDetailsRepository;
}
/// <summary>
/// 创建订单,订单已存在则视为更新
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Order/Upsert")]
public async Task<string> UpsertAsync(UpsertOrderInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo);
if (order != default)
{
// 订单已存在则视为更新
await UpdateOrderAsync(input, order);
return "更新成功";
}
order = ObjectMapper.Map<UpsertOrderInput, OrderEntity>(input);
order.SubSystemId = CurrentUserRequest.SubSystemId;
order.OrderTemplates = ObjectMapper.Map<List<OrderTemplateInfo>, List<OrderTemplateEntity>>(input.Templates!);
order.OrderFlights = ObjectMapper.Map<List<OrderFlightInfo>, List<OrderFlightEntity>>(input.FlightInfos!);
await _orderRepository.CreateOrderAsync(order);
return "创建成功";
}
/// <summary>
/// 删除订单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Order/Delete")]
public async Task<bool> DeleteOrderAsync(DeleteOrderInput input)
{
var orderId = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => x.Id);
if (orderId == default)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
await _orderRepository.DeleteOrderAsync(orderId);
return true;
}
private async Task UpdateOrderAsync(UpdateOrderInput input, OrderEntity order)
{
order = ObjectMapper.Map(input, order);
order.OrderTemplates = ObjectMapper.Map<List<OrderTemplateInfo>, List<OrderTemplateEntity>>(input.Templates!);
order.OrderFlights = ObjectMapper.Map<List<OrderFlightInfo>, List<OrderFlightEntity>>(input.FlightInfos!);
await _orderRepository.UpdateOrderAsync(order);
}
}

View File

@ -0,0 +1,57 @@
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using Volo.Abp.Http.Client.DynamicProxying;
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 轨迹拉取服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class TrackPullService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly IHttpClientProxy<IInterfaceForwardService> _httpClientProxy;
public TrackPullService(IOrderRepository orderRepository,
IHttpClientProxy<IInterfaceForwardService> httpClientProxy)
{
_orderRepository = orderRepository;
_httpClientProxy = httpClientProxy;
}
/// <summary>
/// 刷新轨迹
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Track/Refresh")]
public async Task<bool> RefreshTrackAsync(RefreshTrackInput input)
{
if (input.OrderNos.Count == 0)
{
throw new BusinessException(message: "订单号数组不能为空");
}
input.OrderNos = input.OrderNos.Distinct().ToList();
var orderTemplates = await _orderRepository.GetOrderTemplatesAsync(input.OrderNos);
foreach (var group in orderTemplates.GroupBy(x => x.ServiceProviderId))
{
var data = group.Select(x => new OrderNoInfo
{
OrderType = x.OrderType,
OrderNo = x.OrderNo
}).ToList();
await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
"A012", "yicang", 42, data, GlobalConst.InterfaceRelayTrackRefreshSubscribe
, group.Key.ToString());
}
return true;
}
}

View File

@ -0,0 +1,11 @@
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 轨迹推送服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class TrackPushService: ApplicationService
{
}

View File

@ -0,0 +1,108 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 轨迹查询服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class TrackQueryService : ApplicationService
{
private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
public TrackQueryService(ITrackDetailsRepository trackDetailsRepository,
IOrderRepository orderRepository,
IProvideQueries provideQueries)
{
_trackDetailsRepository = trackDetailsRepository;
_orderRepository = orderRepository;
_provideQueries = provideQueries;
}
/// <summary>
/// 根据订单号获取轨迹
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Track/Query")]
public async Task<List<GetTrackOutput>> QueryAsync(GetTrackInput input)
{
if (input.OrderNos.Count > 500)
{
throw new BusinessException(message: "最多只能查询500单");
}
var res = new List<GetTrackOutput>();
input.OrderNos = input.OrderNos.Where(x => !x.IsNullOrWhiteSpace()).Distinct().ToList(); // 单号去重、去空
var details = await _trackDetailsRepository.GetListAsync(input.OrderType, input.OrderNos);
foreach (var group in details.GroupBy(x => x.OrderId))
{
var item = new GetTrackOutput();
var trackDetails = group.ToList();
item.OrderNo = trackDetails.First().OrderNo;
item.TrackDetails = trackDetails.Select(x => new TrackDetail
{
Code = x.TrackCode,
Status = x.TrackStatus,
Content = x.TrackContent,
Location = x.TrackPlace,
Time = x.TrackTime.AddHours(input.TimeZone ?? 8 - x.TrackTimeZone),
TimeZone = input.TimeZone ?? 8
}).ToList();
res.Add(item);
}
await TrackDetailSort(res, input);
return res;
}
private async Task TrackDetailSort(List<GetTrackOutput> list, GetTrackInput input)
{
switch (input.SortMethod)
{
case SortMethod.ByTrackTime:
// tips:quick-sort 直接修改原list
list.ForEach(item => item.TrackDetails.Sort((a, b) => a.Time.CompareTo(b.Time)));
break;
case SortMethod.ByTrackTimeDesc:
list.ForEach(item => item.TrackDetails.Sort((a, b) => b.Time.CompareTo(a.Time)));
break;
case SortMethod.ByTemplate:
var orderTemplates = await _provideQueries
.GetOrderTemplateLinksAsync(input.OrderType, input.OrderNos);
var distinctTemplateIds = orderTemplates.Select(x => x.TemplateId).Distinct().ToList();
var templateContent = await _provideQueries.GetOrderedTrackCodesAsync(distinctTemplateIds);
list.ForEach(item =>
{
var codes = new List<string>();
// 多模板拼接显示
foreach (var orderTemplate in orderTemplates.Where(x => x.OrderNo == item.OrderNo))
{
codes.AddRange(templateContent
.Where(t => t.TemplateId == orderTemplate.TemplateId) // 按模板
.Where(t => t.IsExternal) // 过滤不对外的
.Select(t => t.Code));
}
item.TrackDetails = item.TrackDetails
.Where(x => codes.Contains(x.Code)) // 剔除不在模板内容中的元素
.OrderBy(x => codes.IndexOf(x.Code)) // 按照在模板内容的位置排序
.ToList();
});
break;
default:
throw new ArgumentOutOfRangeException(nameof(input.SortMethod), input.SortMethod, "不支持的排序方式");
}
}
}

View File

@ -0,0 +1,93 @@
using DotNetCore.CAP;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ProvideServices;
/// <summary>
/// 轨迹服务
/// </summary>
[ApiExplorerSettings(GroupName = "提供接口")]
[Route("/ProviderService")]
public class TrackService : ApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
private readonly ICapPublisher _capPublisher;
public TrackService(IOrderRepository orderRepository, IProvideQueries provideQueries, ICapPublisher capPublisher)
{
_orderRepository = orderRepository;
_provideQueries = provideQueries;
_capPublisher = capPublisher;
}
/// <summary>
/// 新增/更新订单轨迹接口
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Track/Upsert")]
public async Task<bool> UpsertTrackAsync(UpsertTrackInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new
{
x.Id, x.SubSystemId, x.IsPushCompleted, x.CustomId
});
if (order == default)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
// 新增/更新轨迹
var @event = ObjectMapper.Map<UpsertTrackInput, TrackUpsertEvent>(input);
@event.OrderId = order.Id;
@event.SubSystemId = order.SubSystemId;
@event.IsPushCompleted = order.IsPushCompleted;
@event.CustomId = order.CustomId;
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
return true;
}
/// <summary>
/// 删除轨迹
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Track/Delete")]
public async Task<bool> DeleteTrackAsync(DeleteTrackInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new
{
x.Id, x.SubSystemId, x.IsPushCompleted, x.CustomId
});
if (order == default)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
var codes = await _provideQueries.GetCanDeleteTrackCodesAsync(order.Id, input.TrackCodes);
if (codes.Count == 0)
{
throw new BusinessException(message: "没有一个轨迹代码是可删的");
}
// 删除轨迹
var @event = new TrackDeleteEvent
{
OrderId = order.Id,
TrackCodes = codes,
SubSystemId = order.SubSystemId,
};
await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
return true;
}
}

View File

@ -0,0 +1,297 @@
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.TrackContents;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.TrackContents;
using SJZY.Track.Domain.Queries;
using System.Linq.Expressions;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackContents
{
/// <summary>
/// 轨迹内容服务
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹内容")]
[Route("/Track/Content")]
public class TrackContentService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackContentRepository _trackContentRepository;
private readonly IBasicQuery<TrackContentMapEntity> _trackContentMapBasicQuery;
private readonly IBasicQuery<TrackTemplateContentEntity> _trackTemplateContentBasicQuery;
public TrackContentService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackContentRepository trackContentRepository,
IBasicQuery<TrackContentMapEntity> trackContentMapBasicQuery,
IBasicQuery<TrackTemplateContentEntity> trackTemplateContentBasicQuery
)
{
this._stringLocalizer = stringLocalizer;
this._trackContentRepository = trackContentRepository;
this._trackContentMapBasicQuery = trackContentMapBasicQuery;
this._trackTemplateContentBasicQuery = trackTemplateContentBasicQuery;
}
/// <summary>
/// 轨迹内容编辑
/// </summary>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<UnifyResultDto> EditAsync(EditTrackContentInput input)
{
return input.Options switch
{
OptionType.新增 => await AddAsync(input),
OptionType.修改 => await UpdateAsync(input),
OptionType.删除 => await DeleteAsync(input),
_ => throw new BusinessException(message: "当前操作动作不合法")
};
}
/// <summary>
/// 根据内容id获取轨迹内容
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<UnifyResultDto<GetTrackContentDetailDto>> GetDetailAsync(int id)
{
var detailInfo = await _trackContentRepository.GetDetailAsync(id);
if (detailInfo == null)
{
return new UnifyResultDto<GetTrackContentDetailDto>(false, null, "未查询到轨迹状态");
}
var dto = ObjectMapper.Map<GetTrackContentDetailVO, GetTrackContentDetailDto>(detailInfo);
return new UnifyResultDto<GetTrackContentDetailDto>("200", "", dto);
}
/// <summary>
/// 获取分页轨迹内容
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetList")]
public async Task<UnifyPageResultDto<GetTrackContentListDto>> GetPageTrackContent(
GetPageTrackContentInput input)
{
var vo = ObjectMapper.Map<GetPageTrackContentInput, GetPageTrackContentVO>(input);
var resultDto = await _trackContentRepository.GetPageTrackContent(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<GetTrackContentListVO>, UnifyPageResultDto<GetTrackContentListDto>>(
resultDto);
return pageResultDto;
}
#region 私有方法
private async Task<UnifyResultDto> AddAsync(EditTrackContentInput input)
{
#region 业务逻辑校验
var trackContentEntitys = await _trackContentRepository.GetListAsync(a =>
a.SubSystemId == input.SubSystemId && (a.Code == input.Code ||
a.Content == input.Content || a.EnContent == input.EnContent));
if (trackContentEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackContentExist"]);
var codes = trackContentEntitys.FirstOrDefault(a => a.Code==input.Code);
if (codes!=null)
{
throw new BusinessException(message: "该子系统下轨迹代码已存在");
}
var contents = trackContentEntitys.FirstOrDefault(a => a.Content==input.Content);
if (contents!=null)
{
throw new BusinessException(message: "该子系统下轨迹内容已存在");
}
var contentEns = trackContentEntitys.FirstOrDefault(a => a.EnContent==input.EnContent);
if (contentEns!=null)
{
throw new BusinessException(message: "该子系统下轨迹内容英文已存在");
}
//throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在");
}
#endregion 业务逻辑校验
var entity = ObjectMapper.Map<EditTrackContentInput, TrackContentEntity>(input);
var isTrue = await _trackContentRepository.InsertAsync(entity);
return new UnifyResultDto("200", "新增成功", isTrue);
}
private async Task<UnifyResultDto> UpdateAsync(EditTrackContentInput input)
{
#region 业务逻辑校验
var trackContentEntitys = await _trackContentRepository.GetListAsync(a => a.Id != input.Id &&
a.SubSystemId == input.SubSystemId && (a.Code == input.Code ||
a.Content == input.Content || a.EnContent == input.EnContent));
if (trackContentEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackContentExist"]);
//throw new BusinessException(message: "当前子系统下,轨迹代码或轨迹内容或轨迹内容英文存在");
var codes = trackContentEntitys.FirstOrDefault(a => a.Code==input.Code);
if (codes!=null)
{
throw new BusinessException(message: "该子系统下轨迹代码已存在");
}
var contents = trackContentEntitys.FirstOrDefault(a => a.Content==input.Content);
if (contents!=null)
{
throw new BusinessException(message: "该子系统下轨迹内容已存在");
}
var contentEns = trackContentEntitys.FirstOrDefault(a => a.EnContent==input.EnContent);
if (contentEns!=null)
{
throw new BusinessException(message: "该子系统下轨迹内容英文已存在");
}
}
#endregion 业务逻辑校验
//更新的时候需要覆盖内容映射轨迹代码
var templateEntity = await _trackContentRepository.GetFirstAsync(a => a.Id == input.Id);
bool isTrue = false;
using (var ts = TransactionScopeHelper.Create())
{
// 如果轨迹内容的子系统和code发生变化,同步到轨迹映射表
if (templateEntity.SubSystemId != input.SubSystemId || templateEntity.Code != input.Code)
{
await _trackContentRepository.UpdateMapAsync(x => new TrackContentMapEntity
{
SubSystemId = input.SubSystemId,
TrackContentCode = input.Code
}, x => x.TrackContentId == input.Id);
await _trackContentRepository.UpdateMapAsync(x => new TrackContentMapEntity
{
MapSubSystemId = input.SubSystemId,
MapTrackContentCode = input.Code
}, x => x.MapTrackContentId == input.Id);
}
ObjectMapper.Map(input, templateEntity);
isTrue = await _trackContentRepository.UpdateAsync(templateEntity);
ts.Complete();
}
return new UnifyResultDto("200", "修改成功", isTrue);
}
private async Task<UnifyResultDto> DeleteAsync(EditTrackContentInput input)
{
#region 业务校验
//查询是否关联了轨迹模版内容
var isExistTemplate = await _trackContentRepository.GetTemplateIsExist(input.Id);
if (isExistTemplate)
{
throw new BusinessException(message: "该轨迹内容关联轨迹模板,禁止删除");
}
//var trackTemplateContents = await _trackTemplateContentBasicQuery.GetListAsync(a => a.TrackContentId == input.Id);
//if (trackTemplateContents.Any())
//{
// throw new BusinessException(message: "该轨迹内容关联轨迹模板,禁止删除");
//}
//需要加个判断,存在内容映射,则出提示
//var trackContentMapEntities = await _trackContentMapBasicQuery.GetListAsync(a => a.TrackContentId == input.Id || a.MapTrackContentId == input.Id);
//if (trackContentMapEntities.Any())
//{
// throw new BusinessException(message: "无法删除该内容,该轨迹内容已在轨迹内容映射中使用了,请检查");
//}
#endregion 业务校验
var isTrue = await _trackContentRepository.SoftDeleteAsync(x => x.Id == input.Id);
return new UnifyResultDto("200", "删除成功", isTrue);
}
#endregion 私有方法
/// <summary>
/// 轨迹内容映射列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetMapPage")]
public async Task<UnifyPageResultDto<GetTrackContentMapPageOutputVO>> GetMapPageAsync([FromBody] GetTrackContentMapPageInputVO input)
{
return await _trackContentRepository.GetMapPageAsync(input);
}
/// <summary>
/// 轨迹内容映射详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetMapDetail")]
public async Task<GetTrackContentMapDetailOutputVO> GetMapDetailAsync(int id)
{
return await _trackContentRepository.GetMapDetailAsync(id);
}
/// <summary>
/// 轨迹内容映射编辑
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("EditMap")]
public async Task<bool> EditMapAsync([FromBody] EditTrackContentMapInput input)
{
if (input.Options != OptionTypeNoNull.删除)
{
if (input.SubSystemId == input.MapSubSystemId) throw new BusinessException(message: _stringLocalizer["NotAllowedToMapSubSystem"]);
Expression<Func<TrackContentMapEntity, bool>> isMapAnyExp = x =>
x.TrackContentId == input.TrackContentId && x.MapTrackContentId == input.MapTrackContentId;
if (input.Options == OptionTypeNoNull.修改) isMapAnyExp.And(x => x.Id != input.Id);
if (await _trackContentRepository.IsMapAnyAsync(isMapAnyExp))
throw new BusinessException(message: _stringLocalizer["IsTrackContentMapAny"]);
}
switch (input.Options)
{
case OptionTypeNoNull.新增:
{
var trackContentMapEntity = ObjectMapper.Map<EditTrackContentMapInput, TrackContentMapEntity>(input);
await _trackContentRepository.InsertMapAsync(trackContentMapEntity);
}
break;
case OptionTypeNoNull.修改:
{
var oldTrackContentMapEntity = await _trackContentRepository.GetMapByIdAsync(input.Id!.Value) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]);
ObjectMapper.Map(input, oldTrackContentMapEntity);
await _trackContentRepository.UpdateMapAsync(oldTrackContentMapEntity);
}
break;
case OptionTypeNoNull.删除:
await _trackContentRepository.SoftDeleteMapAsync(x => x.Id == input.Id);
break;
default:
throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum,
nameof(EditTrackContentMapInput.Options)]);
}
return true;
}
}
}

View File

@ -0,0 +1,163 @@
using Microsoft.Extensions.Localization;
using SJZY.Track.Application.Contract.Dtos.TrackFlags;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackFlagAggregate;
using SJZY.Track.Domain.Dtos.TrackFlags;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackFlags
{
/// <summary>
/// 轨迹标记服务
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹标记")]
[Route("/Track/Flag")]
public class TrackFlagService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackFlagRepository _trackFlagRepository;
private readonly ITrackContentRepository _trackContentRepository;
public TrackFlagService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackFlagRepository trackFlagRepository,
ITrackContentRepository trackContentRepository
)
{
this._stringLocalizer = stringLocalizer;
this._trackFlagRepository = trackFlagRepository;
this._trackContentRepository=trackContentRepository;
}
/// <summary>
/// 轨迹标记编辑
/// </summary>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<UnifyResultDto> EditAsync(EditTrackFlagInput input)
{
return input.Options switch
{
OptionType.新增 => await AddAsync(input),
OptionType.修改 => await UpdateAsync(input),
OptionType.删除 => await DeleteAsync(input),
_ => throw new BusinessException(message: "当前操作动作不合法")
};
}
/// <summary>
/// 根据标记id获取轨迹标记
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<UnifyResultDto<GetTrackFlagDetailDto>> GetDetailAsync(int id)
{
var detailInfo = await _trackFlagRepository.GetDetailAsync(id);
if (detailInfo == null)
{
return new UnifyResultDto<GetTrackFlagDetailDto>(false, null, "未查询到轨迹状态");
}
var dto = ObjectMapper.Map<GetTrackFlagDetailVO, GetTrackFlagDetailDto>(detailInfo);
return new UnifyResultDto<GetTrackFlagDetailDto>("200", "", dto);
}
/// <summary>
/// 获取分页轨迹标记
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetList")]
public async Task<UnifyPageResultDto<GetTrackFlagListDto>> GetPageTrackFlag(GetPageTrackFlagInput input)
{
var vo = ObjectMapper.Map<GetPageTrackFlagInput, GetPageTrackFlagVO>(input);
var resultDto = await _trackFlagRepository.GetPageTrackFlag(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<GetTrackFlagListVO>, UnifyPageResultDto<GetTrackFlagListDto>>(
resultDto);
return pageResultDto;
}
#region 私有方法
private async Task<UnifyResultDto> AddAsync(EditTrackFlagInput input)
{
#region 业务校验
var trackFlagsEntitys = await _trackFlagRepository.GetListAsync(a =>
a.SubSystemId == input.SubSystemId && (a.Code == input.Code || a.Name == input.Flag));
if (trackFlagsEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackFlagExist"]);
//throw new BusinessException(message: "当前子系统下已存在轨迹标记代码");
var trackFlagCode = trackFlagsEntitys.FirstOrDefault(a => a.Code==input.Code);
if (trackFlagCode!=null)
{
throw new BusinessException(message: "该子系统下代码已存在");
}
var trackFlagName = trackFlagsEntitys.FirstOrDefault(a => a.Name==input.Flag);
if (trackFlagName!=null)
{
throw new BusinessException(message: "该子系统下标记已存在");
}
}
#endregion
var entity = ObjectMapper.Map<EditTrackFlagInput, TrackFlagEntity>(input);
var isTrue = await _trackFlagRepository.InsertAsync(entity);
return new UnifyResultDto("200", "新增成功", isTrue);
}
private async Task<UnifyResultDto> UpdateAsync(EditTrackFlagInput input)
{
#region 业务校验
var trackFlagsEntitys = await _trackFlagRepository.GetListAsync(a => a.Id != input.Id &&
a.SubSystemId == input.SubSystemId && (a.Code == input.Code ||
a.Name == input.Flag));
if (trackFlagsEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackFlagExist"]);
//throw new BusinessException(message: "当前子系统下已存在轨迹标记代码");
var trackFlagCode = trackFlagsEntitys.FirstOrDefault(a => a.Code==input.Code);
if (trackFlagCode!=null)
{
throw new BusinessException(message: "该子系统下代码已存在");
}
var trackFlagName = trackFlagsEntitys.FirstOrDefault(a => a.Name==input.Flag);
if (trackFlagName!=null)
{
throw new BusinessException(message: "该子系统下标记已存在");
}
}
#endregion
var templateEntity = await _trackFlagRepository.GetFirstAsync(a => a.Id == input.Id);
ObjectMapper.Map(input, templateEntity);
var isTrue = await _trackFlagRepository.UpdateAsync(templateEntity);
return new UnifyResultDto("200", "修改成功", isTrue);
}
private async Task<UnifyResultDto> DeleteAsync(EditTrackFlagInput input)
{
#region 业务校验
var isExistContent = await _trackContentRepository.GetFirstAsync(a => a.TrackFlagId==input.Id);
if (isExistContent!=null)
{
//throw new BusinessException(message: _stringLocalizer["IsExistTrackFlag"]);
throw new BusinessException(message: "该标记关联轨迹内容,禁止删除");
}
#endregion
var isTrue = await _trackFlagRepository.SoftDeleteAsync(x => x.Id == input.Id);
return new UnifyResultDto("200", "删除成功", isTrue);
}
#endregion
}
}

View File

@ -0,0 +1,115 @@
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Dtos.Order;
using SJZY.Track.Domain.Dtos.TrackTemplate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackOrders
{
[ApiExplorerSettings(GroupName = "轨迹订单")]
[Route("/Track/Order")]
public class TrackOrderService : ApplicationService, ITransientDependency
{
private readonly IOrderRepository _orderRepository;
private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly ITrackContentRepository _trackContentRepository;
public TrackOrderService(
IOrderRepository orderRepository,
ITrackDetailsRepository trackDetailsRepository,
ITrackContentRepository trackContentRepository
)
{
this._orderRepository=orderRepository;
this._trackDetailsRepository=trackDetailsRepository;
this._trackContentRepository=trackContentRepository;
}
#region 轨迹订单明细
/// <summary>
/// 根据轨迹订单id获取轨迹订单明细列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetDetails")]
public async Task<List<TrackOrderDetailDto>> GetOrderDetails(GetOrderDetailsInput input)
{
var trackDetails = await _trackDetailsRepository.GetListAsync(input.OrderId);
if (!trackDetails.IsNullOrEmpty())
{
var list = ObjectMapper.Map<List<TrackDetailsIndex>, List<TrackOrderDetailDto>>(trackDetails);
var trackCodes = list.Where(a => !a.Code.IsNullOrWhiteSpace()).Select(a => a.Code).Distinct().ToList();
var trackContents = await _trackContentRepository.GetTrackContentAttributeValue(new GetTemplateContentAttributeValueInputVO
{
SubSystemId =input.SubSystemId,
TrackTemplateIds = input.TrackTemplateIds,
TrackCodes=trackCodes
});
input.TrackTemplateIds =input.TrackTemplateIds.Where(a => a>0).ToList();
int id = 1;
list.ForEach(a =>
{
a.Id = id++;
var trackContentsOfTemplates = trackContents.Where(b => b.SubSystemId==input.SubSystemId && b.TrackCode==a.Code
&& input.TrackTemplateIds.Contains(b.TrackTemplateId));
GetTemplateContentAttributeValueVO trackContent = null;
var insertData = input.TrackTemplateIds.Intersect(trackContentsOfTemplates.Select(aa => aa.TrackTemplateId)).ToList();
if (!insertData.IsNullOrEmpty())
{
trackContent =trackContentsOfTemplates.FirstOrDefault(a => a.TrackTemplateId==insertData.FirstOrDefault());
}
if (trackContent!=null)
{
a.IsCanDelete=trackContent.IsCanDelete;
a.IsExternal = trackContent.IsExternal;
}
if (a.TrackTimeZoneValue==0f)
{
a.TrackTimeZone=$"GTM{" "}+00:00";
}
else
{
// 将小数形式的小时转换为时区偏移量
int hours = (int)a.TrackTimeZoneValue; // 提取整数部分作为小时
int minutes = (int)((a.TrackTimeZoneValue - hours) * 60); // 将小数部分乘以 60 转换为分钟
TimeSpan offset = new TimeSpan(hours, minutes, 0);
string timeZoneStr = offset.ToString();
string flag = a.TrackTimeZoneValue>0f ? "+" : "";
a.TrackTimeZone = $"GTM{" "}{flag}{timeZoneStr.RemovePostFix(":00")}";
}
});
return list;
}
return new List<TrackOrderDetailDto>();
}
#endregion
#region 轨迹订单列表
/// <summary>
/// 获取分页的轨迹订单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetTrackOrderList")]
public async Task<UnifyPageResultDto<TrackOrderDto>> GetPageTrackOrder(GetPageTrackOrderInput input)
{
var vo = ObjectMapper.Map<GetPageTrackOrderInput, GetPageTrackOrderInputVO>(input);
var pageList = await _orderRepository.GetPageTrackOrder(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<TrackOrderVO>, UnifyPageResultDto<TrackOrderDto>>(pageList);
return pageResultDto;
}
#endregion
}
}

View File

@ -0,0 +1,241 @@
using System;
using System.Linq.Expressions;
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.TrackPull;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.Common;
using SJZY.Track.Domain.Dtos.TrackPull;
using SqlSugar;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackPull;
/// <summary>
/// 轨迹拉取
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹拉取")]
[Route("/Track/PullConfig")]
public class TrackPullService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackPullConfigRepository _trackPullConfigRepository;
private readonly ITrackTemplateRepository _trackTemplateRepository;
public TrackPullService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackPullConfigRepository trackPullConfigRepository,
ITrackTemplateRepository trackTemplateRepository)
{
_stringLocalizer = stringLocalizer;
_trackPullConfigRepository = trackPullConfigRepository;
_trackTemplateRepository = trackTemplateRepository;
}
/// <summary>
/// 轨迹拉取配置列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetPage")]
public async Task<UnifyPageResultDto<GetTrackPullConfigPageOutputVO>> GetPageAsync([FromBody] KeywordsInputVO input)
{
return await _trackPullConfigRepository.GetPageAsync(input);
}
/// <summary>
/// 轨迹拉取配置内容列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetContentPage")]
public async Task<UnifyPageResultDto<GetTrackPullContentPageOutputVO>> GetContentPageAsync(
[FromBody] GetTrackPullContentPageInputVO input)
{
return await _trackPullConfigRepository.GetContentPageAsync(input);
}
/// <summary>
/// 轨迹拉取配置详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<GetTrackPullConfigDetailOutputVO> GetDetailAsync(int id)
{
return await _trackPullConfigRepository.GetDetailAsync(id);
}
/// <summary>
/// 轨迹拉取配置内容详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetContentDetail")]
public async Task<GetTrackPullContentDetailOutputVO> GetContentDetailAsync(int id)
{
return await _trackPullConfigRepository.GetContentDetailAsync(id);
}
/// <summary>
/// 轨迹拉取配置编辑
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<bool> EditAsync([FromBody] EditTrackPullConfigInput input)
{
if (input.Options != OptionTypeNoNull.删除)
{
Expression<Func<TrackPullConfigEntity, bool>> isAnyExp = x =>
x.SubSystemId == input.SubSystemId && x.TrackTemplateId == input.TrackTemplateId &&
x.ServiceProviderId == input.ServiceProviderId;
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
if (await _trackPullConfigRepository.IsAnyAsync(isAnyExp))
throw new BusinessException(message: _stringLocalizer["IsTrackPullConfigAny"]);
}
switch (input.Options)
{
case OptionTypeNoNull.新增:
{
var trackPullEntity = ObjectMapper.Map<EditTrackPullConfigInput, TrackPullConfigEntity>(input);
var trackPullParamsEntity =
ObjectMapper.Map<EditTrackPullConfigInput, TrackPushPullParamsConfigEntity>(input);
var trackTemplateContentEntities =
await _trackTemplateRepository.GetContentListAsync(x => x.TrackTemplateId == input.TrackTemplateId);
var trackPullContentEntities = new List<TrackPullContentConfigEntity>();
using (var ts = TransactionScopeHelper.Create())
{
int id = await _trackPullConfigRepository.InsertReturnIdentityAsync(trackPullEntity);
trackPullParamsEntity.PullOrPushConfigId = id;
await _trackPullConfigRepository.InsertParamsAsync(trackPullParamsEntity);
foreach (var item in trackTemplateContentEntities)
{
trackPullContentEntities.Add(new()
{
TrackPullConfigId = id,
TrackContentId = item.TrackContentId
});
}
await _trackPullConfigRepository.InsertContentRangeAsync(trackPullContentEntities);
ts.Complete();
}
}
break;
case OptionTypeNoNull.修改:
{
var oldTrackPullEntity = await _trackPullConfigRepository.GetFirstAsync(x => x.Id == input.Id) ??
throw new BusinessException(message: _stringLocalizer["NotFindData"]);
var oldTrackPullParamsEntity =
await _trackPullConfigRepository.GetParamsSingleAsync(x =>
x.PullOrPushConfigId == input.Id && !x.IsPush);
var trackPullContentEntities = new List<TrackPullContentConfigEntity>();
if (oldTrackPullEntity.TrackTemplateId != input.TrackTemplateId)
{
var trackTemplateContentEntities =
await _trackTemplateRepository.GetContentListAsync(x =>
x.TrackTemplateId == input.TrackTemplateId);
foreach (var item in trackTemplateContentEntities)
{
trackPullContentEntities.Add(new()
{
TrackPullConfigId = oldTrackPullEntity.Id,
TrackContentId = item.TrackContentId
});
}
}
ObjectMapper.Map(input, oldTrackPullEntity);
ObjectMapper.Map(input, oldTrackPullParamsEntity);
using (var ts = TransactionScopeHelper.Create())
{
await _trackPullConfigRepository.UpdateAsync(oldTrackPullEntity);
await _trackPullConfigRepository.UpdateParamsAsync(oldTrackPullParamsEntity);
if (trackPullContentEntities.Count > 0)
{
await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.TrackPullConfigId == input.Id);
await _trackPullConfigRepository.InsertContentRangeAsync(trackPullContentEntities);
}
ts.Complete();
}
}
break;
case OptionTypeNoNull.删除:
using (var ts = TransactionScopeHelper.Create())
{
await _trackPullConfigRepository.SoftDeleteAsync(x => x.Id == input.Id);
await _trackPullConfigRepository.SoftDeleteParamsAsync(x =>
x.PullOrPushConfigId == input.Id && !x.IsPush);
await _trackPullConfigRepository.SoftDeleteContentAsync(x => x.TrackPullConfigId == input.Id);
ts.Complete();
}
break;
default:
throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum,
nameof(EditTrackPullConfigInput.Options)]);
}
return true;
}
/// <summary>
/// 轨迹拉取配置内容修改
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("UpdateContent")]
public async Task<bool> UpdateContentAsync([FromBody] UpdateTrackPullContentInput input)
{
Expression<Func<TrackPullContentConfigEntity, bool>> isContentAnyExp = x => x.Id != input.Id && x.TrackPullConfigId == input.TrackPullConfigId;
if (await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentId == input.TrackContentId)))
throw new BusinessException(message: _stringLocalizer["IsTrackPullContentAny"]);
else if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentCodeValue == input.TrackContentCodeValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPullContentCodeValueAny"]);
else if (!input.TrackStatusValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackStatusValue == input.TrackStatusValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPullContentStatusValueAny"]);
else if (!input.TrackContentValue.IsNullOrWhiteSpace() && await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentValue == input.TrackContentValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPullContentValueAny"]);
else if (!input.TrackKeywords.IsNullOrEmpty())
{
Expression<Func<TrackPullContentConfigEntity, bool>> trackKeywordExp = _ => false;
input.TrackKeywords!.ForEach(item => { trackKeywordExp = trackKeywordExp.Or(x => SqlFunc.SplitIn(x.TrackKeyword, item)); });
if (await _trackPullConfigRepository.IsContentAnyAsync(isContentAnyExp.And(trackKeywordExp)))
throw new BusinessException(message: _stringLocalizer["IsTrackPullContentKeywordsAny"]);
}
var oldTrackPullContentEntity = await _trackPullConfigRepository.GetContentByIdAsync(input.Id) ??
throw new BusinessException(message: _stringLocalizer["NotFindData"]);
ObjectMapper.Map(input, oldTrackPullContentEntity);
await _trackPullConfigRepository.UpdateContentAsync(oldTrackPullContentEntity);
return true;
}
}

View File

@ -0,0 +1,39 @@
using SJZY.Expand.ABP.Core;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackPush;
public class TrackPushCacheService : ITrackPushCacheService, ITransientDependency
{
private readonly IBasicQuery<TrackPushConfigEntity> _trackPushConfigQuery;
private string RedisKey(int customId) => GlobalConst.TrackPushKeyPrefix + customId;
public TrackPushCacheService(IBasicQuery<TrackPushConfigEntity> trackPushConfigQuery)
{
_trackPushConfigQuery = trackPushConfigQuery;
}
public async Task<bool> IsPushAsync(int customId)
{
var isPush =
await RedisHelper.Client.GetAsync<bool?>(RedisKey(customId));
if (isPush == null)
{
isPush = await _trackPushConfigQuery.GetFirstAsync(x => x.CustomId == customId,
x => x.IsAutoPush);
await RedisHelper.Client.SetAsync(RedisKey(customId), isPush);
}
return (bool)isPush;
}
public async Task UpdateAsync(int customId, bool isPush)
{
await RedisHelper.Client.SetAsync(RedisKey(customId), isPush);
}
}

View File

@ -0,0 +1,290 @@
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.Common;
using SJZY.Track.Domain.Dtos.TrackPush;
using SqlSugar;
using System.Linq.Expressions;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackPush;
/// <summary>
/// 轨迹推送
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹推送")]
[Route("/Track/PushConfig")]
public class TrackPushService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackPushConfigRepository _trackPushConfigRepository;
private readonly ITrackTemplateRepository _trackTemplateRepository;
private readonly ITrackPullConfigRepository _trackPullConfigRepository;
private readonly ITrackPushCacheService _trackPushCacheService;
public TrackPushService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackPushConfigRepository trackPushConfigRepository,
ITrackTemplateRepository trackTemplateRepository,
ITrackPullConfigRepository trackPullConfigRepository,
ITrackPushCacheService trackPushCacheService)
{
_stringLocalizer = stringLocalizer;
_trackPushConfigRepository = trackPushConfigRepository;
_trackTemplateRepository = trackTemplateRepository;
_trackPullConfigRepository = trackPullConfigRepository;
_trackPushCacheService = trackPushCacheService;
}
/// <summary>
/// 轨迹推送配置列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetPage")]
public async Task<UnifyPageResultDto<GetTrackPushConfigPageOutputVO>> GetPageAsync([FromBody] KeywordsInputVO input)
{
return await _trackPushConfigRepository.GetPageAsync(input);
}
/// <summary>
/// 轨迹推送配置内容列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetContentPage")]
public async Task<UnifyPageResultDto<GetTrackPushContentPageOutputVO>> GetContentPageAsync([FromBody] GetTrackPushContentPageInputVO input)
{
return await _trackPushConfigRepository.GetContentPageAsync(input);
}
/// <summary>
/// 轨迹推送配置详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<GetTrackPushConfigDetailOutputVO> GetDetailAsync(int id)
{
var res = await _trackPushConfigRepository.GetDetailAsync(id);
if (res is null) return null;
List<int> trackTemplateIds = res.TrackTemplateId.Split(',').Select(int.Parse).ToList();
var trackTemplateEntities = await _trackTemplateRepository.GetListAsync(x => trackTemplateIds.Contains(x.Id));
trackTemplateEntities.ForEach(item => { (res.TrackTemplate ??= new()).Add(new() { Value = item.Id, Key = item.Name }); });
return res;
}
/// <summary>
/// 轨迹推送配置内容详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetContentDetail")]
public async Task<GetTrackPushContentDetailOutputVO> GetContentDetailAsync(int id)
{
return await _trackPushConfigRepository.GetContentDetailAsync(id);
}
/// <summary>
/// 轨迹推送配置编辑
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<bool> EditAsync([FromBody] EditTrackPushConfigInput input)
{
if (input.Options != OptionTypeNoNull.删除)
{
Expression<Func<TrackPushConfigEntity, bool>> isAnyExp = x =>
x.SubSystemId == input.SubSystemId && x.CustomId == input.CustomId && x.ServiceProviderId == input.ServiceProviderId;
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
var trackTemplateIdExp = Expressionable.Create<TrackPushConfigEntity>();
input.TrackTemplateIds?.ForEach(item => { trackTemplateIdExp.Or(x => SqlFunc.SplitIn(x.TrackTemplateId, item.ToString())); });
isAnyExp = isAnyExp.And(trackTemplateIdExp.ToExpression());
if (await _trackPushConfigRepository.IsAnyAsync(isAnyExp))
throw new BusinessException(message: _stringLocalizer["IsTrackPushConfigAny"]);
}
switch (input.Options)
{
case OptionTypeNoNull.新增:
{
var trackPushEntity = ObjectMapper.Map<EditTrackPushConfigInput, TrackPushConfigEntity>(input);
var trackPushParamsEntity = ObjectMapper.Map<EditTrackPushConfigInput, TrackPushPullParamsConfigEntity>(input);
using (var ts = TransactionScopeHelper.Create())
{
int id = await _trackPushConfigRepository.InsertReturnIdentityAsync(trackPushEntity);
trackPushParamsEntity.PullOrPushConfigId = id;
await _trackPullConfigRepository.InsertParamsAsync(trackPushParamsEntity);
if (input.IsAutoPush) await _trackPushCacheService.IsPushAsync(input.CustomId);
ts.Complete();
}
}
break;
case OptionTypeNoNull.修改:
{
var oldTrackPushEntity = await _trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]);
int oldCustomId = oldTrackPushEntity.CustomId;
var oldTrackPushParamsEntity =
await _trackPullConfigRepository.GetParamsSingleAsync(x =>
x.PullOrPushConfigId == input.Id && x.IsPush);
ObjectMapper.Map(input, oldTrackPushEntity);
ObjectMapper.Map(input, oldTrackPushParamsEntity);
using (var ts = TransactionScopeHelper.Create())
{
await _trackPushConfigRepository.UpdateAsync(oldTrackPushEntity);
await _trackPullConfigRepository.UpdateParamsAsync(oldTrackPushParamsEntity);
await _trackPushCacheService.UpdateAsync(oldCustomId, false);
if (input.IsAutoPush) await _trackPushCacheService.IsPushAsync(input.CustomId);
ts.Complete();
}
}
break;
case OptionTypeNoNull.删除:
{
var oldTrackPushEntity = await _trackPushConfigRepository.GetFirstAsync(x => x.Id == input.Id) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]);
using (var ts = TransactionScopeHelper.Create())
{
await _trackPushConfigRepository.SoftDeleteAsync(x => x.Id == input.Id);
await _trackPullConfigRepository.SoftDeleteParamsAsync(x =>
x.PullOrPushConfigId == input.Id && x.IsPush);
await _trackPushConfigRepository.SoftDeleteContentAsync(x => x.TrackPushConfigId == input.Id);
await _trackPushCacheService.UpdateAsync(oldTrackPushEntity.CustomId, false);
ts.Complete();
}
}
break;
default:
throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum,
nameof(EditTrackPushConfigInput.Options)]);
}
return true;
}
/// <summary>
/// 轨迹推送配置内容编辑
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("EditContent")]
public async Task<bool> EditContentAsync([FromBody] EditTrackPushContentInput input)
{
if (input.Options != OptionTypeNoNull.删除)
{
Expression<Func<TrackPushContentConfigEntity, bool>> isContentAnyExp = x => x.TrackPushConfigId == input.TrackPushConfigId;
if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id);
if (await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentId == input.TrackContentId)))
throw new BusinessException(message: _stringLocalizer["IsTrackPushContentAny"]);
else if (!input.TrackContentCodeValue.IsNullOrWhiteSpace() && await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentCodeValue == input.TrackContentCodeValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPushContentCodeValueAny"]);
else if (!input.TrackStatusValue.IsNullOrWhiteSpace() && await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackStatusValue == input.TrackStatusValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPushContentStatusValueAny"]);
else if (!input.TrackContentValue.IsNullOrWhiteSpace() && await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackContentValue == input.TrackContentValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPushContentValueAny"]);
else if (!input.TrackEnContentValue.IsNullOrWhiteSpace() && await _trackPushConfigRepository.IsContentAnyAsync(isContentAnyExp.And(x => x.TrackEnContentValue == input.TrackEnContentValue)))
throw new BusinessException(message: _stringLocalizer["IsTrackPushEnContentValueAny"]);
}
switch (input.Options)
{
case OptionTypeNoNull.新增:
{
int maxSort = await _trackPushConfigRepository.ContentMaxAsync(x => x.Sort, x => x.TrackPushConfigId == input.TrackPushConfigId);
var entity = ObjectMapper.Map<EditTrackPushContentInput, TrackPushContentConfigEntity>(input);
entity.Sort = maxSort + 1;
await _trackPushConfigRepository.InsertContentAsync(entity);
break;
}
case OptionTypeNoNull.修改:
{
var entity = await _trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]);
ObjectMapper.Map(input, entity);
await _trackPushConfigRepository.UpdateContentAsync(entity);
break;
}
case OptionTypeNoNull.删除:
{
var entity = await _trackPushConfigRepository.GetContentByIdAsync(input.Id!.Value) ?? throw new BusinessException(message: _stringLocalizer["NotFindData"]);
using (var ts = TransactionScopeHelper.Create())
{
await _trackPushConfigRepository.SoftDeleteContentAsync(x => x.Id == input.Id);
await _trackPushConfigRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, x => x.TrackPushConfigId == entity.TrackPushConfigId && x.Sort > entity.Sort);
ts.Complete();
}
break;
}
default:
throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum,
nameof(EditTrackPushContentInput.Options)]);
}
return true;
}
/// <summary>
/// 轨迹推送配置内容排序
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("SortContent")]
public async Task<bool> SortContentAsync([FromBody] SortTrackPushContentInput input)
{
List<int> ids = input.SortInfo.Select(x => int.Parse(x.Key)).ToList();
var trackPushContentEntities = await _trackPushConfigRepository.GetContentListAsync(x => ids.Contains(x.Id));
trackPushContentEntities.ForEach(item =>
{
item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value;
});
await _trackPushConfigRepository.UpdateContentRangeAsync(trackPushContentEntities);
return true;
}
}

View File

@ -0,0 +1,175 @@
using Microsoft.Extensions.Localization;
using SJZY.Track.Application.Contract.Dtos.TrackStatus;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.TrackStatus;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackStatus;
/// <summary>
/// 轨迹状态
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹状态")]
[Route("/Track/Status")]
public class TrackStatusService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackStatusRepository _trackStatusRepository;
private readonly ITrackContentRepository _trackContentRepository;
public TrackStatusService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackStatusRepository trackStatusRepository,
ITrackContentRepository trackContentRepository
)
{
this._stringLocalizer = stringLocalizer;
this._trackStatusRepository = trackStatusRepository;
this._trackContentRepository=trackContentRepository;
}
/// <summary>
/// 轨迹状态编辑
/// </summary>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<UnifyResultDto> EditAsync(EditTrackStatusInput input)
{
return input.Options switch
{
OptionType.新增 => await AddAsync(input),
OptionType.修改 => await UpdateAsync(input),
OptionType.删除 => await DeleteAsync(input),
_ => throw new BusinessException(message: "当前操作动作不合法")
};
}
/// <summary>
/// 根据状态id获取轨迹状态
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<UnifyResultDto<GetTrackStatusDetailDto>> GetDetailAsync(int id)
{
var detailInfo = await _trackStatusRepository.GetDetailAsync(id);
if (detailInfo == null)
{
return new UnifyResultDto<GetTrackStatusDetailDto>(false, null, "未查询到轨迹状态");
}
var dto = ObjectMapper.Map<GetTrackStatusDetailVO, GetTrackStatusDetailDto>(detailInfo);
return new UnifyResultDto<GetTrackStatusDetailDto>("200", "", dto);
}
/// <summary>
/// 获取分页轨迹状态
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetList")]
public async Task<UnifyPageResultDto<GetTrackStatusListDto>> GetPageTrackStatus(GetPageTrackStatusInput input)
{
var vo = ObjectMapper.Map<GetPageTrackStatusInput, GetPageTrackStatusVO>(input);
var resultDto = await _trackStatusRepository.GetPageTrackStatus(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<GetTrackStatusListVO>, UnifyPageResultDto<GetTrackStatusListDto>>(
resultDto);
return pageResultDto;
}
#region 私有方法
private async Task<UnifyResultDto> AddAsync(EditTrackStatusInput input)
{
#region 业务校验
var trackStatusEntitys = await _trackStatusRepository.GetListAsync(a => a.SubSystemId == input.SubSystemId &&
(a.Code == input.Code ||
a.Status == input.TrackStatus || a.EnStatus == input.EntrackStatus));
if (trackStatusEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackStatusExist"]);
//throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在");
var trackStatusCode = trackStatusEntitys.FirstOrDefault(t => t.Code==input.Code);
if (trackStatusCode!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态代码已存在");
}
var trackStatusName = trackStatusEntitys.FirstOrDefault(t => t.Status==input.TrackStatus);
if (trackStatusName!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态已存在");
}
var trackStatusEnName = trackStatusEntitys.FirstOrDefault(t => t.EnStatus==input.EntrackStatus);
if (trackStatusEnName!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态英文已存在");
}
}
#endregion
var entity = ObjectMapper.Map<EditTrackStatusInput, TrackStatusEntity>(input);
var isTrue = await _trackStatusRepository.InsertAsync(entity);
return new UnifyResultDto("200", "新增成功", isTrue);
}
private async Task<UnifyResultDto> UpdateAsync(EditTrackStatusInput input)
{
#region 业务校验
var trackStatusEntitys = await _trackStatusRepository.GetListAsync(a => a.Id != input.Id &&
a.SubSystemId == input.SubSystemId && (a.Code == input.Code ||
a.Status == input.TrackStatus || a.EnStatus == input.EntrackStatus));
if (trackStatusEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TrackStatusExist"]);
//throw new BusinessException(message: "当前子系统下,轨迹状态代码或轨迹状态或轨迹状态英文存在");
var trackStatusCode = trackStatusEntitys.FirstOrDefault(t => t.Code==input.Code);
if (trackStatusCode!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态代码已存在");
}
var trackStatusName = trackStatusEntitys.FirstOrDefault(t => t.Status==input.TrackStatus);
if (trackStatusName!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态已存在");
}
var trackStatusEnName = trackStatusEntitys.FirstOrDefault(t => t.EnStatus==input.EntrackStatus);
if (trackStatusEnName!=null)
{
throw new BusinessException(message: "该子系统下轨迹状态英文已存在");
}
}
#endregion
var templateEntity = await _trackStatusRepository.GetFirstAsync(a => a.Id == input.Id);
ObjectMapper.Map(input, templateEntity);
var isTrue = await _trackStatusRepository.UpdateAsync(templateEntity);
return new UnifyResultDto("200", "修改成功", isTrue);
}
private async Task<UnifyResultDto> DeleteAsync(EditTrackStatusInput input)
{
#region 业务校验
var isExistStatus = await _trackContentRepository.GetFirstAsync(a => a.TrackStatusId==input.Id);
if (isExistStatus!=null)
{
//throw new BusinessException(message: _stringLocalizer["IsExistTrackStatus"]);
throw new BusinessException(message: "该状态关联轨迹内容,禁止删除");
}
#endregion
var isTrue = await _trackStatusRepository.SoftDeleteAsync(x => x.Id == input.Id);
return new UnifyResultDto("200", "删除成功", isTrue);
}
#endregion
}

View File

@ -0,0 +1,7 @@
namespace SJZY.Track.Application.Services.TrackTemplates
{
public interface ITrackTemplateService
{
}
}

View File

@ -0,0 +1,308 @@
using System.Linq.Expressions;
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.TrackTemplates;
using SJZY.Track.Application.Localization;
using SJZY.Track.Domain.Aggregates.TrackPullAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Aggregates.TrackTemplateAggregate;
using SJZY.Track.Domain.Dtos.TrackTemplate;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.TrackTemplates;
/// <summary>
/// 轨迹模版
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹模版")]
[Route("/Track/Template")]
public class TrackTemplateService : ApplicationService, ITransientDependency
{
private readonly IStringLocalizer<TrackLocalizationResource> _stringLocalizer;
private readonly ITrackTemplateRepository _trackTemplateRepository;
private readonly ITrackPullConfigRepository _trackPullConfigRepository;
private readonly ITrackPushConfigRepository _trackPushConfigRepository;
/// <inheritdoc/>
public TrackTemplateService(
IStringLocalizer<TrackLocalizationResource> stringLocalizer,
ITrackTemplateRepository trackTemplateRepository,
ITrackPullConfigRepository trackPullConfigRepository,
ITrackPushConfigRepository trackPushConfigRepository
)
{
_stringLocalizer = stringLocalizer;
_trackTemplateRepository = trackTemplateRepository;
_trackPullConfigRepository = trackPullConfigRepository;
_trackPushConfigRepository = trackPushConfigRepository;
}
/// <summary>
/// 轨迹模版编辑
/// </summary>
/// <returns></returns>
[HttpPost("Edit")]
public async Task<UnifyResultDto> EditAsync(EditTrackTemplateInput input)
{
return input.Options switch
{
OptionType.新增 => await AddAsync(input),
OptionType.修改 => await UpdateAsync(input),
OptionType.删除 => await DeleteAsync(input),
_ => throw new BusinessException(message: "当前操作动作不合法")
};
}
/// <summary>
/// 根据模版id获取轨迹模版
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetDetail")]
public async Task<UnifyResultDto<GetTrackTemplateDetailDto>> GetDetailAsync(int id)
{
var detailInfo = await _trackTemplateRepository.GetDetailAsync(id);
if (detailInfo == null)
{
return new UnifyResultDto<GetTrackTemplateDetailDto>(false, null, "未查询到轨迹模版");
}
var dto = ObjectMapper.Map<GetTrackTemplateDetailVO, GetTrackTemplateDetailDto>(detailInfo);
return new UnifyResultDto<GetTrackTemplateDetailDto>("200", "", dto);
}
/// <summary>
/// 获取分页轨迹模版
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetList")]
public async Task<UnifyPageResultDto<GetTrackTemplateListDto>> GetPageTrackTemplate(GetPageTrackTemplateInput input)
{
var vo = ObjectMapper.Map<GetPageTrackTemplateInput, GetPageTrackTemplateVO>(input);
var resultDto = await _trackTemplateRepository.GetPageTrackTemplate(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<GetTrackTemplateListVO>, UnifyPageResultDto<GetTrackTemplateListDto>>(
resultDto);
return pageResultDto;
}
#region 私有方法
private async Task<UnifyResultDto> AddAsync(EditTrackTemplateInput input)
{
#region 业务校验
//校验模版代码唯一性
//var templateEntity =
// await _trackTemplateRepository.GetFirstAsync(
// a => a.SubSystemId == input.SubSystemId && a.Code == input.Code);
var templateEntitys = await _trackTemplateRepository.GetListAsync(a => a.SubSystemId == input.SubSystemId && (a.Code == input.Code|| a.Name==input.Name));
if (templateEntitys.Any())
{
//throw new BusinessException(message: _stringLocalizer["TemplateExist"]);
//throw new BusinessException(message: "模板代码已存在于当前选择的子系统下");
var trackTemplateCode = templateEntitys.FirstOrDefault(t => t.Code==input.Code);
if (trackTemplateCode!=null)
{
throw new BusinessException(message: "该子系统下模板代码已存在");
}
var trackTemplateName = templateEntitys.FirstOrDefault(t => t.Name==input.Name);
if (trackTemplateName!=null)
{
throw new BusinessException(message: "该子系统下模板名称已存在");
}
}
#endregion 业务校验
var entity = ObjectMapper.Map<EditTrackTemplateInput, TrackTemplateEntity>(input);
var isTrue = await _trackTemplateRepository.InsertAsync(entity);
return new UnifyResultDto("200", "新增成功", isTrue);
}
private async Task<UnifyResultDto> UpdateAsync(EditTrackTemplateInput input)
{
#region 业务校验
var templateEntitys = await _trackTemplateRepository.GetListAsync(a =>
a.Id != input.Id && a.SubSystemId == input.SubSystemId && (a.Code == input.Code || a.Name==input.Name));
if (templateEntitys.Any())
{
//throw new BusinessException(message: "模板代码已存在于当前选择的子系统下");
var trackTemplateCode = templateEntitys.FirstOrDefault(t => t.Code==input.Code);
if (trackTemplateCode!=null)
{
throw new BusinessException(message: "该子系统下模板代码已存在");
}
var trackTemplateName = templateEntitys.FirstOrDefault(t => t.Name==input.Name);
if (trackTemplateName!=null)
{
throw new BusinessException(message: "该子系统下模板名称已存在");
}
}
#endregion 业务校验
var templateEntity = await _trackTemplateRepository.GetFirstAsync(a => a.Id == input.Id);
ObjectMapper.Map(input, templateEntity);
var isTrue = await _trackTemplateRepository.UpdateAsync(templateEntity);
return new UnifyResultDto("200", "修改成功", isTrue);
}
private async Task<UnifyResultDto> DeleteAsync(EditTrackTemplateInput input)
{
#region 业务校验
//查询看看在轨迹拉取里面有没有被占用
var isExisistTrackPullConfigs = await _trackPullConfigRepository.GetListAsync(a => a.TrackTemplateId == input.Id);
if (isExisistTrackPullConfigs.Any())
{
//throw new BusinessException(message: _stringLocalizer["IsExistTrackPullConfig"]);
throw new BusinessException(message: "该模板存在映射,禁止删除");
}
//轨迹推送里看看是否被占用
var isExisistTrackPushConfigs = await _trackPushConfigRepository.GetListAsync(a => a.TrackTemplateId.Contains(input.Id.ToString()));
if (isExisistTrackPushConfigs.Any())
{
throw new BusinessException(message: "该模板存在映射,禁止删除");
}
#endregion 业务校验
var isTrue = await _trackTemplateRepository.SoftDeleteAsync(x => x.Id == input.Id);
return new UnifyResultDto("200", "删除成功", isTrue);
}
#endregion 私有方法
/// <summary>
/// 轨迹模板内容列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetContentPage")]
public async Task<UnifyPageResultDto<GetTrackTemplateContentPageOutputVO>> GetContentPageAsync(
[FromBody] GetTrackTemplateContentPageInputVO input)
{
return await _trackTemplateRepository.GetContentPageAsync(input);
}
/// <summary>
/// 轨迹模板内容详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("GetContentDetail")]
public async Task<GetTrackTemplateContentDetailOutputVO> GetContentDetailAsync(int id)
{
return await _trackTemplateRepository.GetContentDetailAsync(id);
}
/// <summary>
/// 轨迹模板内容下拉框
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetContentDropDownList")]
public async Task<UnifyPageResultDto<DropdownListDataDto>> GetContentDropDownListAsync([FromBody] GetTrackTemplateContentDropDownListVO input)
{
return await _trackTemplateRepository.GetContentDropDownListAsync(input);
}
/// <summary>
/// 轨迹模板内容编辑
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("EditContent")]
public async Task<bool> EditContentAsync([FromBody] EditTrackTemplateContentInput input)
{
if (input.Options != OptionTypeNoNull.删除)
{
Expression<Func<TrackTemplateContentEntity, bool>> isContentAnyExp = x =>
x.TrackTemplateId == input.TrackTemplateId && x.TrackContentId == input.TrackContentId;
if (input.Options == OptionTypeNoNull.修改) isContentAnyExp = isContentAnyExp.And(x => x.Id != input.Id);
if (await _trackTemplateRepository.IsContentAnyAsync(isContentAnyExp))
throw new BusinessException(message: _stringLocalizer["IsTrackTemplateContentAny"]);
}
switch (input.Options)
{
case OptionTypeNoNull.新增:
{
int maxSort = await _trackTemplateRepository.ContentMaxAsync(x => x.Sort, x => x.TrackTemplateId == input.TrackTemplateId);
var entity = ObjectMapper.Map<EditTrackTemplateContentInput, TrackTemplateContentEntity>(input);
entity.Sort = maxSort + 1;
await _trackTemplateRepository.InsertContentAsync(entity);
break;
}
case OptionTypeNoNull.修改:
{
var entity = await _trackTemplateRepository.GetContentByIdAsync(input.Id!.Value) ??
throw new BusinessException(message: _stringLocalizer["NotFindData"]);
ObjectMapper.Map(input, entity);
await _trackTemplateRepository.UpdateContentAsync(entity);
break;
}
case OptionTypeNoNull.删除:
{
var entity = await _trackTemplateRepository.GetContentByIdAsync(input.Id!.Value) ??
throw new BusinessException(message: _stringLocalizer["NotFindData"]);
using (var ts = TransactionScopeHelper.Create())
{
await _trackTemplateRepository.SoftDeleteContentAsync(input.Id!.Value);
await _trackTemplateRepository.UpdateContentAsync(x => x.Sort == x.Sort - 1, x => x.TrackTemplateId == entity.TrackTemplateId && x.Sort > entity.Sort);
ts.Complete();
}
break;
}
default:
throw new BusinessException(message: _stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum,
nameof(EditTrackTemplateContentInput.Options)]);
}
return true;
}
/// <summary>
/// 轨迹模板内容排序
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("SortContent")]
public async Task<bool> SortContentAsync([FromBody] SortTrackTemplateContentInput input)
{
List<int> ids = input.SortInfo.Select(x => int.Parse(x.Key)).ToList();
var trackTemplateContentEntities = await _trackTemplateRepository.GetContentListAsync(x => ids.Contains(x.Id));
trackTemplateContentEntities.ForEach(item =>
{
item.Sort = input.SortInfo.Single(x => x.Key == item.Id.ToString()).Value;
});
await _trackTemplateRepository.UpdateContentRangeAsync(trackTemplateContentEntities);
return true;
}
}

View File

@ -0,0 +1,127 @@
using System.Text.Json;
using DotNetCore.CAP;
using Microsoft.Extensions.Configuration;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.Contract;
using SJZY.Track.Application.Localization;
using SJZY.UserCenter.Contracts;
using SJZY.UserCenter.SharedModel;
using SJZY.UserCenter.SharedModel.Pub;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AutoMapper;
using Volo.Abp.FluentValidation;
using Volo.Abp.Http.Client;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace SJZY.Track.Application
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpFluentValidationModule),
typeof(AbpLocalizationModule),
typeof(AbpVirtualFileSystemModule),
typeof(AbpHttpClientModule),
typeof(SjzyUserCenterHttpApiModule),
typeof(SJZYInterfaceRelayApplicationContractsModule),
typeof(SjzyTrackDomainModule),
typeof(SjzyTrackApplicationContractModule)
)]
public class SjzyTrackApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpAutoMapperOptions>(options => { options.AddMaps<SjzyTrackApplicationModule>(true); });
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(SjzyTrackApplicationModule).Assembly); //创建动态api
});
//添加虚拟文件系统
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<SjzyTrackApplicationModule>("SJZY.Track.Application");
});
//添加多语言
var languageConfig = configuration.GetSection("Language");
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TrackLocalizationResource>("zh")
.AddBaseTypes(typeof(SjzyBasicLocalization))
.AddRedisResource(languageConfig)
.AddVirtualJson("/Localization/Resources");
});
//授权拦截提示
context.Services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new ApiAsyncAuthorizationFilter());
});
//用户中心
context.Services.AddHttpClientProxies(typeof(SjzyUserCenterHttpApiModule).Assembly, "UserCenter", false);
context.Services.AddHttpClient("InterfaceForward").AddHttpMessageHandler<InterfaceForwardHeaderHandler>();
context.Services.AddHttpClientProxy<IInterfaceForwardService>(
remoteServiceConfigurationName: "InterfaceForward",
asDefaultService: false
);
//CAP
context.Services.AddCapTableNameService();
context.Services.AddCap(options =>
{
options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!);
options.UseRabbitMQ(configure =>
{
configure.HostName = configuration["RabbitMQ:HostName"]!;
configure.UserName = configuration["RabbitMQ:UserName"]!;
configure.Password = configuration["RabbitMQ:Password"]!;
configure.Port = configuration.GetValue<int>("RabbitMQ:Port");
});
options.FailedRetryInterval = 60;
options.FailedRetryCount = 10;
options.UseDashboard(dashboardOptions =>
{
dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached
? ""
: configuration["Swagger:JsonUrlPrefix"];
});
options.FailedThresholdCallback = faileCalback =>
{
try
{
LogHelper.Error($@"
|-CAP失败回调事件:
|-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")}
|-头部信息:{faileCalback?.Message?.Headers?.ToJson()}
|-消息内容:{((JsonElement)faileCalback?.Message?.Value).GetRawText()}");
}
catch (Exception ex)
{
LogHelper.Error("【严重】CAP失败回调事件发生未处理异常" + ex);
}
};
});
}
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientActions.Add((_, _, httpClient) =>
{
//如果设置Token,前端需要传入Token 否则引发异常
httpClient.SetTokenHeader();
httpClient.Timeout = TimeSpan.FromMinutes(3);
});
});
}
}
}

View File

@ -1,68 +0,0 @@
using FluentValidation;
using SJZY.Track.Application.Dtos.Demo;
namespace SJZY.Track.Application.Validations.Demo
{
public class SimpleValidateInputValidation : AbstractValidator<ValidateExecuteInput>, IValidationEnabled
{
public SimpleValidateInputValidation()
{
/*
非空校验
NotNull 和 NotEmpty 的区别?
NotNull:请求中没找到指定参数
NotEmpty:请求中没找到指定参数 或 参数值为初始值(0/"")
关于字符串的最佳实践:
参数定义成可空字符串 string?,校验规则只用isempty
*/
RuleFor(x => x.PassWord).NotNull().WithMessage("操作密码为必填参数!").NotEmpty().WithMessage("操作密码不能为空!");
//雪花id
RuleFor(x => x.SnowId).NotNull().WithMessage("雪花ID为必填参数!").NotEmpty().WithMessage("雪花ID不能为空!");
//枚举校验
RuleFor(x => x.Option).IsInEnum().WithMessage("操作类型不在可选范围!");
//字符串长度校验,长度不分中文、字符、数值
RuleFor(x => x.LoginName).Length(6, 10).WithMessage("登录账号必须在6-10位之间!");
RuleFor(x => x.LoginName).MaximumLength(10).WithMessage("登录账号不能超过10个字符!");
RuleFor(x => x.LoginName).MinimumLength(6).WithMessage("登录账号不能小于6个字符!");
//正则表达式
RuleFor(x => x.PassWord).Matches("^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\\%\\^\\&\\*\\(\\)])[0-9a-zA-Z!@#$\\%\\^\\&\\*\\(\\)]{6,10}")
.WithMessage("密码必须同时包含数字、英文字母、特殊字符,且长度必须在6-10位之间");
//自定义校验规则,注意这里的校验仅限于模型参数级的校验,更复杂的业务校验应在业务层完成
RuleFor(x => x.PassWordAgain).Must((data, context) =>
{
return data.PassWord == data.PassWordAgain;
}).WithMessage("两次输入密码不一致!");
//数字类型校验
RuleFor(x => x.MiniCount).LessThan(100).WithMessage("最小数量必须小于100");
RuleFor(x => x.MiniCount).LessThanOrEqualTo(100).WithMessage("最小数量必须小于或等于100");
RuleFor(x => x.MaxCount).GreaterThan(100).WithMessage("最大数量必须大于100");
RuleFor(x => x.MaxCount).GreaterThanOrEqualTo(100).WithMessage("最大数量必须大于或等于100");
//小数类型校验,10.56
RuleFor(x => x.TotalQuota).ScalePrecision(2, 4, true).WithMessage("最大额度金额【整数位+小数位】不能超过4位,且小数位不能超过2位");
//条件分支
When(x => x.Option == OptionType.修改 || x.Option == OptionType.删除, () =>
{
RuleFor(x => x.Id).NotNull().WithMessage("修改或删除时Id为必填参数!").GreaterThan(0).WithMessage("修改或删除时Id必须大于0!");
});
//单个实体校验
RuleFor(x => x.UserInfoInput).NotNull().WithMessage("用户信息为必填参数!").SetValidator(new UserInfoInputValidation());
//集合校验
RuleForEach(x => x.UserRoleInputList).SetValidator(new UserRoleInputValidation());
}
}
}

View File

@ -1,15 +0,0 @@
using FluentValidation;
using SJZY.Track.Application.Dtos.Demo;
namespace SJZY.Track.Application.Validations.Demo
{
public class UserInfoInputValidation : AbstractValidator<UserInfoInput>, IValidationEnabled
{
public UserInfoInputValidation()
{
RuleFor(x => x.QQ).NotNull().WithMessage("QQ号码不能为空");
}
}
}

View File

@ -1,13 +0,0 @@
using FluentValidation;
using SJZY.Track.Application.Dtos.Demo;
namespace SJZY.Track.Application.Validations.Demo
{
public class UserRoleInputValidation : AbstractValidator<UserRoleInput>, IValidationEnabled
{
public UserRoleInputValidation()
{
RuleFor(m => m.Id).GreaterThan(0).WithMessage("角色ID必须大于0!");
}
}
}

View File

@ -0,0 +1,26 @@
using FluentValidation;
using SJZY.Track.Application.Contract.Dtos.TrackContents;
namespace SJZY.Track.Application.Validations.TrackContents
{
public class EditTrackContentInputValidation : AbstractValidator<EditTrackContentInput>, IValidationEnabled
{
public EditTrackContentInputValidation()
{
//条件分支
When(x => x.Options == OptionType.修改 || x.Options == OptionType.删除,
() => { RuleFor(x => x.Id).GreaterThan(0).WithMessage("修改或删除时Id必须大于0!"); });
When(x => x.Options == OptionType.新增, () => { RuleFor(x => x.Id).Equal(0).WithMessage("新增时Id必须等于0!"); });
When(x => x.Options == OptionType.修改 || x.Options == OptionType.新增, () =>
{
RuleFor(x => x.SubSystemId).GreaterThan(0).WithMessage("子系统的id必须大于0!");
RuleFor(x => x.TrackStatusId).GreaterThan(0).WithMessage("所属状态的id必须大于0!");
RuleFor(x => x.Code).NotNull().WithMessage("轨迹内容代码必填!").NotEmpty().WithMessage("轨迹内容代码不能为空!");
RuleFor(x => x.Content).NotNull().WithMessage("轨迹内容必填!").NotEmpty().WithMessage("轨迹内容不能为空!");
RuleFor(x => x.EnContent).NotNull().WithMessage("轨迹内容英文必填!").NotEmpty().WithMessage("轨迹内容英文不能为空!");
});
}
}
}

View File

@ -0,0 +1,45 @@
using FluentValidation;
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Track.Application.Contract.Dtos.TrackContents;
using SJZY.Track.Application.Localization;
namespace SJZY.Track.Application.Validations.TrackContents;
public class EditTrackContentMapInputValidation : AbstractValidator<EditTrackContentMapInput>, IValidationEnabled
{
public EditTrackContentMapInputValidation(IStringLocalizer<TrackLocalizationResource> stringLocalizer)
{
RuleFor(x => x.Options).IsInEnum().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_IsInEnum, nameof(EditTrackContentMapInput.Options)]);
RuleFor(x => x.Id).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.Id), 0]);
RuleFor(x => x.MapSubSystemId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.MapSubSystemId), 0]);
RuleFor(x => x.MapTrackContentId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.MapTrackContentId), 0]);
RuleFor(x => x.SubSystemId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.SubSystemId), 0]);
RuleFor(x => x.TrackContentId).GreaterThan(0).WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_GreaterThan, nameof(EditTrackContentMapInput.TrackContentId), 0]);
When(x => x.Options != OptionTypeNoNull.新增, () =>
{
RuleFor(x => x.Id).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.Id)]);
});
When(x => x.Options != OptionTypeNoNull.删除, () =>
{
RuleFor(x => x.MapSubSystemId).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.MapSubSystemId)]);
RuleFor(x => x.MapTrackContentCode).NotEmpty().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotEmpty, nameof(EditTrackContentMapInput.MapTrackContentCode)]);
RuleFor(x => x.MapTrackContentId).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.MapTrackContentId)]);
RuleFor(x => x.SubSystemId).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.SubSystemId)]);
RuleFor(x => x.TrackContentCode).NotEmpty().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotEmpty, nameof(EditTrackContentMapInput.TrackContentCode)]);
RuleFor(x => x.TrackContentId).NotNull().WithMessage(stringLocalizer[SjzyBasicLocalization.Validation_NotNull, nameof(EditTrackContentMapInput.TrackContentId)]);
});
}
}

View File

@ -0,0 +1,24 @@
using FluentValidation;
using SJZY.Track.Application.Contract.Dtos.TrackFlags;
namespace SJZY.Track.Application.Validations.TrackFlags
{
public class EditTrackFlagInputValidation : AbstractValidator<EditTrackFlagInput>, IValidationEnabled
{
public EditTrackFlagInputValidation()
{
//条件分支
When(x => x.Options == OptionType.修改 || x.Options == OptionType.删除,
() => { RuleFor(x => x.Id).GreaterThan(0).WithMessage("修改或删除时Id必须大于0!"); });
When(x => x.Options == OptionType.新增, () => { RuleFor(x => x.Id).Equal(0).WithMessage("新增时Id必须等于0!"); });
When(x => x.Options == OptionType.修改 || x.Options == OptionType.新增, () =>
{
RuleFor(x => x.SubSystemId).GreaterThan(0).WithMessage("子系统的id必须大于0!");
RuleFor(x => x.Code).NotNull().WithMessage("轨迹标记代码必填!").NotEmpty().WithMessage("轨迹标记代码不能为空!");
RuleFor(x => x.Flag).NotNull().WithMessage("轨迹标记必填!").NotEmpty().WithMessage("轨迹标记不能为空!");
});
}
}
}

Some files were not shown because too many files have changed in this diff Show More