using System.Collections.Immutable; using System.Text; using Nest; using SJZY.Expand.ElasticSearch; using SJZY.Track.Domain.Aggregates.KPIAreaAggregate; using SJZY.Track.Domain.Consts; namespace SJZY.Track.Domain.Aggregates.WarningAggregate.Transport; // 运输时效预警明细 [ElasticsearchType(RelationName = GlobalConst.TransportWarningDetailsIndex)] public sealed class TransportWarningDetailsIndex : IdBaseIndex { public string IndexName { get; set; } public int WarningId { get; set; } public int WarningSceneId { get; set; } public int WarningSceneRuleItemId { get; set; } public string Version { get; set; } //预警版本号 public string WarningName { get; set; } //(冗余)预警规则名称,规则主体名称 public string WarningRuleDescription { get; set; } // 预警规则描述 (场景+场景规则项目构建) public float TransportTimeSpan { get; set; } //时效 (单位小时),用于计算状态 public float StartTrackWarningTimeSpan { get; set; } //起始轨迹生成预警时间 (单位小时),用于计算状态 //public string NotifyModes { get; set; } //通知方式,多个方式(,)分割 eg: 1,2 public string NotifyUsers { get; set; } //通知人Json eg: [{"UserId":1,"UserName":"张三"},{"UserId":2,"UserName":"李四"}] //订单信息 public int SubSystemId { get; set; } //(冗余)子系统Id // public string SubSystemName { get; set; } //(冗余)子系统名称 public int CustomId { get; set; } //(冗余)客户Id // public string CustomName { get; set; } //冗余 客户简称(用于查询条件) public int OrderId { get; set; } public string OrderNo { get; set; } //订单号 public int OrderType { get; set; } //(冗余)订单类型 // public string OrderTypeName { get; set; } //(冗余)订单类型名称 //轨迹信息-起始(更新用例:新增轨迹时,场景/规则项变更并且重新命中) public int StartTrackStatusId { get; set; } //起始轨迹状态Id public string StartTrackStatus { get; set; } //(冗余)起始轨迹状态名称 public int StartTrackContentId { get; set; } //起始轨迹内容Id public string StartTrackContent { get; set; } //(冗余)起始轨迹内容名称 public DateTime StartTrackTime { get; set; } //起始轨迹发生时间 public float StartTrackTimeZone { get; set; } //起始轨迹发生时区 //轨迹信息-截止(更新用例:新增轨迹时) public int EndTrackStatusId { get; set; } //截止轨迹状态Id public string EndTrackStatus { get; set; } //(冗余)截止轨迹状态名称 public int? EndTrackContentId { get; set; } //截止轨迹内容Id public string? EndTrackContent { get; set; } //(冗余)截止轨迹内容名称 public DateTime? EndTrackTime { get; set; } //截止轨迹发生时间 public float? EndTrackTimeZone { get; set; } //截止轨迹发生时区 // // 实时属性vo // public int LatestTrackContentId { get; set; } //最新轨迹内容Id // public string LatestTrackContent { get; set; } //(冗余)最新轨迹内容名称 // public DateTime LatestTrackTime { get; set; } //最新轨迹发生时间 // public float LatestTrackTimeZone { get; set; } //最新轨迹发生时区 // public string LatestTrackPlace { get; set; } //最新轨迹发生地 //计算属性 public long CumulativeTimeSpan { get; set; } //累计运输时间:当前时间-起始轨迹状态中的最早轨迹发生时间(利用 轨迹信息-起始 完成计算)单位(毫秒) public int Status { get; set; } //1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】 //审计属性 public DateTime CreateTime { get; set; } //预警创建时间 private static readonly ImmutableHashSet CompletedStatus = ImmutableHashSet.Create(3, 4, 5); public bool CanCompleted() => CompletedStatus.Contains(Status); public long CalcCumulativeTimeSpan() { return (long)DateTime.Now.Subtract(StartTrackTime).TotalMilliseconds; } // tips:计算并设置状态,后续维护到vo当中 public int CalcStatus() { // 结束态无需计算,直接返回 if (CompletedStatus.Contains(Status)) return Status; //时效 var transportTimeSpan = TimeSpan.FromHours(TransportTimeSpan); //小时 //累计运输时间 var cumulativeTimeSpan = TimeSpan.FromMilliseconds(CumulativeTimeSpan); //毫秒 //预警时效(预警发出的时间对比于最早轨迹状态时间的跨度) var startTrackWarningTimeSpan = TimeSpan.FromHours(StartTrackWarningTimeSpan); //小时 //时效>累计运输时间>=预警时效 状态调整为【即将超时】 if (transportTimeSpan > cumulativeTimeSpan && cumulativeTimeSpan >= startTrackWarningTimeSpan) return Status = 1; //时效<累计运输时间 状态调整为【已超时】 if (transportTimeSpan < cumulativeTimeSpan) return Status = 2; return Status; } // 预警规则描述,创建预警明细,更新场景(需要重新匹配),更新规则项目(需要重新匹配),更新规则区域名称 // todo:缺失更新规则区域名称目前不被感知,出现预警明细和对于的规则区域名称不一致 // todo:转化为bo的使用 public string GetWarningRuleDescription(TransportWarningSceneEntity scene, TransportWarningSceneRuleItemEntity ruleItem, RuleAreaEntity? ruleArea) { var res = new StringBuilder("{"); // 起始轨迹状态-截止轨迹状态 res.Append($"{StartTrackStatus}-{EndTrackStatus}"); // 货物类型 (普货/危险品/...) if (!string.IsNullOrWhiteSpace(scene.CargoType)) res.Append($",{scene.CargoType}"); // 月份 (1/3/5/...) if (!string.IsNullOrWhiteSpace(scene.Months)) res.Append($",{scene.Months}月份"); // 区域名称 (美国xxx区域) if (ruleArea != null) res.Append($",{ruleArea.Name}"); // 是否中转(中转/直飞) if (scene.IsTransit != null) res.Append($",{(scene.IsTransit ?? false ? "中转" : "直飞")}"); // 出发港(xxx港) if (!string.IsNullOrWhiteSpace(scene.LeavePort)) res.Append($",{scene.LeavePort}"); // 产品代码(xxx) if (!string.IsNullOrWhiteSpace(scene.ProductCode)) res.Append($",{scene.ProductCode}"); // 规则配置信息 res.Append($",生成预警时间{ruleItem.StartTrackWarningTimeSpan}小时" + $",提醒时效{ruleItem.TransportTimeSpan}}}"); return res.ToString(); } public DateTime GetUtc0StartTrackTime() { return Math.Abs(StartTrackTimeZone - GlobalConst.NoneTrackTimeZone) < 0.01f ? StartTrackTime : StartTrackTime.Subtract(TimeSpan.FromHours(StartTrackTimeZone)); } public DateTime? GetUtc0EndTrackTime() { if (EndTrackTime == null || EndTrackTimeZone == null) return null; return Math.Abs(EndTrackTimeZone.Value - GlobalConst.NoneTrackTimeZone) < 0.01f ? EndTrackTime : EndTrackTime.Value.Subtract(TimeSpan.FromHours(EndTrackTimeZone.Value)); } }