..
All checks were successful
Build and Deploy / deploy (push) Successful in 52s

This commit is contained in:
xiaolipro 2026-09-28 09:40:00 +08:00
parent bb15b24829
commit d21149a973
28 changed files with 167 additions and 471 deletions

View File

@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<!-- All Fake packages -->
<FakePackageVersion>8.0.5.16</FakePackageVersion>
<FakePackageVersion>8.0.5.17</FakePackageVersion>
</PropertyGroup>
</Project>

View File

@ -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)

View File

@ -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()]
});

View File

@ -1,11 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Warning"
}
},
"FeiShuNotice": {
"EnableFeiShuExceptionSubscribe": false
}
}

View File

@ -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"
}
}

View File

@ -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
}
}

View File

@ -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; }
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -34,30 +34,32 @@ public static class WarningCalcServiceExtension
services.AddSingleton<IConsumer<TKey, TValue>>(sp =>
{
DebounceHelper.DebounceWrapper? reportFuncWrapper = null;
var bb = new ConsumerBuilder<TKey, TValue>(
new ConsumerConfig
{
ClientId = Dns.GetHostName(),
GroupId = groupId,
BootstrapServers = conf.GetValue<string>("Kafka:BootstrapServers"),
AutoOffsetReset = AutoOffsetReset.Earliest,
//偏移提交控制
EnablePartitionEof = false,
EnableAutoOffsetStore = false,
EnableAutoCommit = false,
//链接控制
SessionTimeoutMs = conf.GetValue<int>("Kafka:Consumer:SessionTimeoutMs"),
MaxPollIntervalMs = conf.GetValue<int>("Kafka:Consumer:MaxPollIntervalMs"),
HeartbeatIntervalMs = conf.GetValue<int>("Kafka:Consumer:HeartbeatIntervalMs"),
//吞吐量
FetchMinBytes = conf.GetValue<int>("Kafka:Consumer:FetchMinBytes"),
FetchMaxBytes = conf.GetValue<int>("Kafka:Consumer:FetchMaxBytes"),
FetchWaitMaxMs = conf.GetValue<int>("Kafka:Consumer:FetchWaitMaxMs"),
CancellationDelayMaxMs = 100,
// Debug = "all",
// LogConnectionClose = false,
// LogQueue = true
})
var consumerConfig = new ConsumerConfig
{
ClientId = Dns.GetHostName(),
GroupId = groupId,
BootstrapServers = conf.GetValue<string>("Kafka:BootstrapServers"),
AutoOffsetReset = AutoOffsetReset.Earliest,
//偏移提交控制
EnablePartitionEof = false,
EnableAutoOffsetStore = false,
EnableAutoCommit = false,
//链接控制
SessionTimeoutMs = conf.GetValue<int>("Kafka:Consumer:SessionTimeoutMs"),
MaxPollIntervalMs = conf.GetValue<int>("Kafka:Consumer:MaxPollIntervalMs"),
HeartbeatIntervalMs = conf.GetValue<int>("Kafka:Consumer:HeartbeatIntervalMs"),
//吞吐量
FetchMinBytes = conf.GetValue<int>("Kafka:Consumer:FetchMinBytes"),
FetchMaxBytes = conf.GetValue<int>("Kafka:Consumer:FetchMaxBytes"),
FetchWaitMaxMs = conf.GetValue<int>("Kafka:Consumer:FetchWaitMaxMs"),
CancellationDelayMaxMs = 100,
// 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,31 +95,34 @@ public static class WarningCalcServiceExtension
services.AddSingleton<IProducer<TKey, TValue>>(sp =>
{
DebounceHelper.DebounceWrapper? reportFuncWrapper = null;
var bb = new ProducerBuilder<TKey, TValue>(new ProducerConfig()
{
ClientId = Dns.GetHostName(),
BootstrapServers = conf.GetValue<string>("Kafka:BootstrapServers"),
// 确保消息发送可靠
Acks = Acks.All,
EnableIdempotence = true,
MessageSendMaxRetries = conf.GetValue<int>("Kafka:Producer:MessageSendMaxRetries"),
RequestTimeoutMs = conf.GetValue<int>("Kafka:Producer:RequestTimeoutMs"),
// 消息体大小
CompressionType = conf.GetValue<CompressionType>("Kafka:Producer:CompressionType"),
CompressionLevel = conf.GetValue<int>("Kafka:Producer:CompressionLevel"),
// 消息发送速率控制(任意一条件先达到就发送)
LingerMs = conf.GetValue<int>("Kafka:Producer:LingerMs"),
BatchSize = conf.GetValue<int>("Kafka:Producer:BatchSize"),
BatchNumMessages = conf.GetValue<int>("Kafka:Producer:BatchNumMessages"),
// 发送缓冲内存限制
QueueBufferingMaxMessages = conf.GetValue<int>("Kafka:Producer:QueueBufferingMaxMessages"),
QueueBufferingMaxKbytes = conf.GetValue<int>("Kafka:Producer:QueueBufferingMaxKbytes"),
// 分区器 一致性hash/随机
Partitioner = conf.GetValue<Partitioner>("Kafka:Producer:Partitioner"),
// Debug = "all",
// LogConnectionClose = false,
// LogQueue = true
})
var producerConfig = new ProducerConfig
{
ClientId = Dns.GetHostName(),
BootstrapServers = conf.GetValue<string>("Kafka:BootstrapServers"),
// 确保消息发送可靠
Acks = Acks.All,
EnableIdempotence = true,
MessageSendMaxRetries = conf.GetValue<int>("Kafka:Producer:MessageSendMaxRetries"),
RequestTimeoutMs = conf.GetValue<int>("Kafka:Producer:RequestTimeoutMs"),
// 消息体大小
CompressionType = conf.GetValue<CompressionType>("Kafka:Producer:CompressionType"),
CompressionLevel = conf.GetValue<int>("Kafka:Producer:CompressionLevel"),
// 消息发送速率控制(任意一条件先达到就发送)
LingerMs = conf.GetValue<int>("Kafka:Producer:LingerMs"),
BatchSize = conf.GetValue<int>("Kafka:Producer:BatchSize"),
BatchNumMessages = conf.GetValue<int>("Kafka:Producer:BatchNumMessages"),
// 发送缓冲内存限制
QueueBufferingMaxMessages = conf.GetValue<int>("Kafka:Producer:QueueBufferingMaxMessages"),
QueueBufferingMaxKbytes = conf.GetValue<int>("Kafka:Producer:QueueBufferingMaxKbytes"),
// 分区器 一致性hash/随机
Partitioner = conf.GetValue<Partitioner>("Kafka:Producer:Partitioner"),
// 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(_ =>

View File

@ -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))
{

View File

@ -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;

View File

@ -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,

View File

@ -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" />

View File

@ -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"]}" +

View File

@ -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>
/// 目的国家

View File

@ -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>
/// 班期

View File

@ -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

View File

@ -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

View File

@ -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>
/// 轨迹内容代码

View File

@ -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>
/// 源应用

View File

@ -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>
/// 标记代码

View File

@ -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

View File

@ -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)

View File

@ -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>
/// 推送单号类型

View File

@ -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>
/// 应用

View File

@ -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

View File

@ -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;
}
}
}