track/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs
hardstylewyl d585f799bd fix: 修复查询轨迹内容时缺失是否对外字段,导致的新增/修改轨迹,中的轨迹明细缺省值错误
fix: 修复中台内部查询轨迹明细接口,中的是否对外标识错误
2025-02-10 15:36:57 +08:00

310 lines
12 KiB
C#

using System.Linq.Expressions;
using SJZY.Expand.AliyunOSS;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Dtos.TrackOrder;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.Order;
namespace SJZY.Track.Application.Services.TrackOrders;
/// <summary>
/// 轨迹订单服务
/// </summary>
[ApiExplorerSettings(GroupName = "轨迹订单")]
[Route("/Track/Order")]
public class TrackOrderService : ApplicationService
{
private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
private readonly IOrderRepository _orderRepository;
private readonly ITrackContentRepository _trackContentRepository;
private readonly ITrackStatusRepository _trackStatusRepository;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
public TrackOrderService(
IOrderRepository orderRepository,
ITrackDetailsEsRepository trackDetailsEsRepository,
ITrackContentRepository trackContentRepository,
ITrackPushRecordEsRepository trackPushRecordEsRepository,
IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
ITrackStatusRepository trackStatusRepository)
{
_orderRepository = orderRepository;
_trackDetailsEsRepository = trackDetailsEsRepository;
_trackContentRepository = trackContentRepository;
_trackPushRecordEsRepository = trackPushRecordEsRepository;
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
_trackStatusRepository = trackStatusRepository;
}
#region 轨迹订单列表
/// <summary>
/// 获取分页的轨迹订单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetTrackOrderList")]
public async Task<UnifyPageResultDto<TrackOrderDto>> GetTrackOrderPagedList(GetPageTrackOrderInput input)
{
var vo = ObjectMapper.Map<GetPageTrackOrderInput, GetPageTrackOrderInputVO>(input);
var pageList = await _orderRepository.GetTrackOrderPagedList(vo);
var pageResultDto =
ObjectMapper.Map<UnifyPageResultDto<TrackOrderVO>, UnifyPageResultDto<TrackOrderDto>>(pageList);
return pageResultDto;
}
#endregion
/// <summary>
/// 更新订单状态
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("UpdateOrderStatus")]
public async Task<bool> UpdateOrderStatus(UpdateOrderStatusInput input)
{
var order = await _orderRepository.GetFirstAsync(x => x.Id == input.OrderId);
if (order == default) throw new BusinessException(message: "订单不存在");
order.IsCompleted = input.IsCompleted;
return await _orderRepository.UpdateColumnAsync(order, x => new
{
x.IsCompleted
});
}
/// <summary>
/// 获取轨迹推送记录
/// </summary>
/// <returns></returns>
/// <param name="orderId">订单id</param>
[HttpGet("GetTrackPushRecords")]
public async Task<List<TrackPushRecordOutput>> GetTrackPushRecordsAsync(int orderId)
{
var records = await _trackPushRecordEsRepository.GetTrackPushRecordsAsync(orderId);
var res = ObjectMapper.Map<List<TrackPushRecordIndex>, List<TrackPushRecordOutput>>(records);
res.ForEach(x =>
{
int hours = (int) x.TrackTimeZone; // 提取整数部分作为小时
int minutes = (int) ((x.TrackTimeZone - hours) * 60); // 将小数部分乘以 60 转换为分钟
x.TrackGTMTimeZone =
$"GMT {(x.TrackTimeZone >= 0 ? "+" : "-")}{new TimeSpan(hours, minutes, 0).ToString().RemovePostFix(":00")}";
});
return res;
}
/// <summary>
/// 根据订单id获取轨迹明细列表
/// </summary>
/// <param name="orderId"></param>
/// <param name="orderNo"></param>
/// <param name="systemId"></param>
/// <returns></returns>
[HttpPost("GetDetails")]
public async Task<List<TrackOrderDetailDto>> GetTracksAsync(int? orderId, string? orderNo, int? systemId)
{
Expression<Func<OrderEntity, bool>>? whereExpression = null;
//根据订单id查询
if (orderId != null && orderId > 0)
whereExpression = m => m.Id == orderId;
//根据订单号+系统id查询
if (!string.IsNullOrEmpty(orderNo) && systemId != null && systemId > 0)
whereExpression = m => m.OrderNo == orderNo && m.SubSystemId == systemId;
if (whereExpression == default)
throw new BusinessException(message: "请求参数异常");
var order = await _orderRepository.GetFirstAsync(whereExpression);
if (order == default)
{
throw new BusinessException(message: "订单不存在");
}
var trackDetails = await _trackDetailsEsRepository.GetListAsync(order.Id);
if (trackDetails.IsNullOrEmpty())
{
return new List<TrackOrderDetailDto>();
}
var list = ObjectMapper.Map<List<TrackDetailsIndex>, List<TrackOrderDetailDto>>(trackDetails);
// 计算时区
list.ForEach(a =>
{
if (a.TrackTimeZoneValue == 0f)
{
a.TrackTimeZone = "GMT +00:00";
}
else if (Math.Abs(a.TrackTimeZoneValue - GlobalConst.NoneTrackTimeZone) < 1)
{
a.TrackTimeZone = "--";
}
else
{
// 将小数形式的小时转换为时区偏移量
var hours = (int) a.TrackTimeZoneValue; // 提取整数部分作为小时
var minutes = (int) ((a.TrackTimeZoneValue - hours) * 60); // 将小数部分乘以 60 转换为分钟
var offset = new TimeSpan(hours, minutes, 0);
var timeZoneStr = offset.ToString();
var flag = a.TrackTimeZoneValue > 0f ? "+" : "";
a.TrackTimeZone = $"GMT {flag}{timeZoneStr.RemovePostFix(":00")}";
}
});
return list;
}
/// <summary>
/// 按时间轴获取轨迹内容
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("GetDetailTimeline")]
public async Task<UnifyResultDto<List<GetDetailTimelineOutput>>> GetDetailTimeline(GetDetailTimelineInput input)
{
var res = new UnifyResultDto<List<GetDetailTimelineOutput>>(true);
var order = await _orderRepository.GetFirstAsync(m => m.OrderNo == input.OrderNumber);
if (order == null)
return new UnifyResultDto<List<GetDetailTimelineOutput>>(false, "订单不存在");
if (input.SystemId <= 0)
return new UnifyResultDto<List<GetDetailTimelineOutput>>(false, "子系统id不合法");
if (input.CurrenUserSystemId <= 0)
return new UnifyResultDto<List<GetDetailTimelineOutput>>(false, "当前登陆用户子系统id不合法");
var system = await _orderRepository.GetSystemInfoById(input.CurrenUserSystemId);
if (system == null)
return new UnifyResultDto<List<GetDetailTimelineOutput>>(false, "未找到指定id的子系统");
var trackDetails = await _trackDetailsEsRepository.GetListAsync(order.Id);
//时间轴不显示轨迹内容为空的轨迹,进行过滤
trackDetails = trackDetails.Where(x => !x.TrackContent.IsNullOrWhiteSpace() && x.TrackContent != GlobalConst.EmptyString).ToList();
res.Data = new List<GetDetailTimelineOutput>();
foreach (var item in trackDetails)
{
//如果是外部系统,且轨迹内容不对外则跳过这条轨迹内容
if (system.SystemProperty == 2 && !item.IsExternal)
continue;
//时间和时区任意一个为空则使用创建时间做为排序参照值
var timeTick = ToUnixTimestamp((item.TrackTime == null
|| Math.Abs(item.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1)
? item.CreateTime
: item.TrackTime);
res.Data.Add(new GetDetailTimelineOutput()
{
IsHighlight = true,
IsShowHover = true,
Remark = item.Remarks == null || item.Remarks == "--" ? "" : item.Remarks,
TrackTimeZone = $"GMT{(item.TrackTimeZone >= 0 ? "+" : "-")}{GetTimeZoneStr(item.TrackTimeZone)}",
TrackTime = timeTick,
TrackPlace = item.TrackPlace,
EnContent = item.TrackEnContent,
Files = item.Files == null
? new List<TrackFileItem>()
: item.Files!.Select(m => new TrackFileItem()
{
OssKey = m.OssKey,
FileName = m.FileName,
Url = m.OssKey.GetUrlByKey(),
}).ToList(),
Content = item.TrackContent,
TrackCode = item.TrackCode,
TrackPlaceNation = item.TrackPlaceNation,
TrackPlaceProvince = item.TrackPlaceProvince,
TrackPlaceCity = item.TrackPlaceCity,
});
}
// 按轨迹发生时间正序排序
res.Data = res.Data.OrderBy(m => m.TrackTime).ToList();
if (!order.IsCompleted) //如果没完结则显示签收节点
{
var eddUnixTimestamp = order.EstimatedDeliveryDate.HasValue ? ToUnixTimestamp(DateTime.Parse(order.EstimatedDeliveryDate.ToString()!)) : 0;
var isShowTime = eddUnixTimestamp > 0 && res.Data.All(m => m.TrackTime < eddUnixTimestamp);
//当存在需要显示的轨迹才需要补充签收节点
if (res.Data.Count != 0)
{
res.Data.Add(new GetDetailTimelineOutput()
{
Content = "签收",
IsHighlight = false,
TrackTimeZone = isShowTime ? $"GMT{(order.DestinationTimeZone >= 0 ? "+" : "-")}{order.DestinationTimeZone}" : "",
TrackTime = isShowTime ? eddUnixTimestamp : 0,
TrackTimePrefix = isShowTime ? "预计签收时间:" : "",
});
}
}
return res;
}
public static long ToUnixTimestamp(DateTime time)
{
var sTime = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Utc, TimeZoneInfo.Local);
return (long) (time - sTime).TotalMilliseconds;
}
private string GetTimeZoneStr(float timeZone)
{
var time = timeZone.ToString().Split('.');
if (time.Length > 1 && time[1] != "0") //如果时区有小数点
{
return time[0] + ":30";
}
else
{
return time[0] + ":00";
}
}
/// <summary>
/// 根据轨迹id删除单条轨迹
/// </summary>
/// <param name="trackId">轨迹id</param>
/// <returns></returns>
[HttpPost("DeleteTrackById")]
public async Task<bool> DeleteTrackByIdAsync(string trackId)
{
var track = await _trackDetailsEsRepository.GetByIdAsync(trackId);
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (track == null)
{
throw new BusinessException(message: "轨迹不存在!");
}
await _trackDetailsEsRepository.DeleteTrackByIdAsync(trackId, track.IndexName);
return true;
}
/// <summary>
/// 根据订单id查询订单操作记录
/// </summary>
/// <param name="orderId">订单id</param>
/// <returns></returns>
[HttpGet("GetOrderOperationsById")]
public async Task<List<OrderOperationRecordIndex>> GetOrderOperationsByIdAsync(int orderId)
{
return await _orderOperationRecordEsRepository.GetOrderOperationsByIdAsync(orderId);
}
}