test 轨迹查询、新增、修改、软删除

This commit is contained in:
李鹏军 2024-03-04 18:48:43 +08:00
parent b6e0abc03f
commit 22dd02507f
12 changed files with 98 additions and 43 deletions

View File

@ -23,7 +23,7 @@ public class TrackDeleteEventHandler: ITransientDependency, ICapSubscribe
_capPublisher = capPublisher; _capPublisher = capPublisher;
} }
[CapSubscribe(GlobalConst.TrackUpsertSubscribe)] [CapSubscribe(GlobalConst.TrackDeleteSubscribe)]
public async Task ConsumerAsync(TrackDeleteEvent @event) public async Task ConsumerAsync(TrackDeleteEvent @event)
{ {
// 不同子系统需要做内容映射 // 不同子系统需要做内容映射

View File

@ -13,6 +13,10 @@
<PackageReference Include="Volo.Abp.FluentValidation" 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.UserCenter.HttpApi" Version="3.0.3-alpha8" />
<PackageReference Include="SJZY.Expand.CAP" Version="7.8.0" /> <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>
<ItemGroup> <ItemGroup>

View File

@ -34,6 +34,12 @@ public class OrderLinkService : ApplicationService
throw new BusinessException(message: $"订单:{input.OrderNo}不存在"); 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; if (input.LinkOrderNos.Count < 1 || input.LinkOrderType == 0) return true;
// 单号去重 // 单号去重

View File

@ -85,7 +85,7 @@ public class TrackService : ApplicationService
TrackCodes = codes, TrackCodes = codes,
SubSystemId = order.SubSystemId, SubSystemId = order.SubSystemId,
}; };
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
return true; return true;
} }

View File

@ -1,4 +1,7 @@
using SJZY.Expand.ABP.Core.Localization; using DotNetCore.CAP;
using Microsoft.Extensions.Configuration;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.InterfaceRelay.Application.Contracts; using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.Contract; using SJZY.Track.Application.Contract;
using SJZY.Track.Application.Localization; using SJZY.Track.Application.Localization;
@ -65,19 +68,41 @@ namespace SJZY.Track.Application
remoteServiceConfigurationName: "InterfaceForward", remoteServiceConfigurationName: "InterfaceForward",
asDefaultService: false 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 =>
{
LogHelper.Error($@"{faileCalback.MessageType} 失败了,消息名称: {faileCalback.Message}");
};
});
} }
public override void PreConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
var configuration = context.Services.GetConfiguration();
PreConfigure<AbpHttpClientBuilderOptions>(options => PreConfigure<AbpHttpClientBuilderOptions>(options =>
{ {
options.ProxyClientActions.Add(async (remoteName, serviceProvider, httpClient) => options.ProxyClientActions.Add((_, _, httpClient) =>
{ {
//如果设置Token,前端需要传入Token 否则引发异常 //如果设置Token,前端需要传入Token 否则引发异常
httpClient.SetTokenHeader(); httpClient.SetTokenHeader();
httpClient.Timeout = TimeSpan.FromMinutes(3); httpClient.Timeout = TimeSpan.FromMinutes(3);
await Task.CompletedTask;
}); });
}); });
} }

View File

@ -9,9 +9,7 @@ public interface IOrderRepository : IBasicRepository<OrderEntity>
/// </summary> /// </summary>
/// <param name="order"></param> /// <param name="order"></param>
/// <returns></returns> /// <returns></returns>
Task<bool> CreateOrderAsync(OrderEntity order); Task CreateOrderAsync(OrderEntity order);
//Task<List<TrackOrderDetailVO>> GetOrderDetails(GetOrderDetailsInputVO input);
/// <summary> /// <summary>
/// 获取分页的轨迹订单 /// 获取分页的轨迹订单

View File

@ -114,9 +114,8 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot
[SugarColumn(ColumnName = "LeavePort")] [SugarColumn(ColumnName = "LeavePort")]
public string? LeavePort { get; set; } public string? LeavePort { get; set; }
[Navigate(NavigateType.OneToMany, nameof(OrderFlightEntity.OrderId))] [SugarColumn(IsIgnore = true)]
public List<OrderFlightEntity> OrderFlights { get; set; } public List<OrderFlightEntity> OrderFlights { get; set; }
[SugarColumn(IsIgnore = true)]
[Navigate(NavigateType.OneToMany, nameof(OrderFlightEntity.OrderId))]
public List<OrderTemplateEntity> OrderTemplates { get; set; } public List<OrderTemplateEntity> OrderTemplates { get; set; }
} }

View File

@ -11,7 +11,7 @@ public interface ITrackDetailsRepository
Task<List<TrackDetailsIndex>> GetListAsync(int orderType, List<string> orderNos); Task<List<TrackDetailsIndex>> GetListAsync(int orderType, List<string> orderNos);
Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input); Task<(List<TrackDetailsIndex> list, long total)> GetListAsync(TrackDetailsQueryInput input);
Task<List<TrackDetailsIndex>> GetListAsync(int orderId); Task<List<TrackDetailsIndex>?> GetListAsync(int orderId);
/// <summary> /// <summary>
/// 删除轨迹 /// 删除轨迹

View File

@ -59,7 +59,7 @@ public class TrackDetailsIndex : IdBaseIndex
/// <summary> /// <summary>
/// 轨迹发生地 /// 轨迹发生地
/// </summary> /// </summary>
public string? TrackPlace { get; set; } public string TrackPlace { get; set; } = null!;
/// <summary> /// <summary>
/// 轨迹发生时间 /// 轨迹发生时间

View File

@ -9,12 +9,17 @@ namespace SJZY.Track.Repository.Repositories;
public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, ITransientDependency public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, ITransientDependency
{ {
public async Task<bool> CreateOrderAsync(OrderEntity order) public async Task CreateOrderAsync(OrderEntity order)
{ {
return await Context.InsertNav(order) using var tran = TransactionHelper.GetReadCommitted();
.Include(x => x.OrderFlights)
.Include(x => x.OrderTemplates) var orderId = await InsertReturnIdentityAsync(order);
.ExecuteCommandAsync(); order.OrderTemplates.ForEach(x => x.OrderId = orderId);
await Context.Insertable(order.OrderTemplates).ExecuteCommandAsync();
order.OrderFlights.ForEach(x => x.OrderId = orderId);
await Context.Insertable(order.OrderFlights).ExecuteCommandAsync();
tran.Complete();
} }
public async Task UpdateOrderAsync(OrderEntity order) public async Task UpdateOrderAsync(OrderEntity order)

View File

@ -1,4 +1,6 @@
using Nest; using Nest;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Expand.ElasticSearch.Services; using SJZY.Expand.ElasticSearch.Services;
using SJZY.Track.Domain; using SJZY.Track.Domain;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
@ -9,8 +11,6 @@ namespace SJZY.Track.Repository.Repositories;
internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetailsIndex>, ITrackDetailsRepository, internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetailsIndex>, ITrackDetailsRepository,
ITransientDependency ITransientDependency
{ {
public string IndexName => $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}";
public TrackDetailsRepository(ConnectionFactory connectionFactory) : base(connectionFactory) public TrackDetailsRepository(ConnectionFactory connectionFactory) : base(connectionFactory)
{ {
} }
@ -18,32 +18,46 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
public async Task<TrackDetailsIndex?> GetFirstOrDefaultAsync(int orderId, string trackCode) public async Task<TrackDetailsIndex?> GetFirstOrDefaultAsync(int orderId, string trackCode)
{ {
var r = await Context.SearchAsync<TrackDetailsIndex>(s => s var r = await Context.SearchAsync<TrackDetailsIndex>(s => s
.Index(IndexName) .Source()
.Query(q => .Query(q =>
q.Term(t => t.Field(f => f.OrderId).Value(orderId)) q.Term(f => f.OrderId, orderId)
&& q.Term(t => t.Field(f => f.TrackCode).Value(trackCode)) && q.Term(f => f.TrackCode.Suffix("keyword"), trackCode)
&& q.Term(t => t.Field(f => f.IsDeleted).Value(true)) && q.Term(f => f.IsDeleted, false)
) )
); );
if (r.IsValid) var res= r.Documents.FirstOrDefault();
if (r.Hits.FirstOrDefault() != default && res != default)
{ {
return r.Documents.FirstOrDefault(); res.Id = r.Hits.FirstOrDefault()!.Id;
} }
return default; return res;
} }
public async Task UpsertAsync(TrackDetailsIndex index) public async Task UpsertAsync(TrackDetailsIndex index)
{ {
var response = await Context.UpdateAsync<TrackDetailsIndex>(index.Id, u => u try
.Index(IndexName) {
if (index.Id.IsNullOrWhiteSpace())
{
// 按天写入es
await Context.IndexAsync(index, request => request
.Index($"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}")
);
}
else
{
await Context.UpdateAsync<TrackDetailsIndex>(index.Id, u => u
.Doc(index) .Doc(index)
.DocAsUpsert()
//.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见
); );
if (!response.IsValid) }
throw new Exception($"数据修改失败,原因:{response.DebugInformation}"); }
catch (Exception ex)
{
LogHelper.Error($"轨迹数据新增/修改失败,原因:{ex.Message}。\n{index.ToJson()}");
}
} }
public async Task<List<TrackDetailsIndex>> GetListAsync(int orderType, List<string> orderNos) public async Task<List<TrackDetailsIndex>> GetListAsync(int orderType, List<string> orderNos)
@ -61,17 +75,17 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
)) ))
.Query(q => .Query(q =>
q.Terms(t => t q.Terms(t => t
.Field(f => f.OrderNo) .Field(f => f.OrderNo.Suffix("keyword"))
.Terms(orderNos)) .Terms(orderNos))
&& q.Term(f => f.OrderType, orderType) && q.Term(f => f.OrderType, orderType)
&& q.Term(t => t.Field(f => f.IsDeleted).Value(true)) && q.Term(t => t.Field(f => f.IsDeleted).Value(false))
) )
); );
return data.Documents.ToList(); return data.Documents.ToList();
} }
public async Task<List<TrackDetailsIndex>> GetListAsync(int orderId) public async Task<List<TrackDetailsIndex>?> GetListAsync(int orderId)
{ {
var data = await Context.SearchAsync<TrackDetailsIndex>(x => x var data = await Context.SearchAsync<TrackDetailsIndex>(x => x
.Source(s => s.Includes(fd => fd .Source(s => s.Includes(fd => fd
@ -83,7 +97,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
.Field(f => f.TraceTimeZone) .Field(f => f.TraceTimeZone)
)).Query(q => )).Query(q =>
q.Terms(t => t.Field(f => f.OrderId).Terms(orderId)) q.Terms(t => t.Field(f => f.OrderId).Terms(orderId))
&& q.Term(t => t.Field(f => f.IsDeleted).Value(true)) && q.Term(t => t.Field(f => f.IsDeleted).Value(false))
) )
); );
@ -98,7 +112,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
q.Term(t => t.OrderId, orderId) q.Term(t => t.OrderId, orderId)
&& q.Terms(t => t.Field(f => f.TrackCode).Terms(trackCodes))) && q.Terms(t => t.Field(f => f.TrackCode).Terms(trackCodes)))
.Script(s => s .Script(s => s
.Source("ctx._source.IsDeleted = true")) .Source("ctx._source.isDeleted = true"))
); );
} }
@ -114,7 +128,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
q.Terms(t => t q.Terms(t => t
.Field(f => f.OrderNo) .Field(f => f.OrderNo)
.Terms(distinctOrderNumbers)) .Terms(distinctOrderNumbers))
&& q.Term(t => t.Field(f => f.IsDeleted).Value(true)) && q.Term(t => t.Field(f => f.IsDeleted).Value(false))
) )
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)) .Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending))
.From((input.PageIndex - 1) * input.PageSize) .From((input.PageIndex - 1) * input.PageSize)

View File

@ -39,6 +39,10 @@ public class SjzyTrackRepositoryModule : AbpModule
context.Services.AddElasticSearch(options => context.Services.AddElasticSearch(options =>
{ {
if (System.Diagnostics.Debugger.IsAttached)
{
options.ShowLogInfo = true;
}
options.NodeUrls = configuration.GetSection("ElasticSearch:NodeUrls").Get<List<string>>()!; options.NodeUrls = configuration.GetSection("ElasticSearch:NodeUrls").Get<List<string>>()!;
options.LoginName = configuration["ElasticSearch:LoginName"]!; options.LoginName = configuration["ElasticSearch:LoginName"]!;
options.Password = configuration["ElasticSearch:Password"]!; options.Password = configuration["ElasticSearch:Password"]!;