20261008-ide1.0版本发布 #1
@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- All Fake packages -->
|
||||
<FakePackageVersion>8.0.5.16</FakePackageVersion>
|
||||
<FakePackageVersion>8.0.5.17</FakePackageVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
6
scripts/sql/migrate_track_pull_config_order_type.sql
Normal file
6
scripts/sql/migrate_track_pull_config_order_type.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- 轨迹拉取配置增加订单类型(小包/大包/主单),用于同一应用+服务商下按订单类型区分配置
|
||||
-- 库:TrackCenter(t_track_pull_config)
|
||||
-- MySQL;若 OrderType 列已存在可跳过
|
||||
|
||||
ALTER TABLE t_track_pull_config
|
||||
ADD COLUMN OrderType INT NOT NULL DEFAULT 1 COMMENT '订单类型(TrackOrderType:1小包 2大包 4主单)' AFTER ServiceProviderCode;
|
||||
@ -2,8 +2,9 @@ using Serilog;
|
||||
using TrackCenter.Api;
|
||||
|
||||
var builder = WebApplication.CreateSlimBuilder(args);
|
||||
builder.Configuration.AddConsul("idwms/common", source => source.ReloadOnChange = true);
|
||||
builder.Configuration.AddConsul("idwms/trackapi", source => source.ReloadOnChange = true);
|
||||
var prefix = builder.Environment.EnvironmentName == "Development" ? "dev" : "idwms";
|
||||
builder.Configuration.AddConsul($"{prefix}/common", source => source.ReloadOnChange = true);
|
||||
builder.Configuration.AddConsul($"{prefix}/trackapi", source => source.ReloadOnChange = true);
|
||||
var configuration = builder.Configuration;
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(configuration)
|
||||
|
||||
@ -2,7 +2,6 @@ using Fake.AspNetCore;
|
||||
using Fake.AspNetCore.Auditing;
|
||||
using Fake.AspNetCore.Authentication;
|
||||
using Fake.AspNetCore.ExceptionHandling;
|
||||
using Fake.AspNetCore;
|
||||
using Fake.AspNetCore.Newtonsoft;
|
||||
using Fake.AspNetCore.Swagger;
|
||||
using Fake.Autofac;
|
||||
@ -15,7 +14,6 @@ using FluentValidation.AspNetCore;
|
||||
using Hangfire;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
@ -182,8 +180,8 @@ public class TrackCenterApiModule : FakeModule
|
||||
{
|
||||
DisplayStorageConnectionString = false,
|
||||
IgnoreAntiforgeryToken = true,
|
||||
// 「返回站点」链接;PathBase 已由 UsePathBase 处理,勿再设 PrefixPath,否则会变成 /track/track/hangfire/...
|
||||
AppPath = configuration["ASPNETCORE_PATHBASE"],
|
||||
PrefixPath = configuration["ASPNETCORE_PATHBASE"],
|
||||
DashboardTitle = "轨迹预警任务",
|
||||
Authorization = [new AnonymousHangfireAuthorizationFilter()]
|
||||
});
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"FeiShuNotice": {
|
||||
"EnableFeiShuExceptionSubscribe": false
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"UseLocalConfigs": false,
|
||||
"Consul": {
|
||||
"Address": "https://consul.nanafa.com",
|
||||
"Token": "97217125-df0b-5c0a-dbfc-8885def5e471"
|
||||
"Address": "http://test.ideship.com:30850",
|
||||
"Token": "c0aea902-dca0-ac29-299b-a0d47e5402aa"
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +80,11 @@ public class Consignee
|
||||
|
||||
public class UpsertBigBagInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务商code
|
||||
/// </summary>
|
||||
public string ApiCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户名称,或者code,必填
|
||||
/// </summary>
|
||||
@ -108,7 +113,7 @@ public class UpsertBigBagInput
|
||||
public string Product { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品名称,或者code
|
||||
/// 目的国家二字码
|
||||
/// </summary>
|
||||
public string Country { get; set; }
|
||||
}
|
||||
|
||||
@ -1,263 +0,0 @@
|
||||
using System.Security.Cryptography;
|
||||
using Aliyun.OSS;
|
||||
|
||||
namespace TrackCenter.Application.Helpers.OSS
|
||||
{
|
||||
/// <summary>
|
||||
/// 阿里云OSS帮助类
|
||||
/// </summary>
|
||||
public static class OSSHelper
|
||||
{
|
||||
#region 初始化
|
||||
private static OSSOptions _OSSOptions;
|
||||
internal static void Init(OSSOptions OSSOptions)
|
||||
{
|
||||
_OSSOptions = OSSOptions;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取client
|
||||
private static OssClient GetClient()
|
||||
{
|
||||
string errorMessage = null;
|
||||
if (string.IsNullOrEmpty(_OSSOptions?.Endpoint))
|
||||
{
|
||||
errorMessage += $"未找到核心配置参数【{nameof(_OSSOptions.Endpoint)}】!";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_OSSOptions?.AccessKeyId))
|
||||
{
|
||||
errorMessage += $"未找到核心配置参数【{nameof(_OSSOptions.AccessKeyId)}】!";
|
||||
}
|
||||
if (string.IsNullOrEmpty(_OSSOptions?.AccessKeySecret))
|
||||
{
|
||||
errorMessage += $"未找到核心配置参数【{nameof(_OSSOptions.AccessKeySecret)}】!";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
var client = new OssClient(_OSSOptions.Endpoint, _OSSOptions.AccessKeyId, _OSSOptions.AccessKeySecret);
|
||||
return client;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 上传
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件
|
||||
/// </summary>
|
||||
/// <param name="data">文档流</param>
|
||||
/// <param name="fileName">文件名称</param>
|
||||
/// <param name="usCustomKey">是否使用自定义ossKey,如果为true,会以fileName为key</param>
|
||||
/// <returns></returns>
|
||||
public static UploadResultDto Upload(Stream data, string fileName = "", bool usCustomKey = false, bool isPublicBucket = false)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return new UploadResultDto(false);
|
||||
|
||||
var result = Private_Upload(fileName, data, usCustomKey, isPublicBucket);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static UploadResultDto Private_Upload(string fileName, Stream data, bool usCustomKey = false, bool isPublicBucket = false)
|
||||
{
|
||||
var client = GetClient();
|
||||
|
||||
var ossKey = "";
|
||||
if (usCustomKey)
|
||||
{
|
||||
ossKey = fileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
var md5 = ComputeDataMd5(data).ToUpper();// 计算文件MD5值
|
||||
var ext = Path.GetExtension(fileName);
|
||||
ossKey = $"{md5}{ext}";
|
||||
}
|
||||
|
||||
|
||||
// 文件已经存在直接返回
|
||||
var existingObject = client.DoesObjectExist(_OSSOptions.BucketName, ossKey);
|
||||
if (existingObject)
|
||||
{
|
||||
var res = new UploadResultDto(true);
|
||||
res.TempUrl = ossKey.GetUrlByKey(isPublicBucket);
|
||||
res.Key = ossKey;
|
||||
res.FileName = fileName;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
bool putResult = false;
|
||||
|
||||
using (var pubObj = client.PutObject(_OSSOptions.BucketName, ossKey, data))
|
||||
{
|
||||
putResult = pubObj.HttpStatusCode == System.Net.HttpStatusCode.OK;
|
||||
}
|
||||
|
||||
|
||||
if (putResult)//上传成功
|
||||
{
|
||||
var result = new UploadResultDto(true);
|
||||
result.FileName = fileName;
|
||||
result.TempUrl = ossKey.GetUrlByKey(isPublicBucket);
|
||||
result.Key = ossKey;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 上传失败
|
||||
var result = new UploadResultDto(false);
|
||||
result.FileName = fileName;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static string ComputeDataMd5(Stream data)
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
var hash = BitConverter.ToString(md5.ComputeHash(data)).Replace("-", "").Replace("=", "").ToLower();
|
||||
data.Position = 0;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 下载
|
||||
|
||||
/// <summary>
|
||||
/// 通过Key获取文件的URL - 同步
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
/// <returns>下载Url</returns>
|
||||
public static string GetUrlByKey(this string key, bool isPublicBucket = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new Exception($"指定的key不能为空");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var client = GetClient();
|
||||
Uri url = client.GeneratePresignedUri(_OSSOptions.BucketName, key);
|
||||
|
||||
if (isPublicBucket)
|
||||
{
|
||||
var urlStr = url?.GetLeftPart(UriPartial.Path);
|
||||
return (_OSSOptions.ReturnHttpsUrl && urlStr?.ToString()?.StartsWith("http://") == true) ? "https://" + urlStr.ToString().Substring(7) : urlStr.ToString();
|
||||
}
|
||||
|
||||
|
||||
return (_OSSOptions.ReturnHttpsUrl && url?.ToString()?.StartsWith("http://") == true) ? "https://" + url.ToString().Substring(7) : url.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据一组key返回url
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static Dictionary<string, string> GetUrlByKeys(params string[] keys)
|
||||
{
|
||||
var resDic = new Dictionary<string, string>();
|
||||
if (keys == null || keys.Count() <= 0)
|
||||
return resDic;
|
||||
|
||||
|
||||
var returnHttps = _OSSOptions.ReturnHttpsUrl;
|
||||
var client = GetClient();
|
||||
|
||||
foreach (var item in keys)
|
||||
{
|
||||
if (resDic.ContainsKey(item))
|
||||
continue;
|
||||
|
||||
Uri url = client.GeneratePresignedUri(_OSSOptions.BucketName, item);
|
||||
if (url == null)
|
||||
continue;
|
||||
|
||||
resDic.Add(item, returnHttps ? url.ToString().Replace("http", "https") : url.ToString());
|
||||
}
|
||||
return resDic;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 通过Key获取文件流
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
/// <returns></returns>
|
||||
public static Stream GetStreamByKey(this string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new Exception($"指定的key不能为空");
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var client = GetClient();
|
||||
var obj = client.GetObject(_OSSOptions.BucketName, key);
|
||||
if (obj != null)
|
||||
{
|
||||
return obj.Content;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"文件获取异常");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(ex.Message);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 删除
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
/// <returns></returns>
|
||||
public static DeleteObjectsResult DeleteObjectsByKeys(params string[] keys)
|
||||
{
|
||||
if (keys == null || keys.Length <= 0)
|
||||
return default(DeleteObjectsResult);
|
||||
|
||||
var client = GetClient();
|
||||
var request = new DeleteObjectsRequest(_OSSOptions.BucketName, keys);
|
||||
|
||||
return client.DeleteObjects(request);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 查看数据信息
|
||||
/// <summary>
|
||||
/// 查看文档信息
|
||||
/// </summary>
|
||||
/// <param name="ossKey"></param>
|
||||
/// <returns></returns>
|
||||
public static ObjectMetadata GetObjectMetadata(string ossKey)
|
||||
{
|
||||
var client = GetClient().GetObjectMetadata(_OSSOptions.BucketName, ossKey);
|
||||
return client;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
namespace TrackCenter.Application.Helpers.OSS;
|
||||
|
||||
public class OSSOptions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 秘钥Id(类似于公钥)
|
||||
/// </summary>
|
||||
public string AccessKeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访问秘钥
|
||||
/// </summary>
|
||||
public string AccessKeySecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OSS端点
|
||||
/// </summary>
|
||||
public string Endpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存储空间名称
|
||||
/// 注意,如果有多个BucketName的话,可以直接使用代码的方式设置这个值
|
||||
/// </summary>
|
||||
public string BucketName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回https的url,默认false返回http
|
||||
/// 阿里OSS默认支持http,https,不需要额外配置
|
||||
/// </summary>
|
||||
public bool ReturnHttpsUrl { get; set; }
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
using Fake.ObjectStorage;
|
||||
|
||||
namespace TrackCenter.Application.Helpers.OSS;
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹附件 object key → 可访问 URL(Fake.ObjectStorage / TencentCos)。
|
||||
/// </summary>
|
||||
public static class ObjectStorageUrlHelper
|
||||
{
|
||||
public static async Task<Dictionary<string, string>> GetUrlByKeysAsync(
|
||||
this IObjectStorage storage,
|
||||
IEnumerable<string?> keys,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
foreach (var raw in keys
|
||||
.Where(k => !string.IsNullOrWhiteSpace(k))
|
||||
.Select(k => k!.Trim())
|
||||
.Distinct(StringComparer.Ordinal))
|
||||
{
|
||||
if (raw.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
||||
|| raw.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result[raw] = raw;
|
||||
continue;
|
||||
}
|
||||
|
||||
result[raw] = await storage.GetUrlAsync(raw, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<string> GetUrlByKeyAsync(
|
||||
this IObjectStorage storage,
|
||||
string? key,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var raw = key.Trim();
|
||||
if (raw.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
||||
|| raw.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
|
||||
return await storage.GetUrlAsync(raw, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
namespace TrackCenter.Application.Helpers.OSS;
|
||||
|
||||
public class UploadResultDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识本次操作是否成功
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 临时URL,过期时间15min
|
||||
/// </summary>
|
||||
public string TempUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件唯一标识Key,通常保存在数据
|
||||
/// 后期所有的文件操作都是通过这个Key
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件原始名称
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
|
||||
public UploadResultDto(bool isSuccess)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
}
|
||||
}
|
||||
@ -34,8 +34,7 @@ public static class WarningCalcServiceExtension
|
||||
services.AddSingleton<IConsumer<TKey, TValue>>(sp =>
|
||||
{
|
||||
DebounceHelper.DebounceWrapper? reportFuncWrapper = null;
|
||||
var bb = new ConsumerBuilder<TKey, TValue>(
|
||||
new ConsumerConfig
|
||||
var consumerConfig = new ConsumerConfig
|
||||
{
|
||||
ClientId = Dns.GetHostName(),
|
||||
GroupId = groupId,
|
||||
@ -57,7 +56,10 @@ public static class WarningCalcServiceExtension
|
||||
// Debug = "all",
|
||||
// LogConnectionClose = false,
|
||||
// LogQueue = true
|
||||
})
|
||||
};
|
||||
ApplyOptionalSasl(consumerConfig, conf);
|
||||
|
||||
var bb = new ConsumerBuilder<TKey, TValue>(consumerConfig)
|
||||
.SetKeyDeserializer(sp.GetRequiredService<JsonCoreSerializer<TKey>>())
|
||||
.SetValueDeserializer(sp.GetRequiredService<JsonCoreSerializer<TValue>>())
|
||||
.SetErrorHandler((_, error) =>
|
||||
@ -93,7 +95,7 @@ public static class WarningCalcServiceExtension
|
||||
services.AddSingleton<IProducer<TKey, TValue>>(sp =>
|
||||
{
|
||||
DebounceHelper.DebounceWrapper? reportFuncWrapper = null;
|
||||
var bb = new ProducerBuilder<TKey, TValue>(new ProducerConfig()
|
||||
var producerConfig = new ProducerConfig
|
||||
{
|
||||
ClientId = Dns.GetHostName(),
|
||||
BootstrapServers = conf.GetValue<string>("Kafka:BootstrapServers"),
|
||||
@ -117,7 +119,10 @@ public static class WarningCalcServiceExtension
|
||||
// Debug = "all",
|
||||
// LogConnectionClose = false,
|
||||
// LogQueue = true
|
||||
})
|
||||
};
|
||||
ApplyOptionalSasl(producerConfig, conf);
|
||||
|
||||
var bb = new ProducerBuilder<TKey, TValue>(producerConfig)
|
||||
.SetKeySerializer(sp.GetRequiredService<JsonCoreSerializer<TKey>>())
|
||||
.SetValueSerializer(sp.GetRequiredService<JsonCoreSerializer<TValue>>())
|
||||
.SetErrorHandler((_, error) =>
|
||||
@ -143,6 +148,21 @@ public static class WarningCalcServiceExtension
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地连外口 kafka-ext(SASL)时配置;集群内 PLAINTEXT 不配 SaslUsername 则跳过。
|
||||
/// </summary>
|
||||
private static void ApplyOptionalSasl(ClientConfig cfg, IConfiguration conf)
|
||||
{
|
||||
var user = conf.GetValue<string>("Kafka:SaslUsername");
|
||||
if (string.IsNullOrWhiteSpace(user))
|
||||
return;
|
||||
|
||||
cfg.SecurityProtocol = conf.GetValue("Kafka:SecurityProtocol", SecurityProtocol.SaslPlaintext);
|
||||
cfg.SaslMechanism = conf.GetValue("Kafka:SaslMechanism", SaslMechanism.Plain);
|
||||
cfg.SaslUsername = user;
|
||||
cfg.SaslPassword = conf.GetValue<string>("Kafka:SaslPassword");
|
||||
}
|
||||
|
||||
private static void AddJsonSerializer<T>(this IServiceCollection services, Action<JsonSerializerOptions>? setup = null)
|
||||
{
|
||||
services.TryAddSingleton(_ =>
|
||||
|
||||
@ -81,7 +81,7 @@ public class TrackRefreshEventHandler(
|
||||
// 客户A 渠道B 产品A
|
||||
|
||||
var config = await trackPullCacheService.GetPullParamsWithContentAsync(attach.AppKey,
|
||||
attach.ServiceProviderCode);
|
||||
attach.ServiceProviderCode, attach.OrderType);
|
||||
if (config is null)
|
||||
{
|
||||
logger.LogWarning("请求id: {@RequestId},轨迹消费失败,找不到拉取配置:{@Attach}", attach.ToJson(), @event.RequestId);
|
||||
|
||||
@ -179,7 +179,8 @@ public partial class OrderService
|
||||
|
||||
var config = await _trackPullConfigRepository
|
||||
.FirstOrDefaultAsync(x => x.AppKey == AppKey
|
||||
&& x.ServiceProviderCode == input.ApiCode);
|
||||
&& x.ServiceProviderCode == input.ApiCode
|
||||
&& x.OrderType == TrackOrderType.小包);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
@ -192,11 +193,12 @@ public partial class OrderService
|
||||
return order;
|
||||
}
|
||||
|
||||
private Task<OrderEntity> BuiltOrder(UpsertBigBagInput input)
|
||||
private async Task<OrderEntity> BuiltOrder(UpsertBigBagInput input)
|
||||
{
|
||||
var order = new OrderEntity
|
||||
{
|
||||
AppKey = AppKey!,
|
||||
ServiceProviderCode = input.ApiCode,
|
||||
OrderType = TrackOrderType.大包,
|
||||
OrderNo = input.BagNo,
|
||||
ThirdPartyOrderNumber = input.OtherNo,
|
||||
@ -206,8 +208,25 @@ public partial class OrderService
|
||||
ArrivalCountry = input.Country
|
||||
};
|
||||
|
||||
// tips: 2025-11-29 zzh 大包没有轨迹拉取能力
|
||||
return Task.FromResult(order);
|
||||
if (string.IsNullOrWhiteSpace(input.ApiCode))
|
||||
{
|
||||
// 未传 apiCode 时保持兼容:不挂拉取配置
|
||||
return order;
|
||||
}
|
||||
|
||||
var config = await _trackPullConfigRepository
|
||||
.FirstOrDefaultAsync(x => x.AppKey == AppKey
|
||||
&& x.ServiceProviderCode == input.ApiCode
|
||||
&& x.OrderType == TrackOrderType.大包);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
throw ProviderServiceActionResult.Exception("创建/更新失败",
|
||||
"没有适用的大包拉取配置,请先配置轨迹拉取,否则无法拉取轨迹");
|
||||
}
|
||||
|
||||
order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
|
||||
return order;
|
||||
}
|
||||
|
||||
private async Task<OrderEntity> BuiltOrder(UpsertMasterOrderInput input)
|
||||
@ -227,7 +246,8 @@ public partial class OrderService
|
||||
|
||||
var config = await _trackPullConfigRepository
|
||||
.FirstOrDefaultAsync(x => x.AppKey == AppKey
|
||||
&& x.ServiceProviderCode == input.ApiCode);
|
||||
&& x.ServiceProviderCode == input.ApiCode
|
||||
&& x.OrderType == TrackOrderType.小包);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Fake.ObjectStorage;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using TrackCenter.Application.Dtos.ProvideServices;
|
||||
using TrackCenter.Application.Helpers;
|
||||
using TrackCenter.Application.Helpers.OSS;
|
||||
@ -14,6 +15,7 @@ public partial class TrackService
|
||||
{
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly IHttpContextAccessor _contextAccessor;
|
||||
private IObjectStorage ObjectStorage => LazyServiceProvider.GetRequiredService<IObjectStorage>();
|
||||
|
||||
/// <summary>
|
||||
/// 查询轨迹(时区补正)
|
||||
@ -37,7 +39,7 @@ public partial class TrackService
|
||||
.SelectMany(x => x.Files!.Select(y => y.OssKey))
|
||||
.ToArray();
|
||||
//根据osskey获取下载地址
|
||||
var ossKeyUrlDict = OSSHelper.GetUrlByKeys(ossKeys);
|
||||
var ossKeyUrlDict = await ObjectStorage.GetUrlByKeysAsync(ossKeys);
|
||||
|
||||
foreach (var group in details.GroupBy(x => x.OrderId))
|
||||
{
|
||||
@ -118,7 +120,7 @@ public partial class TrackService
|
||||
.SelectMany(x => x.Files!.Select(y => y.OssKey))
|
||||
.ToArray();
|
||||
//根据osskey获取下载地址
|
||||
var ossKeyUrlDict = OSSHelper.GetUrlByKeys(ossKeys);
|
||||
var ossKeyUrlDict = await ObjectStorage.GetUrlByKeysAsync(ossKeys);
|
||||
|
||||
foreach (var group in details.GroupBy(x => x.OrderId))
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Linq.Expressions;
|
||||
using Fake.Domain.Dtos;
|
||||
using Fake.ObjectStorage;
|
||||
using TrackCenter.Application.Dtos.ProvideServices;
|
||||
using TrackCenter.Application.Dtos.TrackContents;
|
||||
using TrackCenter.Application.Helpers;
|
||||
@ -27,6 +28,7 @@ public class TrackContentService : ApplicationServiceBase
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly TrackPushCacheService _trackPushCacheService;
|
||||
private IObjectStorage ObjectStorage => LazyServiceProvider.GetRequiredService<IObjectStorage>();
|
||||
|
||||
public TrackContentService(
|
||||
ITrackContentRepository trackContentRepository,
|
||||
@ -249,7 +251,7 @@ public class TrackContentService : ApplicationServiceBase
|
||||
|
||||
if (ossKeys.Length == 0) return res;
|
||||
|
||||
var ossKeyUrlDict = OSSHelper.GetUrlByKeys(ossKeys);
|
||||
var ossKeyUrlDict = await ObjectStorage.GetUrlByKeysAsync(ossKeys);
|
||||
foreach (var item in res.Files)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.OssKey)) continue;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Linq.Expressions;
|
||||
using Fake.Domain.Dtos;
|
||||
using Fake.ObjectStorage;
|
||||
using TrackCenter.Application.Dtos.ProvideServices;
|
||||
using TrackCenter.Application.Dtos.TrackOrder;
|
||||
using TrackCenter.Application.Helpers;
|
||||
@ -27,6 +28,7 @@ public class TrackOrderService : ApplicationServiceBase
|
||||
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
|
||||
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private IObjectStorage ObjectStorage => LazyServiceProvider.GetRequiredService<IObjectStorage>();
|
||||
|
||||
public TrackOrderService(
|
||||
IOrderRepository orderRepository,
|
||||
@ -215,6 +217,9 @@ public class TrackOrderService : ApplicationServiceBase
|
||||
//时间轴不显示轨迹内容为空的轨迹,进行过滤
|
||||
trackDetails = trackDetails.Where(x => !x.TrackContent.IsNullOrWhiteSpace() && x.TrackContent != GlobalConst.EmptyString).ToList();
|
||||
|
||||
var ossKeyUrlDict = await ObjectStorage.GetUrlByKeysAsync(
|
||||
trackDetails.Where(x => x.Files != null).SelectMany(x => x.Files!.Select(f => f.OssKey)));
|
||||
|
||||
foreach (var item in trackDetails)
|
||||
{
|
||||
//时间和时区任意一个为空则使用创建时间做为排序参照值
|
||||
@ -236,7 +241,7 @@ public class TrackOrderService : ApplicationServiceBase
|
||||
{
|
||||
OssKey = m.OssKey,
|
||||
FileName = m.FileName,
|
||||
Url = m.OssKey.GetUrlByKey(),
|
||||
Url = ossKeyUrlDict.TryGetValue(m.OssKey ?? string.Empty, out var u) ? u : string.Empty,
|
||||
}).ToList(),
|
||||
Content = item.TrackContent,
|
||||
TrackCode = item.TrackCode,
|
||||
|
||||
@ -20,12 +20,12 @@ public class TrackPullCacheService : ITransientDependency
|
||||
$"{GlobalConst.TrackPullKeyPrefix}:{config.AppKey}:{config.ServiceProviderCode}:{config.Customer}";
|
||||
|
||||
public async Task<TrackPullParamsWithContentDto?> GetPullParamsWithContentAsync(string appKey,
|
||||
string serviceProviderCode)
|
||||
string serviceProviderCode, TrackOrderType orderType)
|
||||
{
|
||||
var data = await RedisHelper.Client.GetAsync<TrackPullParamsWithContentDto>(TrackPullContentKey(
|
||||
appKey, serviceProviderCode));
|
||||
appKey, serviceProviderCode, orderType));
|
||||
|
||||
var pullId = await _trackPullConfigRepository.FindIdAsync(appKey, serviceProviderCode);
|
||||
var pullId = await _trackPullConfigRepository.FindIdAsync(appKey, serviceProviderCode, orderType);
|
||||
data ??= await SetPullConfigAsync(pullId);
|
||||
|
||||
return data;
|
||||
@ -53,12 +53,13 @@ public class TrackPullCacheService : ITransientDependency
|
||||
trackPullContentList)
|
||||
};
|
||||
|
||||
var key = TrackPullContentKey(trackPullConfigDetail.AppKey, trackPullConfigDetail.ServiceProviderCode);
|
||||
var key = TrackPullContentKey(trackPullConfigDetail.AppKey, trackPullConfigDetail.ServiceProviderCode,
|
||||
trackPullConfigDetail.OrderType);
|
||||
await RedisHelper.Client.SetAsync(key, data, TimeSpan.FromHours(24));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static string TrackPullContentKey(string appKey, string serviceProviderCode) =>
|
||||
$"{GlobalConst.TrackPullContentKeyPrefix}:{appKey}:{serviceProviderCode}";
|
||||
public static string TrackPullContentKey(string appKey, string serviceProviderCode, TrackOrderType orderType) =>
|
||||
$"{GlobalConst.TrackPullContentKeyPrefix}:{appKey}:{serviceProviderCode}:{(int)orderType}";
|
||||
}
|
||||
|
||||
@ -83,9 +83,13 @@ public class TrackPullService(
|
||||
|
||||
if (input.Options != OptionTypeNoNull.删除)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(TrackOrderType), input.OrderType))
|
||||
throw new BusinessException("请选择订单类型");
|
||||
|
||||
Expression<Func<TrackPullConfigEntity, bool>> isAnyExp = x =>
|
||||
x.AppKey == input.AppKey &&
|
||||
x.ServiceProviderCode == input.ServiceProviderCode;
|
||||
x.ServiceProviderCode == input.ServiceProviderCode &&
|
||||
x.OrderType == input.OrderType;
|
||||
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
|
||||
|
||||
if (await trackPullConfigRepository.IsAnyAsync(isAnyExp))
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
<PackageReference Include="Fake.AspNetCore" Version="$(FakePackageVersion)" />
|
||||
<PackageReference Include="Fake.EventBus.RabbitMQ" Version="$(FakePackageVersion)" />
|
||||
<PackageReference Include="Fake.ObjectMapping.AutoMapper" Version="$(FakePackageVersion)" />
|
||||
<PackageReference Include="Fake.ObjectStorage.TencentCos" Version="$(FakePackageVersion)" />
|
||||
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.10.0" />
|
||||
<PackageReference Include="FeishuNetSdk" Version="2.4.6" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.18" />
|
||||
|
||||
@ -7,12 +7,14 @@ using Fake;
|
||||
using Fake.EventBus.RabbitMQ;
|
||||
using Fake.Modularity;
|
||||
using Fake.ObjectMapping.AutoMapper;
|
||||
using Fake.ObjectStorage;
|
||||
using Fake.RabbitMQ;
|
||||
using FreeRedis;
|
||||
using Hangfire;
|
||||
using Hangfire.Redis.StackExchange;
|
||||
using InterfaceForward.Domain.Shared.Helpers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RabbitMQ.Client;
|
||||
using Savorboard.CAP.InMemoryMessageQueue;
|
||||
using TrackCenter.Application.Kafka;
|
||||
@ -26,6 +28,7 @@ namespace TrackCenter.Application;
|
||||
[DependsOn(typeof(FakeRabbitMqModule))]
|
||||
[DependsOn(typeof(FakeObjectMappingAutoMapperModule))]
|
||||
[DependsOn(typeof(FakeEventBusRabbitMqModule))]
|
||||
[DependsOn(typeof(FakeObjectStorageTencentCosModule))]
|
||||
[DependsOn(typeof(TrackCenterDomainModule))]
|
||||
public class TrackCenterApplicationModule : FakeModule
|
||||
{
|
||||
@ -89,7 +92,7 @@ public class TrackCenterApplicationModule : FakeModule
|
||||
capOptions.UseInMemoryMessageQueue();
|
||||
capOptions.UseDashboard();
|
||||
}).AddSubscribeFilter<CapFilter>();
|
||||
Log.Information("-- 当前为本地环境,用内存存储和内存队列");
|
||||
context.Services.GetInitLogger<TrackCenterApplicationModule>().LogInformation("-- 当前为本地环境,用内存存储和内存队列");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -142,16 +145,6 @@ public class TrackCenterApplicationModule : FakeModule
|
||||
context.Services.Configure<InterfaceRelayParamsConfigOptions>(
|
||||
configuration.GetSection("InterfaceRelayParamsConfig"));
|
||||
|
||||
// //注册阿里云OSS服务
|
||||
// context.Services.AddAliOSS(option =>
|
||||
// {
|
||||
// option.AccessKeyId = configuration["OSS:AccessKeyId"];
|
||||
// option.AccessKeySecret = configuration["OSS:AccessKeySecret"];
|
||||
// option.Endpoint = configuration["OSS:Endpoint"];
|
||||
// option.BucketName = configuration["OSS:BucketName"];
|
||||
// option.ReturnHttpsUrl = true;
|
||||
// });
|
||||
|
||||
var connectionString = $"{configuration["Redis:Host"]}" +
|
||||
$",password={configuration["Redis:Password"]}" +
|
||||
$",defaultDatabase={configuration["Redis:Database"]}" +
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||
[SugarTable("t_order")]
|
||||
public class OrderEntity : FullAuditedAggregateRoot<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
@ -109,7 +105,7 @@ public class OrderEntity : FullAuditedAggregateRoot<int, int>
|
||||
/// 目的城市
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "ArrivalCity")]
|
||||
public string ArrivalCity { get; set; } = null!;
|
||||
public string ArrivalCity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目的国家
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||
[SugarTable("t_order_flight")]
|
||||
public class OrderFlightEntity : CreateAuditedEntity<int, int>, ISoftDelete
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 班期
|
||||
|
||||
@ -8,11 +8,7 @@ namespace TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||
[SugarTable("t_order_link")]
|
||||
public class OrderLinkEntity : CreateAuditedEntity<int, int>, ISoftDelete
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
|
||||
@ -11,11 +11,7 @@ namespace TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||
public class OrderPullStatusEntity : Entity<int>, IHasCreateUserId<int>, IHasCreateTime, IHasUpdateUserId<int>,
|
||||
IHasUpdateTime
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 订单id
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackContentAggregate;
|
||||
[SugarTable("t_track_content")]
|
||||
public class TrackContentEntity : FullAuditedAggregateRoot<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹内容代码
|
||||
|
||||
@ -8,11 +8,7 @@ namespace TrackCenter.Domain.Aggregates.TrackContentAggregate;
|
||||
[SugarTable("t_track_content_map")]
|
||||
public class TrackContentMapEntity : FullAuditedEntity<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 源应用
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackFlagAggregate;
|
||||
[SugarTable("t_track_flag")]
|
||||
public class TrackFlagEntity : FullAuditedAggregateRoot<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 标记代码
|
||||
|
||||
@ -75,5 +75,5 @@ public interface ITrackPullConfigRepository : IBasicRepository<TrackPullConfigEn
|
||||
|
||||
Task<bool> IsPriorityAnyAsync(Expression<Func<TrackPullPriorityEntity, bool>> whereExpression);
|
||||
|
||||
Task<int> FindIdAsync(string appKey, string serviceProviderCode);
|
||||
Task<int> FindIdAsync(string appKey, string serviceProviderCode, TrackOrderType orderType);
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@ public class TrackPullConfigEntity : FullAuditedAggregateRoot<int, int>
|
||||
[SugarColumn(ColumnName = "ServiceProviderCode")]
|
||||
public string ServiceProviderCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型(主数据枚举TrackOrderType)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "OrderType")]
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始轨迹code
|
||||
/// </summary>
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
||||
[SugarTable("t_track_pull_content_config")]
|
||||
public class TrackPullContentConfigEntity : FullAuditedEntity<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹拉取配置id
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackPushAggregate;
|
||||
[SugarTable("t_track_push_config")]
|
||||
public class TrackPushConfigEntity : FullAuditedAggregateRoot<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 客户(外部主体id)
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackPushAggregate;
|
||||
[SugarTable("t_track_push_content_config")]
|
||||
public class TrackPushContentConfigEntity : FullAuditedEntity<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 推送单号类型
|
||||
|
||||
@ -9,11 +9,7 @@ namespace TrackCenter.Domain.Aggregates.TrackStatusAggregate;
|
||||
[SugarTable("t_track_status")]
|
||||
public class TrackStatusEntity : FullAuditedAggregateRoot<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 应用
|
||||
|
||||
@ -26,6 +26,11 @@ public class GetTrackPullConfigDetailOutputVO
|
||||
/// </summary>
|
||||
public string AppKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型(主数据枚举TrackOrderType)
|
||||
/// </summary>
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹扩展信息参数名集合(逗号分割)
|
||||
/// </summary>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
using TrackCenter.Domain.Enums;
|
||||
|
||||
namespace TrackCenter.Domain.Dtos.TrackPull;
|
||||
|
||||
public class GetTrackPullConfigPageOutputVO
|
||||
@ -14,6 +16,11 @@ public class GetTrackPullConfigPageOutputVO
|
||||
/// </summary>
|
||||
public string ServiceProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务商code
|
||||
/// </summary>
|
||||
public string ServiceProviderCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用
|
||||
/// </summary>
|
||||
@ -23,4 +30,9 @@ public class GetTrackPullConfigPageOutputVO
|
||||
/// 应用
|
||||
/// </summary>
|
||||
public string AppKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型(主数据枚举TrackOrderType)
|
||||
/// </summary>
|
||||
public TrackOrderType OrderType { get; set; }
|
||||
}
|
||||
|
||||
@ -8,11 +8,7 @@ namespace TrackCenter.Domain.VEntities;
|
||||
[SugarTable("v_service_provider")]
|
||||
public class VServiceProviderEntity : FullAuditedEntity<int, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 自增主键
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 授权接口Code
|
||||
|
||||
@ -9,38 +9,61 @@ namespace TrackCenter.Repository.ES;
|
||||
/// </summary>
|
||||
public static class EsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 月度索引读请求:走 {index}-* 通配符,无匹配索引时返回空结果(首次部署 / 尚未创建别名)。
|
||||
/// </summary>
|
||||
public static SearchDescriptor<T> UseMonthlyIndex<T>(this SearchDescriptor<T> descriptor, string indexPrefix)
|
||||
where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{indexPrefix}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 月度索引按查询更新:目标索引不存在时视为无匹配文档。
|
||||
/// </summary>
|
||||
public static UpdateByQueryDescriptor<T> UseMonthlyIndex<T>(this UpdateByQueryDescriptor<T> descriptor,
|
||||
string indexPrefix)
|
||||
where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{indexPrefix}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 月度索引按查询删除:目标索引不存在时视为无匹配文档。
|
||||
/// </summary>
|
||||
public static DeleteByQueryDescriptor<T> UseMonthlyIndex<T>(this DeleteByQueryDescriptor<T> descriptor,
|
||||
string indexPrefix)
|
||||
where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{indexPrefix}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹明细实际写入月度索引 track_details-yyyy.MM;读请求走通配符,
|
||||
/// 无匹配索引时返回空结果(首次部署 / 尚未 Migrate 别名)。
|
||||
/// </summary>
|
||||
public static SearchDescriptor<T> UseTrackDetailsIndex<T>(this SearchDescriptor<T> descriptor) where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{GlobalConst.TrackDetailsIndex}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
=> descriptor.UseMonthlyIndex(GlobalConst.TrackDetailsIndex);
|
||||
|
||||
/// <summary>
|
||||
/// 轨迹明细按查询更新:目标索引不存在时视为无匹配文档。
|
||||
/// </summary>
|
||||
public static UpdateByQueryDescriptor<T> UseTrackDetailsIndex<T>(this UpdateByQueryDescriptor<T> descriptor)
|
||||
where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{GlobalConst.TrackDetailsIndex}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
=> descriptor.UseMonthlyIndex(GlobalConst.TrackDetailsIndex);
|
||||
|
||||
public static DeleteByQueryDescriptor<T> UseTrackDetailsIndex<T>(this DeleteByQueryDescriptor<T> descriptor)
|
||||
where T : class
|
||||
{
|
||||
return descriptor
|
||||
.Index($"{GlobalConst.TrackDetailsIndex}-*")
|
||||
.IgnoreUnavailable()
|
||||
.AllowNoIndices();
|
||||
}
|
||||
=> descriptor.UseMonthlyIndex(GlobalConst.TrackDetailsIndex);
|
||||
|
||||
/// <summary>
|
||||
/// 索引/别名不存在(含 NEST 对 404 的包装错误)。
|
||||
|
||||
@ -67,13 +67,21 @@ public class OrderOperationRecordEsRepository : ElasticSearchContextAbstract<Ord
|
||||
public async Task<List<OrderOperationRecordIndex>> GetOrderOperationsByIdAsync(int orderId)
|
||||
{
|
||||
var data = await Context.SearchAsync<OrderOperationRecordIndex>(x => x
|
||||
.Index(GlobalConst.OrderOperationRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.OrderOperationRecordIndex)
|
||||
.Query(q =>
|
||||
q.Term(t => t.OrderId, orderId)
|
||||
)
|
||||
.Size(GlobalConst.NormalLimit)
|
||||
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)));
|
||||
|
||||
if (!data.IsValid)
|
||||
{
|
||||
if (data.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"订单操作记录查询失败,原因:{data.DebugInformation}。");
|
||||
}
|
||||
|
||||
return data.ToIdList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ using TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
||||
using TrackCenter.Domain.Aggregates.TrackStatusAggregate;
|
||||
using TrackCenter.Domain.Dtos.Common;
|
||||
using TrackCenter.Domain.Dtos.TrackPull;
|
||||
using TrackCenter.Domain.Enums;
|
||||
using TrackCenter.Domain.VEntities;
|
||||
|
||||
namespace TrackCenter.Repository.Repositories;
|
||||
@ -27,6 +28,8 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
|
||||
AppKey = system.AppKey,
|
||||
App = system.Name,
|
||||
ServiceProvider = service.Name,
|
||||
ServiceProviderCode = service.Code,
|
||||
OrderType = trackPull.OrderType,
|
||||
CreateTime = trackPull.CreateTime
|
||||
})
|
||||
.ToPagedListAsync(input.PageIndex, input.PageSize);
|
||||
@ -216,11 +219,12 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
|
||||
return await Context.Queryable<TrackPullPriorityEntity>().Where(whereExpression).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<int> FindIdAsync(string appKey, string serviceProviderCode)
|
||||
public async Task<int> FindIdAsync(string appKey, string serviceProviderCode, TrackOrderType orderType)
|
||||
{
|
||||
return await AsQueryable()
|
||||
.Where(trackPull => trackPull.AppKey == appKey
|
||||
&& trackPull.ServiceProviderCode == serviceProviderCode)
|
||||
&& trackPull.ServiceProviderCode == serviceProviderCode
|
||||
&& trackPull.OrderType == orderType)
|
||||
.Select(trackPull => trackPull.Id)
|
||||
.FirstAsync();
|
||||
}
|
||||
|
||||
@ -69,13 +69,21 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
public async Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(int orderId)
|
||||
{
|
||||
var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x
|
||||
.Index(GlobalConst.TrackPushRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TrackPushRecordIndex)
|
||||
.Query(q =>
|
||||
q.Term(t => t.OrderId, orderId)
|
||||
)
|
||||
.Size(1000)
|
||||
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)));
|
||||
|
||||
if (!data.IsValid)
|
||||
{
|
||||
if (data.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"轨迹推送记录查询失败,原因:{data.DebugInformation}。");
|
||||
}
|
||||
|
||||
return data.ToIdList();
|
||||
}
|
||||
|
||||
@ -114,7 +122,7 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
if (isShouldQuery)
|
||||
{
|
||||
r = await Context.SearchAsync<TrackPushRecordIndex>(x => x
|
||||
.Index(GlobalConst.TrackPushRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TrackPushRecordIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(mu => mu.Terms(t => t.Field(f => f.IsSuccess).Terms(input.IsSuccess)))
|
||||
.Should(musts)
|
||||
@ -126,7 +134,7 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
{
|
||||
musts.Add(mu => mu.Terms(t => t.Field(f => f.IsSuccess).Terms(input.IsSuccess)));
|
||||
r = await Context.SearchAsync<TrackPushRecordIndex>(x => x
|
||||
.Index(GlobalConst.TrackPushRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TrackPushRecordIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(musts))
|
||||
)
|
||||
@ -136,6 +144,9 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"轨迹推送记录查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -153,7 +164,7 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
musts.Add(mu => mu.Term(t => t.IsSuccess, true));
|
||||
|
||||
var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x
|
||||
.Index(GlobalConst.TrackPushRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TrackPushRecordIndex)
|
||||
.Query(q =>
|
||||
q.Bool(b =>
|
||||
b.Must(musts))
|
||||
@ -161,13 +172,21 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
.Size(1000)
|
||||
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)));
|
||||
|
||||
if (!data.IsValid)
|
||||
{
|
||||
if (data.IsIndexUnavailable())
|
||||
return null;
|
||||
|
||||
throw new InvalidOperationException($"轨迹推送记录查询失败,原因:{data.DebugInformation}。");
|
||||
}
|
||||
|
||||
return data.Documents.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<List<TrackPushRecordIndex>> GetHistorySuccessTrackPushRecordAsync(int orderId)
|
||||
{
|
||||
var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x
|
||||
.Index(GlobalConst.TrackPushRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TrackPushRecordIndex)
|
||||
.Source(s =>
|
||||
s.Excludes(fs =>
|
||||
fs.Field(f => f.PushContent)))
|
||||
@ -179,6 +198,15 @@ public class TrackPushRecordEsRepository : ElasticSearchContextAbstract<TrackPus
|
||||
)
|
||||
.Size(1000)
|
||||
.Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)));
|
||||
|
||||
if (!data.IsValid)
|
||||
{
|
||||
if (data.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"轨迹推送记录查询失败,原因:{data.DebugInformation}。");
|
||||
}
|
||||
|
||||
return data.ToIdList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
c => c.Match(f => f.Field(d => d.NotifyUsers).Query(input.NotifyUserId)));
|
||||
|
||||
var r = await _client.SearchAsync<TransportWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Sort(s => s.Ascending(f => f.Status).Descending(f => f.CreateTime))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
@ -60,6 +60,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return new PagedResult<TransportWarningDetailsIndex>(0, []);
|
||||
|
||||
throw new InvalidOperationException($"运输预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -116,7 +119,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
if (isShouldQuery)
|
||||
{
|
||||
r = await _client.SearchAsync<TransportWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(mu => mu.Terms(t => t.Field(f => f.Status).Terms(input.Status)))
|
||||
.Should(musts)
|
||||
@ -128,7 +131,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
{
|
||||
musts.Add(mu => mu.Terms(t => t.Field(f => f.Status).Terms(input.Status)));
|
||||
r = await _client.SearchAsync<TransportWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Size(SafelyLimit)
|
||||
);
|
||||
@ -136,6 +139,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"运输预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -294,7 +300,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
musts.AddIf(x => x.HasOrderIds, c => c.Terms(t => t.Field(f => f.OrderId).Terms(input.OrderIds)));
|
||||
|
||||
var r = await _client.UpdateByQueryAsync<TransportWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.TransportWarningDetailsIndex)
|
||||
u.UseMonthlyIndex(GlobalConst.TransportWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Script(s => s
|
||||
.Source(@"ctx._source.status = params.status;
|
||||
@ -310,7 +316,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
if (!r.IsValid && !r.IsIndexUnavailable())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"运输时效预警明细更新失败,input:{input.ToJson()},原因:{r.DebugInformation}。");
|
||||
@ -387,7 +393,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
c => c.Match(f => f.Field(d => d.Customer).Query(input.Customer)));
|
||||
|
||||
var r = await _client.SearchAsync<ReturnWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Sort(s => s.Ascending(f => f.Status).Descending(f => f.CreateTime))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
@ -397,6 +403,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return new PagedResult<ReturnWarningDetailsIndex>(0, []);
|
||||
|
||||
throw new InvalidOperationException($"回传预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -442,7 +451,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
if (isShouldQuery)
|
||||
{
|
||||
r = await _client.SearchAsync<ReturnWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(mu => mu.Terms(t => t.Field(f => f.Status).Terms(input.Status)))
|
||||
.Should(musts)
|
||||
@ -454,7 +463,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
{
|
||||
musts.Add(c => c.Terms(t => t.Field(f => f.Status).Terms(input.Status)));
|
||||
r = await _client.SearchAsync<ReturnWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(musts)
|
||||
))
|
||||
@ -464,6 +473,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"回传预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -473,13 +485,16 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
public async Task<List<ReturnMessageRecordIndex>> GetReturnMessageRecordListByIdAsync(string esId)
|
||||
{
|
||||
var r = await _client.SearchAsync<ReturnMessageRecordIndex>(x => x
|
||||
.Index(GlobalConst.ReturnMessageRecordIndex)
|
||||
.UseMonthlyIndex(GlobalConst.ReturnMessageRecordIndex)
|
||||
.Query(q => q.Match(f => f.Field(d => d.WarningDetailsIds).Query(esId)))
|
||||
.Size(SafelyLimit)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"回传预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -489,13 +504,13 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
public async Task ReturnWarningDetailsRetryIncrementAsync(HashSet<string> esIds)
|
||||
{
|
||||
var r = await _client.UpdateByQueryAsync<ReturnWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
u.UseMonthlyIndex(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Ids(i => i.Values(esIds)))
|
||||
.Script(s => s
|
||||
.Source("ctx._source.retryCount = ctx._source.retryCount+1;")
|
||||
)
|
||||
);
|
||||
if (!r.IsValid)
|
||||
if (!r.IsValid && !r.IsIndexUnavailable())
|
||||
{
|
||||
throw new InvalidOperationException($"回传预警明细更新失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
@ -661,7 +676,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
musts.AddIf(x => x.HasOrderIds, c => c.Terms(t => t.Field(f => f.OrderId).Terms(input.OrderIds)));
|
||||
|
||||
var r = await _client.UpdateByQueryAsync<ReturnWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.ReturnWarningDetailsIndex)
|
||||
u.UseMonthlyIndex(GlobalConst.ReturnWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Script(s => s
|
||||
.Source("ctx._source.status = params.status")
|
||||
@ -669,7 +684,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
if (!r.IsValid && !r.IsIndexUnavailable())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"回传预警明细更新失败,input:{input.ToJson()},原因:{r.DebugInformation}。");
|
||||
@ -766,7 +781,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
.Params(p => p.Add("value", input.MissingTrackStatusId.ToString())))));
|
||||
|
||||
var r = await _client.SearchAsync<CompleteWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Sort(s => s.Ascending(f => f.Status).Descending(f => f.CreateTime))
|
||||
.From((input.PageIndex - 1) * input.PageSize)
|
||||
@ -776,6 +791,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return new PagedResult<CompleteWarningDetailsIndex>(0, []);
|
||||
|
||||
throw new InvalidOperationException($"回传预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -830,7 +848,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
if (isShouldQuery)
|
||||
{
|
||||
r = await _client.SearchAsync<CompleteWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(mu => mu.Terms(t => t.Field(f => f.Status).Terms(input.Status)))
|
||||
.Should(musts)
|
||||
@ -842,7 +860,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
{
|
||||
musts.Add(c => c.Terms(t => t.Field(f => f.Status).Terms(input.Status)));
|
||||
r = await _client.SearchAsync<CompleteWarningDetailsIndex>(x => x
|
||||
.Index(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.UseMonthlyIndex(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b
|
||||
.Must(musts)
|
||||
))
|
||||
@ -852,6 +870,9 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
|
||||
if (!r.IsValid)
|
||||
{
|
||||
if (r.IsIndexUnavailable())
|
||||
return [];
|
||||
|
||||
throw new InvalidOperationException($"完整预警明细查询失败,原因:{r.DebugInformation}。");
|
||||
}
|
||||
|
||||
@ -872,7 +893,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
musts.AddIf(x => x.HasOrderIds, c => c.Terms(t => t.Field(f => f.OrderId).Terms(input.OrderIds)));
|
||||
|
||||
var r = await _client.UpdateByQueryAsync<CompleteWarningDetailsIndex>(u =>
|
||||
u.Index(GlobalConst.CompleteWarningDetailsIndex)
|
||||
u.UseMonthlyIndex(GlobalConst.CompleteWarningDetailsIndex)
|
||||
.Query(q => q.Bool(b => b.Must(musts)))
|
||||
.Script(s => s
|
||||
.Source(@"
|
||||
@ -886,7 +907,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien
|
||||
)
|
||||
);
|
||||
|
||||
if (!r.IsValid)
|
||||
if (!r.IsValid && !r.IsIndexUnavailable())
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"完整预警明细更新失败,input:{input.ToJson()},原因:{r.DebugInformation}。");
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using Fake;
|
||||
using Fake.Domain.Entities;
|
||||
using Fake.SqlSugarCore;
|
||||
|
||||
@ -18,5 +19,10 @@ public class TrackCenterDbContext : SugarDbContext<TrackCenterDbContext>
|
||||
}
|
||||
|
||||
base.ConfigureEntityService(property, column);
|
||||
|
||||
if (property.Name == nameof(Entity<Any>.Id))
|
||||
{
|
||||
column.IsIdentity = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user