This commit is contained in:
xiaolipro 2024-07-31 18:21:23 +08:00
parent 8f8d7b2a44
commit ca68cde257
22 changed files with 271 additions and 253 deletions

View File

@ -2,17 +2,17 @@ namespace SJZY.Track.Application.Contract.Dtos.Forewarning;
public class WarningNotifyCacheEntry public class WarningNotifyCacheEntry
{ {
/// <summary>
/// 订单id
/// </summary>
public int OrderId { get; set; }
/// <summary> /// <summary>
/// 规则id /// 规则id
/// </summary> /// </summary>
public int RuleId { get; set; } public int RuleId { get; set; }
/// <summary>
/// 订单id
/// </summary>
public int OrderId { get; set; }
public WarningNotifyCacheEntry(int orderId, int ruleId) public WarningNotifyCacheEntry(int ruleId, int orderId)
{ {
RuleId = ruleId; RuleId = ruleId;
OrderId = orderId; OrderId = orderId;
@ -21,12 +21,12 @@ public class WarningNotifyCacheEntry
public WarningNotifyCacheEntry(string notifyValue) public WarningNotifyCacheEntry(string notifyValue)
{ {
var values = notifyValue.Split(':'); var values = notifyValue.Split(':');
OrderId = int.Parse(values[0]); RuleId = int.Parse(values[0]);
RuleId = int.Parse(values[1]); OrderId = int.Parse(values[1]);
} }
public override string ToString() public override string ToString()
{ {
return $"{OrderId}:{RuleId}"; return $"{RuleId}:{OrderId}";
} }
} }

View File

@ -7,6 +7,11 @@ public class WarningOrderDto
/// </summary> /// </summary>
public int Id { get; set; } public int Id { get; set; }
/// <summary>
/// 轨迹发生时间
/// </summary>
public DateTime TrackTime { get; set; }
public string? CargoType { get; set; } public string? CargoType { get; set; }
public int Month { get; set; } public int Month { get; set; }

View File

@ -19,6 +19,5 @@ public interface IForewarningNotifyService
/// <summary> /// <summary>
/// 发送通知。 /// 发送通知。
/// </summary> /// </summary>
/// <param name="intervalMinute">通知间隔时间,以分钟为单位。</param> Task SendNotificationAsync();
void SendNotification(int intervalMinute);
} }

View File

@ -125,6 +125,7 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
Orders = orders.Select(order => new WarningOrderDto Orders = orders.Select(order => new WarningOrderDto
{ {
Id = order.Id, Id = order.Id,
TrackTime = @event.TrackTime,
CargoType = order.CargoType, CargoType = order.CargoType,
Month = order.CreateTime.Month, Month = order.CreateTime.Month,

View File

@ -60,7 +60,9 @@ public class ForewarningHelper
for (var i = 0; i < repeat; i++, row++) for (var i = 0; i < repeat; i++, row++)
{ {
rules[row].StartTrackStatusId = span.StartTrackStatusId; rules[row].StartTrackStatusId = span.StartTrackStatusId;
rules[row].StartTrackStatus = span.StartTrackStatus;
rules[row].EndTrackStatusId = span.EndTrackStatusId; rules[row].EndTrackStatusId = span.EndTrackStatusId;
rules[row].EndTrackStatus = span.EndTrackStatus;
} }
} }
} }

View File

@ -1,13 +1,12 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using FreeRedis;
using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core;
using SJZY.Expand.ABP.Core.PublicMethords; using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Dtos.Forewarning; using SJZY.Track.Application.Contract.Dtos.Forewarning;
using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
using SJZY.Track.Domain.Aggregates.KPIAreaAggregate; using SJZY.Track.Domain.Aggregates.KPIAreaAggregate;
using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Dtos.Forewarning; using SJZY.Track.Domain.Dtos.Forewarning;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.ForewarningServices; namespace SJZY.Track.Application.Services.ForewarningServices;
@ -15,17 +14,17 @@ namespace SJZY.Track.Application.Services.ForewarningServices;
public class ForewarningCacheService : IForewarningCacheService, ISingletonDependency public class ForewarningCacheService : IForewarningCacheService, ISingletonDependency
{ {
readonly IKpiAreaRepository _kpiAreaRepository; readonly IKpiAreaRepository _kpiAreaRepository;
readonly IWarningRepository _warningRepository; private readonly IWarningQueries _warningQueries;
private const string GlobalWaningLockKey = "GlobalWaningLockKey_GlobalLock"; private const string GlobalWaningLockKey = "GlobalWaningLockKey_GlobalLock";
private readonly ConcurrentDictionary<string, List<ForewarningRuleCacheEntry>> _rules = new(); private readonly ConcurrentDictionary<string, List<ForewarningRuleCacheEntry>> _rules = new();
private readonly ConcurrentDictionary<int, List<AreaCacheEntry>> _areas = new(); private readonly ConcurrentDictionary<int, List<AreaCacheEntry>> _areas = new();
object _lock = new object(); object _lock = new object();
public ForewarningCacheService(IKpiAreaRepository kpiAreaRepository, IWarningRepository warningRepository) public ForewarningCacheService(IKpiAreaRepository kpiAreaRepository, IWarningQueries warningQueries)
{ {
_kpiAreaRepository = kpiAreaRepository; _kpiAreaRepository = kpiAreaRepository;
_warningRepository = warningRepository; _warningQueries = warningQueries;
} }
string WarningKey(int subSystemId, int customerId) => string WarningKey(int subSystemId, int customerId) =>
@ -105,7 +104,7 @@ public class ForewarningCacheService : IForewarningCacheService, ISingletonDepen
{ {
if (_rules.TryGetValue(key, out var ruleResult)) return ruleResult; if (_rules.TryGetValue(key, out var ruleResult)) return ruleResult;
var warnings = await _warningRepository.GetWarningRule(systemId, customerId); var warnings = await _warningQueries.GetWarningRule(systemId, customerId);
if (warnings == null || warnings.Count == 0) if (warnings == null || warnings.Count == 0)
{ {
RedisHelper.Client.Set(key, new List<WarningRuleCacheDto>(), TimeSpan.FromSeconds(20)); RedisHelper.Client.Set(key, new List<WarningRuleCacheDto>(), TimeSpan.FromSeconds(20));
@ -202,7 +201,7 @@ public class ForewarningCacheService : IForewarningCacheService, ISingletonDepen
public async Task ClearRedisByAreaId(int areaId) public async Task ClearRedisByAreaId(int areaId)
{ {
var baseInfos = await _warningRepository.GetWarningRuleByAreaId(areaId); var baseInfos = await _warningQueries.GetWarningRuleByAreaId(areaId);
if(baseInfos==null||baseInfos.Count==0) return; if(baseInfos==null||baseInfos.Count==0) return;
baseInfos = baseInfos.DistinctBy(val => WarningKey(val.SystemId, val.CustomerId)).ToList(); baseInfos = baseInfos.DistinctBy(val => WarningKey(val.SystemId, val.CustomerId)).ToList();

View File

@ -2,7 +2,9 @@ using FreeRedis;
using SJZY.Expand.ABP.Core; using SJZY.Expand.ABP.Core;
using SJZY.Track.Application.Contract.Dtos.Forewarning; using SJZY.Track.Application.Contract.Dtos.Forewarning;
using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.Services.ForewarningServices; namespace SJZY.Track.Application.Services.ForewarningServices;
@ -12,11 +14,13 @@ namespace SJZY.Track.Application.Services.ForewarningServices;
/// </summary> /// </summary>
public class ForewarningNotifyService : IForewarningNotifyService, ITransientDependency public class ForewarningNotifyService : IForewarningNotifyService, ITransientDependency
{ {
private readonly ForewarningCacheService _cacheService; private readonly IForewarningCacheService _cacheService;
private readonly IWarningQueries _warningQueries;
public ForewarningNotifyService(ForewarningCacheService cacheService) public ForewarningNotifyService(IForewarningCacheService cacheService, IWarningQueries warningQueries)
{ {
_cacheService = cacheService; _cacheService = cacheService;
_warningQueries = warningQueries;
} }
/// <summary> /// <summary>
@ -31,8 +35,8 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
var rules = await _cacheService.GetRulesAsync(dto.SubSystemId, dto.CustomerId); var rules = await _cacheService.GetRulesAsync(dto.SubSystemId, dto.CustomerId);
if (rules == null || rules.Count == 0) return; if (rules == null || rules.Count == 0) return;
var zMembers = new List<ZMember>(); var adds = new List<(int ruleId, int orderId, int cnt, long ts)>();
var members = new List<string>(); var dels = new List<(int ruleId, int orderId)>();
foreach (var order in dto.Orders) foreach (var order in dto.Orders)
{ {
MatchRule( MatchRule(
@ -40,33 +44,28 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
order order
).ForEach(rule => ).ForEach(rule =>
{ {
var notifyTimestamp = GetTimestamp(DateTime.Now.AddMinutes(rule.WarnTimeSpan)); var timestamp = GetTimestamp(order.TrackTime.AddMinutes(rule.WarnTimeSpan));
var entry = new WarningNotifyCacheEntry(rule.Id, order.Id); adds.Add((rule.Id, order.Id, rule.WarnCount, timestamp));
var notifyValue = new ZMember(entry.ToString(), notifyTimestamp);
zMembers.Add(notifyValue);
}); });
var endingRules = MatchRule( MatchRule(
rules.Where(rule => rule.EndTrackStatusId == dto.TrackStatusId).ToList(), rules.Where(rule => rule.EndTrackStatusId == dto.TrackStatusId).ToList(),
order order
); ).ForEach(rule => { dels.Add((rule.Id, order.Id)); });
foreach (var member in endingRules.Select(rule =>
new WarningNotifyCacheEntry(rule.Id, order.Id).ToString())
)
{
// todo: pipeline optimize?
var score = await RedisHelper.Client.ZScoreAsync(GlobalConst.ForewarningNotifyKey, member);
// tips: score is null 说明发生ending时,没有匹配到规则,所以没有add到set,不需要删除
if (score != null && (long)score > GetTimestamp(DateTime.Now))
{
members.Add(member);
}
}
} }
await RedisHelper.Client.ZAddAsync(GlobalConst.ForewarningNotifyKey, zMembers.ToArray());
await RedisHelper.Client.ZRemAsync(GlobalConst.ForewarningNotifyKey, members.ToArray()); await RedisHelper.Client.HSetAsync(GlobalConst.ForewarningNotifyCntKey,
adds.ToDictionary(x => $"{x.ruleId}_{x.orderId}", x => x.cnt));
await RedisHelper.Client.ZAddAsync(GlobalConst.ForewarningNotifyKey, adds.Select(x =>
{
var entry = new WarningNotifyCacheEntry(x.ruleId, x.orderId);
return new ZMember(entry.ToString(), x.ts);
}).ToArray());
await RedisHelper.Client.HDelAsync(GlobalConst.ForewarningNotifyCntKey,
dels.Select(x => $"{x.ruleId}_{x.orderId}").ToArray());
// await RedisHelper.Client.ZRemAsync(GlobalConst.ForewarningNotifyKey,
// dels.Select(x => $"{x.ruleId}:{x.orderId}").ToArray());
} }
private static List<ForewarningRuleCacheEntry> MatchRule(List<ForewarningRuleCacheEntry> rules, private static List<ForewarningRuleCacheEntry> MatchRule(List<ForewarningRuleCacheEntry> rules,
@ -118,17 +117,20 @@ public class ForewarningNotifyService : IForewarningNotifyService, ITransientDep
return res; return res;
} }
public void SendNotification(int intervalMinute) public async Task SendNotificationAsync()
{ {
var currentTimestamp = GetTimestamp(DateTime.Now); var max = GetTimestamp(DateTime.Now);
var notifyMembers = var set = await RedisHelper.Client.ZRangeByScoreAsync(GlobalConst.ForewarningNotifyKey, 0, max);
RedisHelper.Client.ZRangeByScore(GlobalConst.ForewarningNotifyKey, 0, currentTimestamp);
if (notifyMembers == null || notifyMembers.Length == 0) if (set.IsNullOrEmpty()) return;
return;
var notifyValues = notifyMembers.Select(val => new WarningNotifyCacheEntry(val)); var entries = set.Select(x => new WarningNotifyCacheEntry(x)).ToList();
foreach (var notifyValue in notifyValues) var ruleIds = entries.Select(x => x.RuleId).ToList();
var notifyRules = await _warningQueries.GetWarningNotifyRulesAsync(ruleIds);
foreach (var group in notifyRules)
{ {
} }
} }

View File

@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using SJZY.Track.Application.Contract.Dtos.Common; using SJZY.Track.Application.Contract.Dtos.Common;
using SJZY.Track.Application.Contract.Dtos.Forewarning; using SJZY.Track.Application.Contract.Dtos.Forewarning;
using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Application.Helpers; using SJZY.Track.Application.Helpers;
using SJZY.Track.Domain.Aggregates.ForewarningAggregate; using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate; using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
@ -15,10 +16,12 @@ namespace SJZY.Track.Application.Services.ForewarningServices;
public class ForewarningService : ApplicationService public class ForewarningService : ApplicationService
{ {
private readonly IWarningRepository _warningRepository; private readonly IWarningRepository _warningRepository;
private readonly IForewarningCacheService _forewarningCacheService;
public ForewarningService(IWarningRepository warningRepository) public ForewarningService(IWarningRepository warningRepository, IForewarningCacheService forewarningCacheService)
{ {
_warningRepository = warningRepository; _warningRepository = warningRepository;
_forewarningCacheService = forewarningCacheService;
} }
/// <summary> /// <summary>
@ -115,7 +118,7 @@ public class ForewarningService : ApplicationService
}).ToList(); }).ToList();
await _warningRepository.UpdateForewarningAsync(warning); await _warningRepository.UpdateForewarningAsync(warning);
return true; return true;
} }
@ -145,7 +148,12 @@ public class ForewarningService : ApplicationService
warning.SetEnable(isEnable); warning.SetEnable(isEnable);
return await _warningRepository.TurnWarningAsync(warning); await _warningRepository.TurnWarningAsync(warning);
// 清除缓存
await _forewarningCacheService.DeleteRulesAsync(warning.SubSystemId, warning.CustomerId);
return true;
} }
/// <summary> /// <summary>
@ -174,17 +182,20 @@ public class ForewarningService : ApplicationService
[HttpPost("ModifyTimeSpans")] [HttpPost("ModifyTimeSpans")]
public async Task<bool> ModifyTimeSpans(ModifyTimeSpanInput input) public async Task<bool> ModifyTimeSpans(ModifyTimeSpanInput input)
{ {
if (!await _warningRepository.IsAnyAsync(x => x.Id == input.WarningId)) if (input.Items.IsNullOrEmpty()) return false;
var warning = await _warningRepository.GetFirstAsync(x => x.Id == input.WarningId);
if (warning == null)
{ {
throw new BusinessException(message: "预警不存在"); throw new BusinessException(message: "预警不存在");
} }
if (input.Items.IsNullOrEmpty()) return false;
var warningRules = ObjectMapper.Map<List<WarningTimeSpanDto>, List<WarningRuleEntity>>(input.Items); var warningRules = ObjectMapper.Map<List<WarningTimeSpanDto>, List<WarningRuleEntity>>(input.Items);
await _warningRepository.ModifyTimeSpansAsync(warningRules); await _warningRepository.ModifyTimeSpansAsync(warningRules);
// 清除缓存
await _forewarningCacheService.DeleteRulesAsync(warning.SubSystemId, warning.CustomerId);
return true; return true;
} }
} }

View File

@ -59,18 +59,4 @@ public interface IWarningRepository : IBasicRepository<WarningEntity>
/// <param name="warningId"></param> /// <param name="warningId"></param>
/// <returns></returns> /// <returns></returns>
Task<WarningEntity?> GetByIdAsync(int warningId); Task<WarningEntity?> GetByIdAsync(int warningId);
/// <summary>
/// 获取预警规则列表
/// </summary>
/// <returns></returns>
Task<List<WarningRuleCacheDto>?> GetWarningRule(int systemId, int customerId);
/// <summary>
/// 获取预警规则基础信息
/// </summary>
/// <param name="areaId"></param>
/// <returns></returns>
Task<List<RuleAreaBaseInfo>?> GetWarningRuleByAreaId(int areaId);
} }

View File

@ -36,14 +36,26 @@ public class WarningRuleEntity : IFullAuditedBasicEntitys, IEntity
/// <summary> /// <summary>
/// 起始轨迹状态id /// 起始轨迹状态id
/// </summary> /// </summary>
[SugarColumn(ColumnName = "StartTrackStatusId", IsNullable = false)] [SugarColumn(ColumnName = "StartTrackStatusId")]
public int StartTrackStatusId { get; set; } public int StartTrackStatusId { get; set; }
/// <summary>
/// 起始轨迹状态(冗余)
/// </summary>
[SugarColumn(ColumnName = "StartTrackStatusId")]
public string StartTrackStatus { get; set; } = null!;
/// <summary> /// <summary>
/// 终止轨迹状态id /// 终止轨迹状态id
/// </summary> /// </summary>
[SugarColumn(ColumnName = "EndTrackStatusId", IsNullable = false)] [SugarColumn(ColumnName = "EndTrackStatusId")]
public int EndTrackStatusId { get; set; } public int EndTrackStatusId { get; set; }
/// <summary>
/// 终止轨迹状态(冗余)
/// </summary>
[SugarColumn(ColumnName = "EndTrackStatus")]
public string EndTrackStatus { get; set; } = null!;
/// <summary> /// <summary>
/// 货物类型 /// 货物类型

View File

@ -27,6 +27,11 @@ public partial class GlobalConst
/// </summary> /// </summary>
public const string ForewarningNotifyKey = "ForewarningNotify"; public const string ForewarningNotifyKey = "ForewarningNotify";
/// <summary>
/// 预警通知剩余次数redis key
/// </summary>
public const string ForewarningNotifyCntKey = "ForewarningNotifyCnt";
/// <summary> /// <summary>
/// kpi区域redis key前缀 /// kpi区域redis key前缀
/// </summary> /// </summary>

View File

@ -0,0 +1,69 @@
namespace SJZY.Track.Domain.Dtos.Forewarning;
public class GetWarningNotifiesVo
{
/// <summary>
/// rule id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 预警名称
/// </summary>
public string WarningName { get; set; } = null!;
/// <summary>
/// 时效(小时)
/// </summary>
public float TotalTimeSpan { get; set; }
/// <summary>
/// 提醒的时间(小时)
/// </summary>
public float WarnTimeSpan { get; set; }
/// <summary>
/// 提醒次数
/// </summary>
public int WarnCount { get; set; }
/// <summary>
/// 起始轨迹状态(冗余)
/// </summary>
public string StartTrackStatus { get; set; } = null!;
/// <summary>
/// 终止轨迹状态(冗余)
/// </summary>
public string EndTrackStatus { get; set; } = null!;
/// <summary>
/// 货物类型
/// </summary>
public string? CargoType { get; set; }
/// <summary>
/// 月份
/// </summary>
public string? Months { get; set; }
/// <summary>
/// 区域
/// </summary>
public string? AreaName { get; set; }
/// <summary>
/// 是否中转
/// </summary>
public bool? IsTransit { get; set; }
/// <summary>
/// 起运港口
/// </summary>
public string? LeavePort { get; set; }
/// <summary>
/// 产品编码
/// </summary>
public string? ProductCode { get; set; }
}

View File

@ -0,0 +1,27 @@
using SJZY.Track.Domain.Dtos.Forewarning;
namespace SJZY.Track.Domain.Queries;
public interface IWarningQueries
{
/// <summary>
/// 获取预警通知数据
/// </summary>
/// <param name="ruleIds"></param>
/// <returns></returns>
Task<List<GetWarningNotifiesVo>> GetWarningNotifyRulesAsync(List<int> ruleIds);
/// <summary>
/// 获取预警规则列表
/// </summary>
/// <returns></returns>
Task<List<WarningRuleCacheDto>?> GetWarningRule(int systemId, int customerId);
/// <summary>
/// 获取预警规则基础信息
/// </summary>
/// <param name="areaId"></param>
/// <returns></returns>
Task<List<RuleAreaBaseInfo>?> GetWarningRuleByAreaId(int areaId);
}

View File

@ -0,0 +1,66 @@
using SJZY.Track.Domain.Aggregates.ForewarningAggregate;
using SJZY.Track.Domain.Dtos.Forewarning;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Repository.Queries;
public class WarningQueries : ISugarRepository, IWarningQueries,
ITransientDependency
{
public ISqlSugarClient Context { get; set; }
public WarningQueries()
{
Context = SqlsugarScopeBasic.GetContextSafely("default");
}
public async Task<List<GetWarningNotifiesVo>> GetWarningNotifyRulesAsync(List<int> ruleIds)
{
return await Context.Queryable<WarningEntity>()
.LeftJoin<WarningRuleEntity>((a, b) => a.Id == b.WarningId)
.LeftJoin<WarningNotifyEntity>((a, b, c) =>
b.WarningId == c.WarningId && b.StartTrackStatusId == c.StartTrackStatusId &&
b.EndTrackStatusId == c.EndTrackStatusId)
.Where((a, b) => ruleIds.Contains(b.Id))
.Select<GetWarningNotifiesVo>((a, b, c) => new GetWarningNotifiesVo
{
WarningName = a.Name
}, true)
.ToListAsync();
}
public Task<List<WarningRuleCacheDto>?> GetWarningRule(int systemId, int customerId)
{
return Context.Queryable<WarningRuleEntity>()
.InnerJoin<WarningEntity>((a, b) => a.WarningId == b.Id)
.Where((a, b) => b.IsEnable && b.SubSystemId == systemId && b.CustomerId == customerId)
.Select((a, b) => new WarningRuleCacheDto
{
Id = a.Id,
WarningId = a.WarningId,
TotalTimeSpan = a.TotalTimeSpan,
WarnTimeSpan = a.WarnTimeSpan,
WarnCount = a.WarnCount,
StartTrackStatusId = a.StartTrackStatusId,
EndTrackStatusId = a.EndTrackStatusId,
CargoType = a.CargoType,
Months = a.Months,
AreaId = a.AreaId,
IsTransit = a.IsTransit,
LeavePort = a.LeavePort,
ProductCode = a.ProductCode,
CustomerId = b.CustomerId,
SystemId = b.SubSystemId
})
.ToListAsync();
}
public Task<List<RuleAreaBaseInfo>?> GetWarningRuleByAreaId(int areaId)
{
return Context.Queryable<WarningRuleEntity>()
.InnerJoin<WarningEntity>((a, b) => a.WarningId == b.Id)
.Where((a, b) => b.IsEnable && a.AreaId == areaId)
.Select((a, b) => new RuleAreaBaseInfo(b.CustomerId, b.SubSystemId))
.ToListAsync();
}
}

View File

@ -109,40 +109,4 @@ public class WarningRepository : BasicRepository<WarningEntity>, IWarningReposit
return warning; return warning;
} }
public Task<List<WarningRuleCacheDto>?> GetWarningRule(int systemId, int customerId)
{
return Context.Queryable<WarningRuleEntity>()
.InnerJoin<WarningEntity>((a, b) => a.WarningId == b.Id)
.Where((a,b)=>b.IsEnable && b.SubSystemId == systemId && b.CustomerId == customerId)
.Select((a,b)=>new WarningRuleCacheDto
{
Id = a.Id,
WarningId = a.WarningId,
TotalTimeSpan = a.TotalTimeSpan,
WarnTimeSpan = a.WarnTimeSpan,
WarnCount = a.WarnCount,
StartTrackStatusId = a.StartTrackStatusId,
EndTrackStatusId = a.EndTrackStatusId,
CargoType = a.CargoType,
Months = a.Months,
AreaId = a.AreaId,
IsTransit = a.IsTransit,
LeavePort = a.LeavePort,
ProductCode = a.ProductCode,
CustomerId = b.CustomerId,
SystemId = b.SubSystemId
})
.ToListAsync();
}
public Task<List<RuleAreaBaseInfo>?> GetWarningRuleByAreaId(int areaId)
{
return Context.Queryable<WarningRuleEntity>()
.InnerJoin<WarningEntity>((a, b) => a.WarningId == b.Id)
.Where((a,b)=>b.IsEnable && a.AreaId==areaId)
.Select((a,b)=>new RuleAreaBaseInfo(b.CustomerId,b.SubSystemId))
.ToListAsync();
}
} }

View File

@ -17,4 +17,16 @@
<ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" /> <ProjectReference Include="..\SJZY.Track.Domain\SJZY.Track.Domain.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="TrackPushRecordDetails\Entitys\" />
<Folder Include="TrackPushRecordDetails\Services\" />
<Folder Include="TrackPushRecord\Entitys\" />
<Folder Include="TrackPushRecord\Services\" />
</ItemGroup>
<ItemGroup>
<Compile Remove="TrackPushRecord\Entitys\TrackPushRecordEntity.cs" />
<Compile Remove="TrackPushRecord\Services\ITrackPushRecordRepository.cs" />
</ItemGroup>
</Project> </Project>

View File

@ -1,59 +0,0 @@
using SJZY.Track.Domain.SeedWork;
namespace SJZY.Track.Repository.TrackPushRecord.Entitys
{
/// <summary>
/// 轨迹推送记录
/// </summary>
[SugarTable("t_track_push_record")]
public class TrackPushRecordEntity : IAggregateRoot
{
/// <summary>
/// 自增主键
/// </summary>
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 创建时间(推送时间)
/// </summary>
[SugarColumn(ColumnName = "CreateTime")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 创建人(推送人)
/// </summary>
[SugarColumn(ColumnName = "CreateUserId")]
public int CreateUserId { get; set; }
/// <summary>
/// 是否自动推送
/// </summary>
[SugarColumn(ColumnName = "IsAutoPush")]
public bool IsAutoPush { get; set; }
/// <summary>
/// 推送内容
/// </summary>
[SugarColumn(ColumnName = "PushContent")]
public string PushContent { get; set; } = null!;
/// <summary>
/// 接口通请求id
/// </summary>
[SugarColumn(ColumnName = "RequestId")]
public string RequestId { get; set; } = null!;
/// <summary>
/// 服务商id
/// </summary>
[SugarColumn(ColumnName = "ServiceProviderId")]
public int ServiceProviderId { get; set; }
/// <summary>
/// 推送轨迹总数
/// </summary>
[SugarColumn(ColumnName = "TrackTotal")]
public int TrackTotal { get; set; }
}
}

View File

@ -1,8 +0,0 @@
using SJZY.Track.Repository.TrackPushRecord.Entitys;
namespace SJZY.Track.Repository.TrackPushRecord.Services
{
public interface ITrackPushRecordRepository : ISimpleClient<TrackPushRecordEntity>
{
}
}

View File

@ -1,10 +0,0 @@
using SJZY.Track.Repository.Repositories;
using SJZY.Track.Repository.TrackPushRecord.Entitys;
namespace SJZY.Track.Repository.TrackPushRecord.Services
{
public class TrackPushRecordRepository : BasicRepository<TrackPushRecordEntity>, ITrackPushRecordRepository, IScopedDependency
{
}
}

View File

@ -1,47 +0,0 @@
using SJZY.Track.Domain.SeedWork;
namespace SJZY.Track.Repository.TrackPushRecordDetails.Entitys
{
/// <summary>
/// 轨迹推送明细表
/// </summary>
[SugarTable("t_track_push_record_details")]
public class TrackPushRecordDetailsEntity : IAggregateRoot
{
/// <summary>
/// 自增主键
/// </summary>
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 创建时间(消费完成时间)
/// </summary>
[SugarColumn(ColumnName = "CreateTime")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 异常信息
/// </summary>
[SugarColumn(ColumnName = "ErrorMessage")]
public string ErrorMessage { get; set; }
/// <summary>
/// 是否成功
/// </summary>
[SugarColumn(ColumnName = "IsSuccess")]
public bool IsSuccess { get; set; }
/// <summary>
/// 订单id
/// </summary>
[SugarColumn(ColumnName = "OrderId")]
public int OrderId { get; set; }
/// <summary>
/// 推送记录id
/// </summary>
[SugarColumn(ColumnName = "PushRecordId")]
public int PushRecordId { get; set; }
}
}

View File

@ -1,8 +0,0 @@
using SJZY.Track.Repository.TrackPushRecordDetails.Entitys;
namespace SJZY.Track.Repository.TrackPushRecordDetails.Services
{
public interface ITrackPushRecordDetailsRepository : ISimpleClient<TrackPushRecordDetailsEntity>
{
}
}

View File

@ -1,10 +0,0 @@
using SJZY.Track.Repository.Repositories;
using SJZY.Track.Repository.TrackPushRecordDetails.Entitys;
namespace SJZY.Track.Repository.TrackPushRecordDetails.Services
{
public class TrackPushRecordDetailsRepository : BasicRepository<TrackPushRecordDetailsEntity>, ITrackPushRecordDetailsRepository, IScopedDependency
{
}
}