This commit is contained in:
xiaolipro 2025-08-15 17:19:27 +08:00
parent 9870fb0ae7
commit 297e91cc04
26 changed files with 293 additions and 233 deletions

View File

@ -1,3 +0,0 @@
<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/=dels/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SJZY/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -18,7 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution items", "solution
NuGet.Config = NuGet.Config NuGet.Config = NuGet.Config
.gitignore = .gitignore .gitignore = .gitignore
.editorconfig = .editorconfig .editorconfig = .editorconfig
global.json = global.json
EndProjectSection EndProjectSection
EndProject EndProject
Global Global

View File

@ -1,9 +1,17 @@
FROM harbor.sjzy.local/images/dotnet:7.0 FROM mcr.microsoft.com/dotnet/sdk:8.0.303 AS base
COPY publish/ /app/ ARG BUILD_CONFIGURATION=Release
COPY version.log /app/ WORKDIR /src
COPY --chown=appuser:appuser publish/ /app/ COPY . /src
COPY --chown=appuser:appuser version.log /app/ RUN dotnet restore "src/TrackCenter.Api/TrackCenter.Api.csproj"
ENV ASPNETCORE_HOSTINGSTARTUPASSEMBLIES SJZY.Expand.ABP.Core.HostingStartup;SkyAPM.Agent.AspNetCore WORKDIR "/src/src/TrackCenter.Api"
ENV SKYWALKING__SERVICENAME Package_Track_Dev RUN dotnet build "TrackCenter.Api.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM base AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "TrackCenter.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# 使用运行时镜像
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app WORKDIR /app
CMD ["/usr/bin/dotnet","SJZY.Track.Api.dll"] COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TrackCenter.Api.dll"]

View File

@ -1,15 +1,15 @@
{ {
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": { "profiles": {
"SJZY.Track.Api": { "http": {
"commandName": "Project", "commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SJZY.Expand.ABP.Core",
"SKYWALKING__SERVICENAME": "Track"
},
"dotnetRunMessages": true, "dotnetRunMessages": true,
"applicationUrl": "http://*:5056" "launchBrowser": true,
"launchUrl": "swagger/index.html",
"applicationUrl": "http://localhost:8889",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
} }
},
"$schema": "https://json.schemastore.org/launchsettings.json"
} }

View File

@ -24,8 +24,11 @@
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="10.0.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="kafkalib\**\*" CopyToPublishDirectory="Always" CopyToOutputDirectory="Always" /> <Content Include="..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<RetainVMGarbageCollection>true</RetainVMGarbageCollection> <RetainVMGarbageCollection>true</RetainVMGarbageCollection>

View File

@ -13,6 +13,7 @@ using TrackCenter.Repository;
namespace TrackCenter.Api; namespace TrackCenter.Api;
[DependsOn(typeof(FakeAutofacModule))] [DependsOn(typeof(FakeAutofacModule))]
[DependsOn(typeof(FakeAspNetCoreModule))]
[DependsOn(typeof(TrackCenterApplicationModule))] [DependsOn(typeof(TrackCenterApplicationModule))]
[DependsOn(typeof(TrackCenterRepositoryModule))] [DependsOn(typeof(TrackCenterRepositoryModule))]
public class TrackCenterApiModule : FakeModule public class TrackCenterApiModule : FakeModule
@ -54,7 +55,13 @@ public class TrackCenterApiModule : FakeModule
public override void ConfigureApplication(ApplicationConfigureContext context) public override void ConfigureApplication(ApplicationConfigureContext context)
{ {
var app = context.GetWebApplication(); var app = context.GetWebApplication();
var configuration = context.GetConfiguration(); app.Use(async (httpContext, next) =>
{
httpContext.Request.EnableBuffering();
await next.Invoke();
});
app.UseFakeExceptionHandling();
app.MapControllers(); app.MapControllers();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@ -20,11 +20,11 @@ public class CapFilter : SubscribeFilter
if (!string.IsNullOrEmpty(argumentJsonStr)) if (!string.IsNullOrEmpty(argumentJsonStr))
{ {
context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); context.DeliverMessage.Headers.TryGetValue("track-arguments-hash", out var hash);
if (hash.IsNullOrEmpty()) // 计算参数hash if (hash.IsNullOrEmpty()) // 计算参数hash
{ {
hash = StringHelper.GetHash(argumentJsonStr); hash = StringHelper.GetHash(argumentJsonStr);
context.DeliverMessage.Headers["sjzy-arguments-hash"] = hash; context.DeliverMessage.Headers["track-arguments-hash"] = hash;
} }
if (await RedisHelper.Client.ExistsAsync($"CapExecuteFilter:{hash}{DateTime.Now:G}")) if (await RedisHelper.Client.ExistsAsync($"CapExecuteFilter:{hash}{DateTime.Now:G}"))
@ -36,7 +36,7 @@ public class CapFilter : SubscribeFilter
public override async Task OnSubscribeExecutedAsync(ExecutedContext context) public override async Task OnSubscribeExecutedAsync(ExecutedContext context)
{ {
context.DeliverMessage.Headers.TryGetValue("sjzy-arguments-hash", out var hash); context.DeliverMessage.Headers.TryGetValue("track-arguments-hash", out var hash);
if (!hash.IsNullOrEmpty()) if (!hash.IsNullOrEmpty())
{ {
await RedisHelper.Client.SetAsync($"CapExecuteFilter:{hash}{DateTime.Now:G}", 1, TimeSpan.FromMinutes(3)); await RedisHelper.Client.SetAsync($"CapExecuteFilter:{hash}{DateTime.Now:G}", 1, TimeSpan.FromMinutes(3));

View File

@ -8,7 +8,6 @@ public class LinkOrderInput
/// 应用 /// 应用
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public string AppKey { get; set; } public string AppKey { get; set; }
/// <summary> /// <summary>
@ -33,7 +32,6 @@ public class LinkOrderInput
/// 关联应用 /// 关联应用
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public string LinkAppKey { get; set; } public string LinkAppKey { get; set; }
/// <summary> /// <summary>

View File

@ -11,14 +11,12 @@ public class OrderNoInfo
/// 应用 /// 应用
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public string AppKey { get; set; } public string AppKey { get; set; }
/// <summary> /// <summary>
/// 订单类型,必填 /// 订单类型,必填
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public TrackOrderType OrderType { get; set; } public TrackOrderType OrderType { get; set; }
/// <summary> /// <summary>
@ -35,14 +33,12 @@ public class OrderNosInfo
/// 应用 /// 应用
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public string AppKey { get; set; } public string AppKey { get; set; }
/// <summary> /// <summary>
/// 订单类型 /// 订单类型
/// </summary> /// </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public TrackOrderType OrderType { get; set; } public TrackOrderType OrderType { get; set; }
/// <summary> /// <summary>

View File

@ -6,12 +6,10 @@ public class QueryPushRecordInput
{ {
/// <summary> 应用 </summary> /// <summary> 应用 </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public string AppKey { get; set; } public string AppKey { get; set; }
/// <summary> 订单类型 </summary> /// <summary> 订单类型 </summary>
[Required] [Required]
[Range(1, int.MaxValue)]
public TrackOrderType OrderType { get; set; } public TrackOrderType OrderType { get; set; }
/// <summary> 订单号集合 </summary> /// <summary> 订单号集合 </summary>

View File

@ -0,0 +1,91 @@
using FeishuNetSdk;
using FeishuNetSdk.Im;
using FeishuNetSdk.Im.Dtos;
using TrackCenter.Application.Helpers;
namespace TrackCenter.Application.Hangfire;
// 标题:预警通知
// 内容:尊敬的用户,截止到2024-12-13 10:00:01(UTC +8:00),轨迹中心监测到与您相关的预警风险信息共计299 条,请及时处理,详情如下:
// 运输时效预警共计100条,其中过去4小时内新增的预警10条,查看详情
// 回传时效预警共计99条,其中过去4小时内新增的预警10条,查看详情
// 轨迹完整预警共计100条,其中过去4小时内新增的预警10条,查看详情
public static class WarningNotifyBuilder
{
private const string Title = "预警通知";
// 构建飞书卡片发消息请求体
public static PostImV1MessagesBodyDto BuildFeiShuCard(WarningNotifyParam param, string fsUserId, string baseUrl)
{
var totalCount = param.TransportCount + param.ReturnCount + param.CompleteCount;
var body = new List<object>
{
new MarkdownElement(Content: $"尊敬的用户,截止到{DateTime.Now:yyyy-MM-dd HH:mm:ss}({BuildLocalTimezoneStr()}),轨迹中心监测到与您相关的预警风险信息共计{totalCount} 条,请及时处理,详情如下:", TextAlign: "left", TextSize: "normal_v2")
};
// 按需构建预警消息体
if (param.TransportCount > 0)
{
var url1 = WarningUrlBuilder.BuildUrl(baseUrl, WarningRuleType.运输时效预警, param.UserId);
body.Add(new MarkdownElement(Content: $"运输时效预警共计{param.TransportCount}条,其中过去{param.Hours}小时内新增的预警{param.TransportLastNHoursCount}条 [查看详情]({url1})", TextAlign: "left", TextSize: "normal_v2"));
}
if (param.ReturnCount > 0)
{
var url2 = WarningUrlBuilder.BuildUrl(baseUrl, WarningRuleType.回传时效预警, param.UserId);
body.Add(new MarkdownElement(Content: $"轨迹回传时效预警共计{param.ReturnCount}条,其中过去{param.Hours}小时内新增的预警{param.ReturnLastNHoursCount}条 [查看详情]({url2})", TextAlign: "left", TextSize: "normal_v2"));
}
if (param.CompleteCount > 0)
{
var url3 = WarningUrlBuilder.BuildUrl(baseUrl, WarningRuleType.完整预警, param.UserId);
body.Add(new MarkdownElement(Content: $"轨迹完整预警共计{param.CompleteCount}条,其中过去{param.Hours}小时内新增的预警{param.CompleteLastNHoursCount}条 [查看详情]({url3})", TextAlign: "left", TextSize: "normal_v2"));
}
var dto = new PostImV1MessagesBodyDto
{
MsgType = "interactive",
ReceiveId = fsUserId
};
dto.SetContent(new ElementsCardV2Dto
{
// 配置卡片全局行为
Config = new ElementsCardV2Dto.ConfigSuffix(),
Header = new ElementsCardV2Dto.HeaderSuffix()
{
Title = new HeaderTitleElement(Title),
Template = "red"
},
Body = new ElementsCardV2Dto.BodySuffix(body.ToArray()),
});
return dto;
}
// 构建本地时区字符串标识 e.g UTC +8:00
private static string BuildLocalTimezoneStr()
{
var offset = TimeZoneInfo.Local.BaseUtcOffset;
var flag = offset.Hours > 0 ? "+" : "";
var offsetStr = offset.ToString().RemovePostFix(":00");
return $"UTC {flag}{offsetStr}";
}
public static class WarningUrlBuilder
{
public const string TransportPath = "/trajectoryCenter/trajectoryWarningOrder/timeWaring";
public const string ReturnPath = "/trajectoryCenter/trajectoryWarningOrder/ReturnWarning";
public const string CompletePath = "/trajectoryCenter/trajectoryWarningOrder/CompleteWarning";
public static string BuildUrl(string baseUrl, WarningRuleType warningRuleType, int userId)
{
return warningRuleType switch
{
WarningRuleType.运输时效预警 => $"{baseUrl}{TransportPath}?userid={userId}",
WarningRuleType.回传时效预警 => $"{baseUrl}{ReturnPath}?userid={userId}",
WarningRuleType.完整预警 => $"{baseUrl}{CompletePath}?userid={userId}",
_ => throw new ArgumentOutOfRangeException()
};
}
}
}

View File

@ -1,76 +0,0 @@
using Hangfire;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TrackCenter.Application.Helpers;
using TrackCenter.Application.Options;
namespace TrackCenter.Application.Hangfire;
/// <summary>
/// 预警任务组件初始化
/// tips:支持定时任务执行周期配置 动态更新并应用 √
/// </summary>
public class WarningTaskComponentBackgroundService : BackgroundService
{
private readonly IOptionsMonitor<TrackWarningTaskOptions> _optionsMonitor;
private TrackWarningTaskOptions? _oldOptions;
private readonly ILogger<WarningTaskComponentBackgroundService> _logger;
public WarningTaskComponentBackgroundService(IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor, ILogger<WarningTaskComponentBackgroundService> logger)
{
_optionsMonitor = optionsMonitor;
_logger = logger;
// 防抖配置变更包装
var onChanged = DebounceHelper.WrapMethod(TimeSpan.FromSeconds(1), () => { ReloadConfig(optionsMonitor); });
optionsMonitor.OnChange(_ => onChanged.Debounce());
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
// 立即初始化一次
ReloadConfig(_optionsMonitor);
return Task.CompletedTask;
}
private void ReloadConfig(IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor)
{
var newVal = optionsMonitor.CurrentValue;
_logger.LogInformation("扫描任务配置,预警通知扫描周期{a}h,回传重试推送任务扫描周期{b}min,运输预警明细扫描周期{c}min",
newVal.ScanWarningNotifyTaskHourInterval,
newVal.ScanReturnWarningRetryPushTaskMinuteInterval,
newVal.ScanTransportWarningDetailsGenerateTaskMinuteInterval);
if ((_oldOptions?.ScanWarningNotifyTaskHourInterval ?? 0) != newVal.ScanWarningNotifyTaskHourInterval)
{
var q = GlobalConst.TaskQueueLevelDict[_optionsMonitor.CurrentValue.ScanWarningNotifyTaskLevel];
// 预警通知任务扫描
RecurringJob.AddOrUpdate<IWarningTaskScanner>("Scan_WarningNotifyTask",
q,
x => x.ScanNotifyTaskAndSchedulingAsync(),
$"0 */{newVal.ScanWarningNotifyTaskHourInterval} * * *");
}
if ((_oldOptions?.ScanReturnWarningRetryPushTaskMinuteInterval ?? 0) != newVal.ScanReturnWarningRetryPushTaskMinuteInterval)
{
var q = GlobalConst.TaskQueueLevelDict[_optionsMonitor.CurrentValue.ScanReturnWarningRetryPushTaskLevel];
// 回传预警通知重试推送任务扫描
RecurringJob.AddOrUpdate<IWarningTaskScanner>("Scan_ReturnWarningRetryPushTask",
q,
x => x.ScanReturnRetryPushTaskAndSchedulingAsync(),
$"*/{newVal.ScanReturnWarningRetryPushTaskMinuteInterval} * * * *");
}
if ((_oldOptions?.ScanTransportWarningDetailsGenerateTaskMinuteInterval ?? 0) != newVal.ScanTransportWarningDetailsGenerateTaskMinuteInterval)
{
var q = GlobalConst.TaskQueueLevelDict[_optionsMonitor.CurrentValue.ScanTransportWarningDetailsGenerateTaskLevel];
// 运输预警明细生成任务扫描
RecurringJob.AddOrUpdate<IWarningTaskScanner>("Scan_TransportWarningDetailsGenerateTask",
q,
x => x.ScanTransportDetailsGenerateTaskAndSchedulingAsync(),
$"*/{newVal.ScanTransportWarningDetailsGenerateTaskMinuteInterval} * * * *");
}
_oldOptions = newVal;
}
}

View File

@ -29,7 +29,9 @@ public class WarningTaskScanner : IWarningTaskScanner, ITransientDependency
private readonly IWarningTaskService _warningTaskService; private readonly IWarningTaskService _warningTaskService;
private readonly IOptionsMonitor<TrackWarningTaskOptions> _optionsMonitor; private readonly IOptionsMonitor<TrackWarningTaskOptions> _optionsMonitor;
public WarningTaskScanner(IWarningTaskRepository warningTaskRepository, ITransportWarningHandler transportWarningHandler, WarningNotifyAggregator warningNotifyAggregator, IWarningTaskService warningTaskService, IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor) public WarningTaskScanner(IWarningTaskRepository warningTaskRepository,
ITransportWarningHandler transportWarningHandler, WarningNotifyAggregator warningNotifyAggregator,
IWarningTaskService warningTaskService, IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor)
{ {
_warningTaskRepository = warningTaskRepository; _warningTaskRepository = warningTaskRepository;
_transportWarningHandler = transportWarningHandler; _transportWarningHandler = transportWarningHandler;
@ -67,7 +69,8 @@ public class WarningTaskScanner : IWarningTaskScanner, ITransientDependency
if (tasks.Count > 0) if (tasks.Count > 0)
{ {
var taskIds = tasks.Select(x => x.Id).ToList(); var taskIds = tasks.Select(x => x.Id).ToList();
await _warningTaskRepository.CloseReturnWarningRetryPushTaskAsync(x => !x.IsClosed && taskIds.Contains(x.Id)); await _warningTaskRepository.CloseReturnWarningRetryPushTaskAsync(x =>
!x.IsClosed && taskIds.Contains(x.Id));
} }
} }
@ -83,6 +86,7 @@ public class WarningTaskScanner : IWarningTaskScanner, ITransientDependency
// 3.关闭预警生成任务 // 3.关闭预警生成任务
var taskIds = tasks.Select(x => x.Id).ToList(); var taskIds = tasks.Select(x => x.Id).ToList();
await _warningTaskRepository.CloseTransportWarningDetailsGenerateTaskAsync(x => !x.IsClosed && taskIds.Contains(x.Id)); await _warningTaskRepository.CloseTransportWarningDetailsGenerateTaskAsync(x =>
!x.IsClosed && taskIds.Contains(x.Id));
} }
} }

View File

@ -20,41 +20,33 @@ public interface IWarningTaskService
Task CallTrackRetryPushAsync(ReturnWarningRetryPushTaskEntity entity, CancellationToken ct); Task CallTrackRetryPushAsync(ReturnWarningRetryPushTaskEntity entity, CancellationToken ct);
} }
public class WarningTaskService : IWarningTaskService, ITransientDependency public class WarningTaskService(
{
private readonly IOptionsMonitor<InterfaceRelayParamsConfigOptions> _interfaceRelayOptions;
private readonly IOptionsMonitor<TrackWarningTaskOptions> _warningTaskOptions;
private readonly IFeishuTenantApi _feishuTenantApi;
private readonly IWarningDetailsEsRepository _warningDetailsEsRepository;
private readonly IWarningTaskRepository _warningTaskRepository;
public WarningTaskService(
IOptionsMonitor<InterfaceRelayParamsConfigOptions> interfaceRelayOptions, IOptionsMonitor<InterfaceRelayParamsConfigOptions> interfaceRelayOptions,
IOptionsMonitor<TrackWarningTaskOptions> warningTaskOptions, IOptionsMonitor<TrackWarningTaskOptions> warningTaskOptions,
IOptionsMonitor<TrackAppOptions> trackAppOptions,
IFeishuTenantApi feishuTenantApi, IFeishuTenantApi feishuTenantApi,
IWarningDetailsEsRepository warningDetailsEsRepository, IWarningDetailsEsRepository warningDetailsEsRepository,
IWarningTaskRepository warningTaskRepository) IWarningTaskRepository warningTaskRepository,
{ InterfaceForwardService interfaceForwardService)
_interfaceRelayOptions = interfaceRelayOptions; : IWarningTaskService, ITransientDependency
_warningTaskOptions = warningTaskOptions; {
_feishuTenantApi = feishuTenantApi;
_warningDetailsEsRepository = warningDetailsEsRepository;
_warningTaskRepository = warningTaskRepository;
}
#region 用户中心调用,通知(一次) #region 用户中心调用,通知(一次)
[AutomaticRetry(Attempts = 1)] [AutomaticRetry(Attempts = 1)]
public async Task CallNotifyAsync(WarningNotifyParam param, CancellationToken ct) public async Task CallNotifyAsync(WarningNotifyParam param, CancellationToken ct)
{ {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
var options = _warningTaskOptions.CurrentValue; var options = warningTaskOptions.CurrentValue;
var baseUrl = trackAppOptions.CurrentValue.WarningNotifyUrl;
// 发送站内信 // todo:发送FeiShu卡片信息
// https://centerapi.test.shijizhongyun.com/userApi/index.html?urls.primaryName=%E6%B6%88%E6%81%AF%E8%AE%A2%E9%98%85%E5%AE%9E%E4%BE%8B var fsUserId = "";
// MsgSubscribeInstance/SendMessageByTemplate if (string.IsNullOrWhiteSpace(fsUserId))
throw new BusinessException(message: "查询用户中心失败:SendMessageByTemplateAsync Msg:未找到用户对应的飞书用户Id");
// 发送FeiShu卡片信息 var dto = WarningNotifyBuilder.BuildFeiShuCard(param, fsUserId, baseUrl);
var res = await feishuTenantApi.PostImV1MessagesAsync("user_id", dto);
if (res.Code != 0)
throw new BusinessException(message: $"飞书调用失败:SendMessageByTemplateAsync Msg:{res.Msg}");
} }
#endregion #endregion
@ -87,27 +79,27 @@ public class WarningTaskService : IWarningTaskService, ITransientDependency
using (Track2InterfaceRelayAppContext.Use(new Track2InterfaceRelayAppContext(task.AppCode))) using (Track2InterfaceRelayAppContext.Use(new Track2InterfaceRelayAppContext(task.AppCode)))
{ {
var upStreamCode = isAdd var upStreamCode = isAdd
? _interfaceRelayOptions.CurrentValue.PushTrackInterfaceCode ? interfaceRelayOptions.CurrentValue.PushTrackInterfaceCode
: _interfaceRelayOptions.CurrentValue.TrackUpdateInterfaceCode; : interfaceRelayOptions.CurrentValue.TrackUpdateInterfaceCode;
// var r = await _interfaceForwardServiceV2.Service.BatchForwardThenPushToQueueAsync( var r = await interfaceForwardService.BatchForwardThenPushToQueueAsync(
// upStreamCode: upStreamCode, upStreamCode: upStreamCode,
// serviceProviderCode: task.ServiceProviderCode, serviceProviderCode: task.ServiceProviderCode,
// data: items, data: items,
// resSubscribeName: GlobalConst.TrackPushCompletedSubscribe, resSubscribeName: GlobalConst.TrackPushCompletedSubscribe,
// attach: Base64Helper.SerializeObject(task.OptionType)); attach: Base64Helper.SerializeObject(task.OptionType));
// if (r.Code != GlobalConst.SuccessCode) if (r.Code != GlobalConst.SuccessCode)
// { {
// var msg = $"接口通调用失败:BatchForwardThenPushToQueueAsync" + var msg = $"接口通调用失败:BatchForwardThenPushToQueueAsync" +
// $"RequestId: {r.RequestId};AppCode:{task.AppCode};" + $"RequestId: {r.RequestId};AppCode:{task.AppCode};" +
// $" serviceProviderCode:{task.ServiceProviderCode} Msg: {r.Msg}"; $" serviceProviderCode:{task.ServiceProviderCode} Msg: {r.Msg}";
//
// // 处理调用接口通失败,直接处于完结状态 // 处理调用接口通失败,直接处于完结状态
// await HandlerCallBusinessException(task, msg); await HandlerCallBusinessException(task, msg);
// retryCountChanged = true; retryCountChanged = true;
// throw new BusinessException(message: msg); throw new BusinessException(message: msg);
// } }
} }
} }
catch (Exception e) catch (Exception e)
@ -121,7 +113,7 @@ public class WarningTaskService : IWarningTaskService, ITransientDependency
if (!retryCountChanged) if (!retryCountChanged)
{ {
var warningDetailsIds = task.WarningDetailIds.Split(',').ToHashSet(); var warningDetailsIds = task.WarningDetailIds.Split(',').ToHashSet();
await _warningDetailsEsRepository.ReturnWarningDetailsRetryIncrementAsync(warningDetailsIds); await warningDetailsEsRepository.ReturnWarningDetailsRetryIncrementAsync(warningDetailsIds);
} }
} }
} }
@ -130,7 +122,7 @@ public class WarningTaskService : IWarningTaskService, ITransientDependency
{ {
var detailIds = task.WarningDetailIds.Split(',').ToHashSet(); var detailIds = task.WarningDetailIds.Split(',').ToHashSet();
// 1.查询处理(重试中/人工介入)的预警明细 // 1.查询处理(重试中/人工介入)的预警明细
var warningDetails = await _warningDetailsEsRepository.GetReturnWarningDetailsAsync(new GetReturnWarningDetailsVO var warningDetails = await warningDetailsEsRepository.GetReturnWarningDetailsAsync(new GetReturnWarningDetailsVO
{ {
DetailsIds = detailIds DetailsIds = detailIds
}); });
@ -157,8 +149,8 @@ public class WarningTaskService : IWarningTaskService, ITransientDependency
} }
// 更新预警明细,添加回传报文记录 // 更新预警明细,添加回传报文记录
await _warningDetailsEsRepository.BulkUpdateReturnWarningDetailsAsync(warningDetails); await warningDetailsEsRepository.BulkUpdateReturnWarningDetailsAsync(warningDetails);
await _warningDetailsEsRepository.InsertReturnMessageRecordAsync(new ReturnMessageRecordIndex await warningDetailsEsRepository.InsertReturnMessageRecordAsync(new ReturnMessageRecordIndex
{ {
WarningDetailsIds = task.WarningDetailIds, WarningDetailsIds = task.WarningDetailIds,
IsSuccess = false, IsSuccess = false,
@ -168,7 +160,7 @@ public class WarningTaskService : IWarningTaskService, ITransientDependency
// 添加通知任务 // 添加通知任务
if (addNotifyTasks.Count > 0) if (addNotifyTasks.Count > 0)
await _warningTaskRepository.BulkInsertWarningNotifyTaskAsync(addNotifyTasks); await warningTaskRepository.BulkInsertWarningNotifyTaskAsync(addNotifyTasks);
} }
private static WarningNotifyTaskEntity BuildWarningNotifyTask(ReturnWarningDetailsIndex detail) private static WarningNotifyTaskEntity BuildWarningNotifyTask(ReturnWarningDetailsIndex detail)

View File

@ -15,10 +15,14 @@ namespace TrackCenter.Application.Kafka;
/// </summary> /// </summary>
public sealed class WarningCalcBackgroundService : BackgroundService public sealed class WarningCalcBackgroundService : BackgroundService
{ {
private const int MinWarningCalcInterval = 10 * 1000;
private const int MaxWarningCalcBatchSize = 2000;
private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IConsumer<WarningSignalKey, WarningSignal> _consumer; private readonly IConsumer<WarningSignalKey, WarningSignal> _consumer;
private readonly WarningSignalPublisher _warningSignalPublisher; private readonly WarningSignalPublisher _warningSignalPublisher;
private TrackWarningTaskOptions _options; private TrackWarningTaskOptions _options;
private int _interval;
private int _batchSize;
public WarningCalcBackgroundService( public WarningCalcBackgroundService(
IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor, IOptionsMonitor<TrackWarningTaskOptions> optionsMonitor,
@ -31,7 +35,14 @@ public sealed class WarningCalcBackgroundService : BackgroundService
_consumer = consumer; _consumer = consumer;
_warningSignalPublisher = warningSignalPublisher; _warningSignalPublisher = warningSignalPublisher;
_options = optionsMonitor.CurrentValue; _options = optionsMonitor.CurrentValue;
optionsMonitor.OnChange(x => _options = x); _interval = Math.Max(MinWarningCalcInterval, _options.WarningCalcInterval);
_batchSize = Math.Min(MaxWarningCalcBatchSize, _options.WarningCalcBatchSize);
optionsMonitor.OnChange(newVal =>
{
_options = newVal;
_interval = Math.Max(MinWarningCalcInterval, _options.WarningCalcInterval);
_batchSize = Math.Min(MaxWarningCalcBatchSize, _options.WarningCalcBatchSize);
});
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
@ -39,7 +50,7 @@ public sealed class WarningCalcBackgroundService : BackgroundService
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
await DoExecuteAsync(stoppingToken); await DoExecuteAsync(stoppingToken);
await Task.Delay(_options.WarningCalcInterval, stoppingToken); await Task.Delay(_interval, stoppingToken);
} }
} }
@ -75,7 +86,7 @@ public sealed class WarningCalcBackgroundService : BackgroundService
private async ValueTask FetchAndHandlerAsync(CancellationToken ct) private async ValueTask FetchAndHandlerAsync(CancellationToken ct)
{ {
// 500ms或者提取到1000条消息任意以条件到达既可返回 // 500ms或者提取到1000条消息任意以条件到达既可返回
var list = _consumer.ConsumeBatch(_options.WarningCalcBatchSize, TimeSpan.FromMilliseconds(500)).ToList(); var list = _consumer.ConsumeBatch(_batchSize, TimeSpan.FromMilliseconds(500)).ToList();
// 没有提取到任何消息跳过 // 没有提取到任何消息跳过
if (list.Count == 0) return; if (list.Count == 0) return;
@ -96,6 +107,48 @@ public sealed class WarningCalcBackgroundService : BackgroundService
// 提交内存中所有的偏移到服务器,适用于EnableAutoCommit为false的手动提交场景 // 提交内存中所有的偏移到服务器,适用于EnableAutoCommit为false的手动提交场景
_consumer.Commit(); _consumer.Commit();
// 动态调整消费速率
AdjustSettings(list.Count);
}
private void AdjustSettings(int actualFetchSize)
{
// MaxBatchSize 2000 MinBatchSize _options
// MinInterval 10s MaxInterval _options
// 实际拉取为批次大小,设置为最高速率
if (actualFetchSize >= _batchSize)
{
_interval = MinWarningCalcInterval;
_batchSize = MaxWarningCalcBatchSize;
return;
}
// 低负载场景:拉取量低于当前批次70%时
if (actualFetchSize < _batchSize * 0.7)
{
// 逐步缩小批次(每次减少15%)
_batchSize = Math.Max(_options.WarningCalcBatchSize, (int) (_batchSize * 0.85));
// 适度增加间隔(当前间隔+20%)
_interval = Math.Min(_options.WarningCalcInterval, (int) (_interval * 1.2));
return;
}
// 中等负载场景:拉取量处于70%-90%区间时
if (actualFetchSize < _batchSize * 0.9)
{
// 温和调整策略
_batchSize = Math.Min(MaxWarningCalcBatchSize, (int) (_batchSize * 1.05)); // 缓慢扩容
_interval = Math.Max(MinWarningCalcInterval, (int) (_interval * 0.95)); // 适度缩短间隔
return;
}
// 高负载临界:拉取量接近当前批次大小时
// 直接扩容5%并缩短间隔
_batchSize = Math.Min(MaxWarningCalcBatchSize, (int) (_batchSize * 1.05));
_interval = Math.Max(MinWarningCalcInterval, (int) (_interval * 0.9));
} }
private async ValueTask MessageHandler(IEnumerable<Message<WarningSignalKey, WarningSignal>> messages, CancellationToken ct) private async ValueTask MessageHandler(IEnumerable<Message<WarningSignalKey, WarningSignal>> messages, CancellationToken ct)
@ -171,8 +224,10 @@ public sealed class WarningCalcBackgroundService : BackgroundService
}).ToArray(); }).ToArray();
await Task.WhenAll(tasks); await Task.WhenAll(tasks);
_activity?.SetTag("EndPublicRetryMessage", $"[预警计算] 已重新投递[{needRetryMetadata.Count}]条消息"); var errorReasons = needRetryMetadata.Select(x => x.LastErrorReason).ToHashSet();
LogHelper.Warn($"[预警计算] 已重新投递[{needRetryMetadata.Count}]条消息", true); var errorMessage = "------------\r\n" + string.Join("\r\n------------\r\n", errorReasons);
_activity?.SetTag("EndPublicRetryMessage", $"[预警计算] 已重新投递[{needRetryMetadata.Count}]条消息\r\n{errorMessage}");
LogHelper.Warn($"[预警计算] 已重新投递[{needRetryMetadata.Count}]条消息\r\n{errorMessage}", true);
} }
// 4.进入死信的消息,投入到死信队列,等待人工处理 // 4.进入死信的消息,投入到死信队列,等待人工处理
@ -194,8 +249,10 @@ public sealed class WarningCalcBackgroundService : BackgroundService
}).ToArray(); }).ToArray();
await Task.WhenAll(tasks); await Task.WhenAll(tasks);
_activity?.SetTag("StartPublicDLXMessage", $"[预警计算] 已进入死信队列[{needEnqueueDlxMetadata.Count}]条消息"); var errorReasons = needRetryMetadata.Select(x => x.LastErrorReason).ToHashSet();
LogHelper.Warn($"[预警计算] 已进入死信队列[{needEnqueueDlxMetadata.Count}]条消息", true); var errorMessage = "------------\r\n" + string.Join("\r\n------------\r\n", errorReasons);
_activity?.SetTag("StartPublicDLXMessage", $"[预警计算] 已进入死信队列[{needEnqueueDlxMetadata.Count}]条消息\r\n{errorMessage}");
LogHelper.Warn($"[预警计算] 已进入死信队列[{needEnqueueDlxMetadata.Count}]条消息\r\n{errorMessage}", true);
} }
} }

View File

@ -14,7 +14,6 @@ public static class WarningCalcServiceExtension
{ {
public static void AddWarningCalcServices(this IServiceCollection services, IConfiguration conf) public static void AddWarningCalcServices(this IServiceCollection services, IConfiguration conf)
{ {
PrintKafkaLibVersion();
var env = "-" + conf.GetValue<string>("Environment")!.ToLower(); var env = "-" + conf.GetValue<string>("Environment")!.ToLower();
// 预警信号批处理后台任务 // 预警信号批处理后台任务
services.AddHostedService<WarningCalcBackgroundService>(); services.AddHostedService<WarningCalcBackgroundService>();
@ -167,20 +166,6 @@ public static class WarningCalcServiceExtension
return list; return list;
} }
public static void PrintKafkaLibVersion()
{
var loadSuccess = Library.Load(null);
Console.WriteLine($@"
+-------------------------------------------------------+
| |
| LibrdKafka |
| 加载:{loadSuccess},版本号:{Library.VersionString} |
| |
+-------------------------------------------------------+
");
}
} }
internal sealed class JsonCoreSerializer<T> : ISerializer<T>, IDeserializer<T> internal sealed class JsonCoreSerializer<T> : ISerializer<T>, IDeserializer<T>

View File

@ -4,8 +4,6 @@ namespace TrackCenter.Application.Rabbit;
public class RabbitOptions public class RabbitOptions
{ {
public string ConnectionString { get; set; }
public List<ConsumeOptions> Consumes { get; set; } = new(); public List<ConsumeOptions> Consumes { get; set; } = new();
public List<Action<IDeclaration>> Declarations { get; set; } = new(); public List<Action<IDeclaration>> Declarations { get; set; } = new();

View File

@ -3,7 +3,7 @@ using TrackCenter.Domain.VEntities;
namespace TrackCenter.Application.Track2InterfaceRelay; namespace TrackCenter.Application.Track2InterfaceRelay;
public class InterfaceForwardService public class InterfaceForwardService : ITransientDependency
{ {
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory _httpClientFactory;
private readonly IBasicRepository<VAppEntity> _appRepository; private readonly IBasicRepository<VAppEntity> _appRepository;
@ -30,12 +30,14 @@ public class InterfaceForwardService
{ {
throw new BusinessException(message: $"请在{nameof(Track2InterfaceRelayAppContext)}中调用接口通"); throw new BusinessException(message: $"请在{nameof(Track2InterfaceRelayAppContext)}中调用接口通");
} }
var key = Track2InterfaceRelayAppContext.Current.AppKey; var key = Track2InterfaceRelayAppContext.Current.AppKey;
var secret = await _appRepository.GetFirstAsync(x => x.AppKey == key, x => x.AppSecret); var secret = await _appRepository.GetFirstAsync(x => x.AppKey == key, x => x.AppSecret);
if (secret == null) if (secret == null)
{ {
throw new BusinessException(message: $"未能找到相应app,请联系管理员"); throw new BusinessException(message: $"未能找到相应app,请联系管理员");
} }
content.Headers.Add(nameof(InterfaceForwardOptions.AppKey), key); content.Headers.Add(nameof(InterfaceForwardOptions.AppKey), key);
content.Headers.Add(nameof(InterfaceForwardOptions.AppSecret), secret); content.Headers.Add(nameof(InterfaceForwardOptions.AppSecret), secret);

View File

@ -10,20 +10,22 @@ using Hangfire;
using Hangfire.Redis.StackExchange; using Hangfire.Redis.StackExchange;
using InterfaceForward.Domain.Shared.Helpers; using InterfaceForward.Domain.Shared.Helpers;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using RabbitMQ.Client; using RabbitMQ.Client;
using Savorboard.CAP.InMemoryMessageQueue; using Savorboard.CAP.InMemoryMessageQueue;
using TrackCenter.Application.Kafka; using TrackCenter.Application.Kafka;
using TrackCenter.Application.CAP; using TrackCenter.Application.CAP;
using TrackCenter.Application.Hangfire; using TrackCenter.Application.Hangfire;
using TrackCenter.Application.HostServices;
using TrackCenter.Application.Options; using TrackCenter.Application.Options;
using TrackCenter.Application.Rabbit; using TrackCenter.Application.Rabbit;
namespace TrackCenter.Application; namespace TrackCenter.Application;
[DependsOn(typeof(FakeRabbitMqModule))] [DependsOn(typeof(FakeRabbitMqModule))]
[DependsOn(typeof(FakeAspNetCoreModule))]
[DependsOn(typeof(FakeObjectMappingAutoMapperModule))] [DependsOn(typeof(FakeObjectMappingAutoMapperModule))]
[DependsOn(typeof(FakeEventBusRabbitMqModule))] [DependsOn(typeof(FakeEventBusRabbitMqModule))]
[DependsOn(typeof(TrackCenterDomainModule))]
public class TrackCenterApplicationModule : FakeModule public class TrackCenterApplicationModule : FakeModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -35,19 +37,21 @@ public class TrackCenterApplicationModule : FakeModule
options.ScanProfiles<TrackCenterApplicationModule>(); options.ScanProfiles<TrackCenterApplicationModule>();
}); });
var rabbitOptions = configuration.GetSection("RabbitMQ").Get<FakeRabbitMqOptions>()!.Default;
//CAP //CAP
context.Services.AddSingleton<ISubscribeExecutor, MySubscribeExecutor>(); context.Services.AddSingleton<ISubscribeExecutor, MySubscribeExecutor>();
if (!System.Diagnostics.Debugger.IsAttached) if (!System.Diagnostics.Debugger.IsAttached)
{ {
context.Services.AddCap(options => context.Services.AddCap(options =>
{ {
options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!); options.UseMySql(configuration["ConnectionStrings:Default"]!);
options.UseRabbitMQ(configure => options.UseRabbitMQ(configure =>
{ {
configure.HostName = configuration["RabbitMQ:HostName"]!; configure.HostName = rabbitOptions.HostName;
configure.UserName = configuration["RabbitMQ:UserName"]!; configure.UserName = rabbitOptions.UserName;
configure.Password = configuration["RabbitMQ:Password"]!; configure.Password = rabbitOptions.Password;
configure.Port = configuration.GetValue<int>("RabbitMQ:Port"); configure.Port = rabbitOptions.Port;
configure.BasicQosOptions = configure.BasicQosOptions =
new RabbitMQOptions.BasicQos(configuration.GetValue<ushort>("CAP:PrefetchCount")); new RabbitMQOptions.BasicQos(configuration.GetValue<ushort>("CAP:PrefetchCount"));
}); });
@ -86,14 +90,12 @@ public class TrackCenterApplicationModule : FakeModule
capOptions.UseInMemoryMessageQueue(); capOptions.UseInMemoryMessageQueue();
capOptions.UseDashboard(); capOptions.UseDashboard();
}).AddSubscribeFilter<CapFilter>(); }).AddSubscribeFilter<CapFilter>();
Console.WriteLine("-- 当前为VS本地环境,用内存存储和内存队列"); LogHelper.Info("-- 当前为本地环境,用内存存储和内存队列");
} }
context.Services.AddHostedService<RabbitClient>(); context.Services.AddHostedService<RabbitClient>();
context.Services.Configure<RabbitOptions>(options => context.Services.Configure<RabbitOptions>(options =>
{ {
options.ConnectionString =
$"amqp://{configuration["RabbitMQ:UserName"]}:{configuration["RabbitMQ:Password"]}@{configuration["RabbitMQ:HostName"]}:{configuration["RabbitMQ:Port"]}";
options.Declarations = new List<Action<IDeclaration>>() options.Declarations = new List<Action<IDeclaration>>()
{ {
o => o.ExchangeDeclare(GlobalConst.TrackChangeExchange, ExchangeType.Topic, true), o => o.ExchangeDeclare(GlobalConst.TrackChangeExchange, ExchangeType.Topic, true),
@ -149,11 +151,11 @@ public class TrackCenterApplicationModule : FakeModule
$",defaultDatabase={configuration["Redis:Database"]}" + $",defaultDatabase={configuration["Redis:Database"]}" +
$",abortConnect=false"; $",abortConnect=false";
// 注册预警计算服务 // todo:注册预警计算服务
context.Services.AddWarningCalcServices(configuration); //context.Services.AddWarningCalcServices(configuration);
// 注册预警任务后台服务 // 注册预警任务后台服务
context.Services.AddHostedService<WarningTaskComponentBackgroundService>(); context.Services.AddHostedService<WarningTaskComponentHostedService>();
// 注册飞书服务(用于预警通知) // 注册飞书服务(用于预警通知)
context.Services.AddFeishuNetSdk(o => context.Services.AddFeishuNetSdk(o =>
@ -188,20 +190,7 @@ public class TrackCenterApplicationModule : FakeModule
context.Services.AddHttpClient("itfx", client => context.Services.AddHttpClient("itfx", client =>
{ {
client.Timeout = TimeSpan.FromSeconds(20); client.Timeout = TimeSpan.FromSeconds(20);
client.BaseAddress = new Uri(configuration["itfx:BaseAddress"]!); client.BaseAddress = new Uri(configuration["TrackApp:ItfxBaseAddress"]!);
}); });
} }
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,3 +1,4 @@
using Fake.Domain.Entities;
using Fake.Domain.Entities.Auditing; using Fake.Domain.Entities.Auditing;
using TrackCenter.Domain.SeedWork; using TrackCenter.Domain.SeedWork;
@ -7,7 +8,8 @@ namespace TrackCenter.Domain.Aggregates.OrderAggregate;
/// 订单轨迹拉取状态表(1:N) /// 订单轨迹拉取状态表(1:N)
/// </summary> /// </summary>
[SugarTable("t_order_pull_status")] [SugarTable("t_order_pull_status")]
public class OrderPullStatusEntity : FullAuditedEntity<int> public class OrderPullStatusEntity : Entity<int>, IHasCreateUserId<int>, IHasCreateTime, IHasUpdateUserId<int>,
IHasUpdateTime
{ {
/// <summary> /// <summary>
/// 自增主键 /// 自增主键
@ -88,7 +90,7 @@ public class OrderPullStatusEntity : FullAuditedEntity<int>
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
[SugarColumn(ColumnName = "UpdateTime")] [SugarColumn(ColumnName = "UpdateTime")]
public DateTime? UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
[SugarColumn(ColumnName = "UpdateUserId")] [SugarColumn(ColumnName = "UpdateUserId")]
public int UpdateUserId { get; set; } public int UpdateUserId { get; set; }

View File

@ -5,36 +5,36 @@ public partial class GlobalConst
/// <summary> /// <summary>
/// 轨迹明细 es索引名称(模板按月) /// 轨迹明细 es索引名称(模板按月)
/// </summary> /// </summary>
public const string TrackDetailsIndex = "sjzy_track_details"; public const string TrackDetailsIndex = "track_details";
/// <summary> /// <summary>
/// 轨迹推送记录 es索引名称(模板按月) /// 轨迹推送记录 es索引名称(模板按月)
/// </summary> /// </summary>
public const string TrackPushRecordIndex = "sjzy_track_push_records"; public const string TrackPushRecordIndex = "track_push_records";
/// <summary> /// <summary>
/// 订单操作记录 es索引名称(模板按月) /// 订单操作记录 es索引名称(模板按月)
/// </summary> /// </summary>
public const string OrderOperationRecordIndex = "sjzy_track_order_operation_records"; public const string OrderOperationRecordIndex = "track_order_operation_records";
// todo:以下为新增需要配置索引模板(prod) 生产环境还需要建立索引!! // todo:以下为新增需要配置索引模板(prod) 生产环境还需要建立索引!!
/// <summary> /// <summary>
/// 运输时效预警明细 es索引名称(模板按月) /// 运输时效预警明细 es索引名称(模板按月)
/// </summary> /// </summary>
public const string TransportWarningDetailsIndex = "sjzy_track_transport_warning_details"; public const string TransportWarningDetailsIndex = "track_transport_warning_details";
/// <summary> /// <summary>
/// 回传时效预警明细 es索引名称(模板按月) /// 回传时效预警明细 es索引名称(模板按月)
/// </summary> /// </summary>
public const string ReturnWarningDetailsIndex = "sjzy_track_return_warning_details"; public const string ReturnWarningDetailsIndex = "track_return_warning_details";
/// <summary> /// <summary>
/// 回传报文日志 es索引名称(模板按月) /// 回传报文日志 es索引名称(模板按月)
/// </summary> /// </summary>
public const string ReturnMessageRecordIndex = "sjzy_track_return_message_records"; public const string ReturnMessageRecordIndex = "track_return_message_records";
/// <summary> /// <summary>
/// 完整预警明细 es索引名称(模板按月) /// 完整预警明细 es索引名称(模板按月)
/// </summary> /// </summary>
public const string CompleteWarningDetailsIndex = "sjzy_track_complete_warning_details"; public const string CompleteWarningDetailsIndex = "track_complete_warning_details";
} }

View File

@ -1,7 +0,0 @@
using Fake.Modularity;
namespace TrackCenter.Domain;
public class SjzyTrackDomainModule : FakeModule
{
}

View File

@ -0,0 +1,17 @@
using Fake.DomainDrivenDesign;
using Fake.Modularity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TrackCenter.Domain.Extensions;
namespace TrackCenter.Domain;
[DependsOn(typeof(FakeDomainDrivenDesignModule))]
public class TrackCenterDomainModule : FakeModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
LogHelper.Init(configuration.GetSection("FeiShuNotice").Get<FeiShuNoticeOptions>()!);
}
}

View File

@ -804,7 +804,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract<TrackDetail
public async Task<TrackDetailsIndex?> GetDetailAsync(string orderNo, string trackCode, TrackOrderType orderType, string appKey, DateTime trackTime) public async Task<TrackDetailsIndex?> GetDetailAsync(string orderNo, string trackCode, TrackOrderType orderType, string appKey, DateTime trackTime)
{ {
var res = await Context.SearchAsync<TrackDetailsIndex>(s => s var res = await Context.SearchAsync<TrackDetailsIndex>(s => s
.Index("sjzy_track_details") .Index(GlobalConst.TrackDetailsIndex)
.Query(q => q .Query(q => q
.Bool(b => b .Bool(b => b
.Must(mu => mu .Must(mu => mu