|
|
using Furion;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
using Furion.DynamicApiController;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Components;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Enum;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using Myshipping.Application.Service.TaskManagePlat;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Service;
|
|
|
using MySqlX.XDevAPI.Common;
|
|
|
using Newtonsoft.Json;
|
|
|
using NPOI.XWPF.UserModel;
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net.Http;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 预甩货通知
|
|
|
/// </summary>
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManageRollingNomination", Order = 10)]
|
|
|
public class TaskManageRollingNominationService : ITaskManageRollingNominationService, IDynamicApiController, ITransient
|
|
|
{
|
|
|
private readonly ISysCacheService _cache;
|
|
|
private readonly ILogger<TaskManageRollingNominationService> _logger;
|
|
|
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationInfo> _taskRollingNominationInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationShipInfo> _taskRollingNominationShipInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationDetailInfo> _taskRollingNominationDetailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationDispatchInfo> _taskRollingNominationDispatchInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskShareLinkInfo> _taskShareLinkInfoRepository;
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
|
|
|
private readonly SqlSugarRepository<BookingCtn> _bookingCtnRepository;
|
|
|
private readonly SqlSugarRepository<BookingPrintTemplate> _repPrintTemplate;
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
|
|
|
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
|
|
|
private readonly SqlSugarRepository<BookingOrderContact> _bookingOrderContactRepository;
|
|
|
private readonly IDjyTenantParamService _djyTenantParamService;
|
|
|
|
|
|
private readonly INamedServiceProvider<ITaskManageShareLinkService> _namedServiceProvider;
|
|
|
|
|
|
public TaskManageRollingNominationService(SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
|
|
|
SqlSugarRepository<TaskRollingNominationInfo> taskRollingNominationInfoRepository,
|
|
|
SqlSugarRepository<TaskRollingNominationDetailInfo> taskRollingNominationDetailInfoRepository,
|
|
|
SqlSugarRepository<TaskRollingNominationDispatchInfo> taskRollingNominationDispatchInfoRepository,
|
|
|
SqlSugarRepository<TaskRollingNominationShipInfo> taskRollingNominationShipInfoRepository,
|
|
|
SqlSugarRepository<TaskShareLinkInfo> taskShareLinkInfoRepository,
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository,
|
|
|
SqlSugarRepository<BookingPrintTemplate> repPrintTemplate,
|
|
|
SqlSugarRepository<SysUser> sysUserRepository,
|
|
|
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
|
|
|
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
|
|
|
INamedServiceProvider<ITaskManageShareLinkService> namedServiceProvider,
|
|
|
SqlSugarRepository<BookingCtn> bookingCtnRepository, ISysCacheService cache, ILogger<TaskManageRollingNominationService> logger,
|
|
|
IDjyTenantParamService djyTenantParamService)
|
|
|
{
|
|
|
_taskBaseRepository = taskBaseRepository;
|
|
|
_taskRollingNominationInfoRepository = taskRollingNominationInfoRepository;
|
|
|
_taskRollingNominationDetailInfoRepository = taskRollingNominationDetailInfoRepository;
|
|
|
_taskRollingNominationDispatchInfoRepository = taskRollingNominationDispatchInfoRepository;
|
|
|
_taskRollingNominationShipInfoRepository = taskRollingNominationShipInfoRepository;
|
|
|
_taskShareLinkInfoRepository = taskShareLinkInfoRepository;
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
_bookingCtnRepository = bookingCtnRepository;
|
|
|
_repPrintTemplate = repPrintTemplate;
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
_djyUserMailAccount = djyUserMailAccount;
|
|
|
_bookingOrderContactRepository = bookingOrderContactRepository;
|
|
|
|
|
|
_namedServiceProvider = namedServiceProvider;
|
|
|
_djyTenantParamService = djyTenantParamService;
|
|
|
|
|
|
_cache = cache;
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
#region 获取预甩详情
|
|
|
/// <summary>
|
|
|
/// 获取预甩详情
|
|
|
/// </summary>
|
|
|
/// <param name="pkId">预甩主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetInfo")]
|
|
|
public async Task<TaskRollingNominationShowDto> GetInfo(string pkId)
|
|
|
{
|
|
|
TaskRollingNominationShowDto model = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var rollModel = _taskRollingNominationInfoRepository.AsQueryable()
|
|
|
.First(a => a.PK_ID == pkId && !a.IsDeleted);
|
|
|
|
|
|
if (rollModel == null)
|
|
|
throw Oops.Oh($"预甩货主键{pkId}无法获取业务信息");
|
|
|
|
|
|
model = await InnerGetInfo(rollModel);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
|
|
|
|
|
|
throw ex;
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 通过任务主键获取预甩详情
|
|
|
/// <summary>
|
|
|
/// 通过任务主键获取预甩详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">预甩任务主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetInfoByTaskId")]
|
|
|
public async Task<TaskRollingNominationShowDto> GetInfoByTaskId(string taskPkId)
|
|
|
{
|
|
|
TaskRollingNominationShowDto model = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId && !a.IsDeleted);
|
|
|
|
|
|
if (taskBase == null)
|
|
|
throw Oops.Oh($"预甩货任务主键{taskPkId}无法获取任务信息");
|
|
|
|
|
|
var rollModel = _taskRollingNominationInfoRepository.AsQueryable()
|
|
|
.First(a => a.TASK_ID == taskBase.PK_ID && !a.IsDeleted);
|
|
|
|
|
|
if (rollModel == null)
|
|
|
throw Oops.Oh($"预甩货任务主键{taskBase.PK_ID}无法获取业务信息");
|
|
|
|
|
|
model = await InnerGetInfo(rollModel);
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
|
|
|
|
|
|
throw ex;
|
|
|
}
|
|
|
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取预甩详情
|
|
|
/// <summary>
|
|
|
/// 获取预甩详情
|
|
|
/// </summary>
|
|
|
/// <param name="rollModel">预甩货详情实体类</param>
|
|
|
/// <returns>返回详情</returns>
|
|
|
private async Task<TaskRollingNominationShowDto> InnerGetInfo(TaskRollingNominationInfo rollModel)
|
|
|
{
|
|
|
TaskRollingNominationShowDto model = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
List<string> rollingPlanList = new List<string>();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rollModel.PLAN_TXT))
|
|
|
{
|
|
|
rollingPlanList = rollModel.PLAN_TXT.Split("\\n").ToList();
|
|
|
}
|
|
|
|
|
|
model = new TaskRollingNominationShowDto
|
|
|
{
|
|
|
PlanType = rollModel.PLAN_TYPE,
|
|
|
CarrierId = rollModel.CARRIERID,
|
|
|
Carrier = rollModel.CARRIER,
|
|
|
ConfirmDeadLine = rollModel.CONFIRM_DEAD_LINE,
|
|
|
CreateTime = rollModel.READ_CREATE_TIME,
|
|
|
RollingTouchDoubleRollRemark = rollModel.ROLL_DOUBLE_REMARK,
|
|
|
LoadDetailList = new List<TaskRollingNominationShipDetailShowDto>(),
|
|
|
RollingPlanList = rollingPlanList,
|
|
|
PreBillList = new List<TaskRollingNominationShipPreBillShowDto>(),
|
|
|
NominationId = rollModel.PK_ID
|
|
|
};
|
|
|
|
|
|
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable()
|
|
|
.Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList();
|
|
|
|
|
|
var fromEntity = shipList.Where(a =>
|
|
|
a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
if (fromEntity.Count > 0)
|
|
|
model.From = fromEntity.Select(p=>p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE,"To(\\s+[0-9]+)?"
|
|
|
, RegexOptions.IgnoreCase)).ToList();
|
|
|
|
|
|
if (toEntity.Count > 0)
|
|
|
model.To = toEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
//优先PORT关联FROM和TO,也有PORT为空的情况,这种就需要用Terminal来关联
|
|
|
if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port)))
|
|
|
{
|
|
|
//这里为了前端原船和换船做了根据Terminal对应
|
|
|
model.FromToList = model.From.GroupJoin(model.To, l => l.Terminal?.Trim(), r => r.Terminal?.Trim(), (l, r) =>
|
|
|
{
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
{
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
{
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
}
|
|
|
|
|
|
return dto;
|
|
|
}).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//这里为了前端原船和换船做了根据PORT对应
|
|
|
model.FromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) =>
|
|
|
{
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
{
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
{
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
}
|
|
|
|
|
|
return dto;
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
List<Tuple<string, int>> tuples = new List<Tuple<string, int>>();
|
|
|
|
|
|
var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.LeftJoin<TaskRollingNominationDispatchInfo>((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID)
|
|
|
.Where((detail, dispatch) => detail.NOM_ID == rollModel.PK_ID && detail.IsDeleted == false
|
|
|
&& (string.IsNullOrWhiteSpace(dispatch.PK_ID) || (!string.IsNullOrWhiteSpace(dispatch.PK_ID) && dispatch.IsDeleted == false)))
|
|
|
.Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList();
|
|
|
|
|
|
if (withDispatchList.Count > 0)
|
|
|
{
|
|
|
model.PreBillList = withDispatchList.Where(a => !a.Detail.NOM_STATUS_NOTE.Equals("Load",StringComparison.OrdinalIgnoreCase))
|
|
|
.Select((a, idx) => {
|
|
|
|
|
|
TaskRollingNominationShipPreBillShowDto preBillInfo = new TaskRollingNominationShipPreBillShowDto
|
|
|
{
|
|
|
Bookedby = a.Detail.BOOKED_BY,
|
|
|
ConfirmDate = a.Dispatch?.CONFIRM_DATE,
|
|
|
ConfirmDeadLine = a.Dispatch?.CONFIRM_DEAD_LINE,
|
|
|
CtnStat = $"{a.Detail.CTNALL}*{a.Detail.CTNNUM}",
|
|
|
CustomerId = a.Detail.CUSTOMERID,
|
|
|
CustomerName = a.Detail.CUSTOMERNAME,
|
|
|
ContractualName = a.Detail.CONTRACTUAL_NAME,
|
|
|
CreateShareLinkDate = a.Dispatch?.CREATE_SHARE_LINK_DATE,
|
|
|
DischargePortName = a.Detail.DISCHARGEPORT_NAME,
|
|
|
IsSend = a.Dispatch != null ? a.Dispatch.IS_SEND : false,
|
|
|
IsUserManual = a.Dispatch != null ? a.Dispatch.IS_USER_MANUAL : false,
|
|
|
LoadPortName = a.Detail.LOADPORT_NAME,
|
|
|
PlaceOfDelivery = a.Detail.PLACEOF_DELIVERY,
|
|
|
PlaceOfReceipt = a.Detail.PLACEOF_RECEIPT,
|
|
|
Shipment = a.Detail.SHIPMENT,
|
|
|
Status = a.Dispatch?.STATUS,
|
|
|
ShareLinkKey = a.Dispatch?.SHARE_LINK_KEY,
|
|
|
UserOpinion = a.Dispatch?.USER_OPINION,
|
|
|
UserOpinionTxt = a.Dispatch?.USER_OPINION_TXT,
|
|
|
BatchId = a.Dispatch?.BATCH_ID,
|
|
|
BookingId = a.Detail.BOOKING_ID,
|
|
|
GroupName = a.Detail.CUSTOMERID.HasValue ? $"CUST_{idx + 1}" : "",
|
|
|
CtnNote = !string.IsNullOrWhiteSpace(a.Detail.CTNNOTE) ? a.Detail.CTNNOTE : ""
|
|
|
};
|
|
|
|
|
|
return preBillInfo;
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
tuples = withDispatchList.Where(a => !a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
|
|
|
.GroupBy(t => t.Detail.CTNALL)
|
|
|
.Select(t => new
|
|
|
{
|
|
|
Key = t.Key,
|
|
|
Num = t.ToList().Sum(x => x.Detail.CTNNUM)
|
|
|
}).Select(x => new Tuple<string, int>(x.Key, x.Num)).ToList();
|
|
|
}
|
|
|
|
|
|
if (withDispatchList.Any(a =>
|
|
|
a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)))
|
|
|
{
|
|
|
model.LoadDetailList.AddRange(withDispatchList.Where(a =>
|
|
|
a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
|
|
|
.Select((a, idx) =>
|
|
|
{
|
|
|
return a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>();
|
|
|
|
|
|
}).ToList());
|
|
|
}
|
|
|
|
|
|
model.TotalPreBillCtnStat = string.Join(",", tuples.GroupBy(x => x.Item1)
|
|
|
.Select(x =>
|
|
|
$"{x.Key}*{x.Sum(t => t.Item2)}").ToArray());
|
|
|
|
|
|
if (model.LoadDetailList.Count > 0)
|
|
|
{
|
|
|
model.TotalLoadCtnStat = string.Join(",", model.LoadDetailList.GroupBy(x => x.CtnAll)
|
|
|
.Select(x =>
|
|
|
$"{x.Key}*{x.Sum(t => t.CtnNum)}").ToArray());
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
|
|
|
|
|
|
throw ex;
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 推送预甩货客户访问链接
|
|
|
/// <summary>
|
|
|
/// 推送预甩货客户访问链接
|
|
|
/// </summary>
|
|
|
/// <param name="nominationDispatchId">预甩货任务主键组</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/PushShareLink")]
|
|
|
public async Task<TaskManageOrderResultDto> PushShareLink([FromBody] string[] nominationDispatchId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 生成预甩货调度
|
|
|
/// <summary>
|
|
|
/// 生成预甩货调度
|
|
|
/// </summary>
|
|
|
/// <param name="model">生成预甩货调度请求</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/DispatchRollingNomination")]
|
|
|
public async Task<TaskManageOrderResultDto> DispatchRollingNomination([FromBody] RollingNominationDispatchRequestDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
/*
|
|
|
1、如果调度ID不为空,标识选择新的明细替换原有的调度。
|
|
|
(1)首先匹配所选的箱型箱量是否一致,装货港、卸货港必需一致,不满足不能进行生成调度。
|
|
|
(2)删除原调度,生成新调度。
|
|
|
2、如果调度ID为空,标识是新增调度。
|
|
|
3、没有订舱ID或委托单位ID的数据不能生成调度。
|
|
|
*/
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
if (!model.isAdd)
|
|
|
{
|
|
|
if(string.IsNullOrWhiteSpace(model.nominationBatchId))
|
|
|
{
|
|
|
throw Oops.Oh($"改配调度需要提供预甩货调度批次ID");
|
|
|
}
|
|
|
|
|
|
if (model.loadDetailIds == null || model.loadDetailIds.Length == 0)
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货可Load明细信息不能为空");
|
|
|
}
|
|
|
|
|
|
var detailList = _taskRollingNominationDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => model.loadDetailIds.Contains(a.PK_ID) && a.IsDeleted == false).ToList();
|
|
|
|
|
|
if (detailList.Count != model.loadDetailIds.Length)
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货明细部分获取失败,请重新获取预甩货明细");
|
|
|
}
|
|
|
|
|
|
if (detailList.Any(a => !a.BOOKING_ID.HasValue || !a.CUSTOMERID.HasValue))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货明细存在未对应订舱的记录,不能生成调度");
|
|
|
}
|
|
|
|
|
|
var nomId = detailList.FirstOrDefault().NOM_ID;
|
|
|
|
|
|
var nomModel = _taskRollingNominationInfoRepository.AsQueryable()
|
|
|
.First(a => a.PK_ID == nomId);
|
|
|
|
|
|
var shipmentList = detailList.Select(a => a.SHIPMENT).Distinct().ToList();
|
|
|
|
|
|
Dictionary<string, string> batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() })
|
|
|
.ToDictionary(a => a.Key, b => b.BatchId);
|
|
|
|
|
|
List<TaskRollingNominationDispatchInfo> dispatchList = new List<TaskRollingNominationDispatchInfo>();
|
|
|
List<TaskRollingNominationDetailInfo> withDispatchDetailList = new List<TaskRollingNominationDetailInfo>();
|
|
|
|
|
|
var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationDispatchInfo>((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID)
|
|
|
.Where((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID && detail.IsDeleted == false
|
|
|
&& dispatch.IsDeleted == false && dispatch.BATCH_ID == model.nominationBatchId)
|
|
|
.Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList();
|
|
|
|
|
|
if (withDispatchList.Count > 0)
|
|
|
{
|
|
|
withDispatchDetailList = withDispatchList.Select(a => a.Detail)
|
|
|
.ToList();
|
|
|
}
|
|
|
|
|
|
if (dispatchList.Count == 0)
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货调度获取失败,无法改配");
|
|
|
}
|
|
|
|
|
|
//如果原调度对应的明细含有本次提交的明细,不允许改配调度
|
|
|
if (withDispatchDetailList.Any(a =>
|
|
|
model.loadDetailIds.Any(b => b == a.PK_ID)))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货调度获取失败,提交明细已生成调度,无法改配");
|
|
|
}
|
|
|
|
|
|
//需要匹配箱型箱量
|
|
|
var origCtnStat = string.Join(",", withDispatchDetailList
|
|
|
.GroupBy(a => a.CTNALL).OrderBy(a => a.Key)
|
|
|
.Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray());
|
|
|
|
|
|
detailList = _taskRollingNominationDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => shipmentList.Contains(a.SHIPMENT) && a.IsDeleted == false && a.NOM_ID == nomId).ToList();
|
|
|
|
|
|
var targetCtnStat = string.Join(",", detailList
|
|
|
.GroupBy(a => a.CTNALL).OrderBy(a => a.Key)
|
|
|
.Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray());
|
|
|
|
|
|
//如果箱型箱量不一致不能改配
|
|
|
if (!origCtnStat.Equals(targetCtnStat))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货调度获取失败,提交明细箱型箱量于被改配调度不一致,无法改配");
|
|
|
}
|
|
|
|
|
|
var origShip = withDispatchDetailList.FirstOrDefault();
|
|
|
var targetShip = detailList.FirstOrDefault();
|
|
|
|
|
|
var origKey = $"{origShip.PLACEOF_RECEIPT}_{origShip.LOADPORT_NAME}_{origShip.DISCHARGEPORT_NAME}_{origShip.PLACEOF_DELIVERY}";
|
|
|
var targeKey = $"{targetShip.PLACEOF_RECEIPT}_{targetShip.LOADPORT_NAME}_{targetShip.DISCHARGEPORT_NAME}_{targetShip.PLACEOF_DELIVERY}";
|
|
|
|
|
|
//收货地、装货港、卸货港、交货地必需一致
|
|
|
if (!origKey.Equals(targeKey))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货调度获取失败,提交明细收货地、装货港、卸货港、交货地被改配调度不一致,无法改配");
|
|
|
}
|
|
|
|
|
|
//删除原调度
|
|
|
withDispatchList.ForEach(async a =>
|
|
|
{
|
|
|
a.Dispatch.IsDeleted = true;
|
|
|
a.Dispatch.UpdatedTime = nowDate;
|
|
|
a.Dispatch.UpdatedUserId = UserManager.UserId;
|
|
|
a.Dispatch.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _taskRollingNominationDispatchInfoRepository.AsUpdateable(a.Dispatch)
|
|
|
.UpdateColumns(it => new
|
|
|
{
|
|
|
it.IsDeleted,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
});
|
|
|
|
|
|
//写入新调度
|
|
|
detailList.ForEach(a =>
|
|
|
{
|
|
|
TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
CreatedTime = nowDate,
|
|
|
UpdatedTime = nowDate,
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
DETAIL_ID = a.PK_ID,
|
|
|
NOM_ID = a.NOM_ID,
|
|
|
NOM_SHIP_ID = a.NOM_SHIP_ID,
|
|
|
IsDeleted = false,
|
|
|
STATUS = "WAIT",
|
|
|
TASK_ID = nomModel.TASK_ID,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME,
|
|
|
BATCH_ID = batchDict[a.SHIPMENT],
|
|
|
};
|
|
|
|
|
|
_taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo);
|
|
|
});
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var withDispatchList =
|
|
|
_taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
|
|
|
.LeftJoin<TaskRollingNominationDispatchInfo>((nom, detail, dispatch) =>
|
|
|
detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false)
|
|
|
.Where((nom, detail, dispatch) =>
|
|
|
detail.IsDeleted == false
|
|
|
&& detail.NOM_ID == model.nominationId)
|
|
|
.Select((nom, detail, dispatch) =>
|
|
|
new { Nom = nom, Detail = detail, Dispatch = dispatch }).ToList();
|
|
|
|
|
|
if (withDispatchList.Any(p => p.Dispatch != null
|
|
|
&& !string.IsNullOrWhiteSpace(p.Dispatch.PK_ID)))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩货明细已生成调度不能重复");
|
|
|
}
|
|
|
|
|
|
var nomiInfo = withDispatchList.FirstOrDefault().Nom;
|
|
|
|
|
|
var shipmentList = withDispatchList
|
|
|
.Select(a => a.Detail.SHIPMENT)
|
|
|
.Distinct().ToList();
|
|
|
|
|
|
Dictionary<string, string> batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() })
|
|
|
.ToDictionary(a => a.Key, b => b.BatchId);
|
|
|
|
|
|
DateTime deadLine = nomiInfo.CONFIRM_DEAD_LINE.Value.AddHours(2);
|
|
|
|
|
|
//开始写入调度
|
|
|
withDispatchList.ForEach(info =>
|
|
|
{
|
|
|
var a = info.Detail;
|
|
|
|
|
|
if (!a.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
CreatedTime = nowDate,
|
|
|
UpdatedTime = nowDate,
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
DETAIL_ID = a.PK_ID,
|
|
|
NOM_ID = a.NOM_ID,
|
|
|
NOM_SHIP_ID = a.NOM_SHIP_ID,
|
|
|
IsDeleted = false,
|
|
|
STATUS = RollingNominationDispatchStatusEnum.WAIT.ToString(),
|
|
|
TASK_ID = nomiInfo.TASK_ID,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME,
|
|
|
BATCH_ID = batchDict[a.SHIPMENT],
|
|
|
CONFIRM_DEAD_LINE = deadLine
|
|
|
};
|
|
|
|
|
|
_taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"生成预甩货调度异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 刷新预甩货对应订舱
|
|
|
/// <summary>
|
|
|
/// 刷新预甩货对应订舱
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">预甩货主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/RefreshBookingOrder")]
|
|
|
public async Task<TaskManageOrderResultDto> RefreshBookingOrder(string taskPkId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
/*
|
|
|
获取所有当票预甩的所有没有BOOKING_ID的明细记录,并用SHIPMENT(提单号),检索订舱数据,能匹配的更新
|
|
|
*/
|
|
|
var list = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
|
|
|
.Where((nom, detail) => nom.TASK_ID == taskPkId
|
|
|
&& detail.IsDeleted == false && !detail.BOOKING_ID.HasValue)
|
|
|
.Select((nom, detail) => detail).ToList();
|
|
|
|
|
|
|
|
|
if (list.Count > 0)
|
|
|
{
|
|
|
var mblNoArg = list.Select(a => a.SHIPMENT?.Trim()).Distinct().ToList();
|
|
|
|
|
|
var orderList = _bookingOrderRepository.AsQueryable()
|
|
|
.Where(a => mblNoArg.Contains(a.MBLNO) && (a.ParentId == null || a.ParentId == 0) && a.IsDeleted == false).ToList();
|
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
if (orderList.Count > 0)
|
|
|
{
|
|
|
orderList.ForEach(ord =>
|
|
|
{
|
|
|
var dlist = list.Where(b => b.SHIPMENT.Equals(ord.MBLNO)).ToList();
|
|
|
|
|
|
if (dlist.Count > 0)
|
|
|
{
|
|
|
dlist.ForEach(dt =>
|
|
|
{
|
|
|
dt.BOOKING_ID = ord.Id;
|
|
|
dt.UpdatedTime = nowDate;
|
|
|
dt.UpdatedUserId = UserManager.UserId;
|
|
|
dt.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
_taskRollingNominationDetailInfoRepository.AsUpdateable(dt)
|
|
|
.UpdateColumns(it => new
|
|
|
{
|
|
|
it.BOOKING_ID,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommand();
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "对应订舱完成";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"刷新预甩货对应订舱异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 查看分享链接
|
|
|
/// <summary>
|
|
|
/// 查看分享链接
|
|
|
/// </summary>
|
|
|
/// <param name="dispatchBatchId">预甩调度批次号</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetUrl")]
|
|
|
public async Task<TaskManageOrderResultDto> GetUrl(string dispatchBatchId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
/*
|
|
|
用预甩调度的dispatchBatchId关联分享表的BUSI_ID获取分享KEY
|
|
|
*/
|
|
|
if (string.IsNullOrWhiteSpace(dispatchBatchId))
|
|
|
throw Oops.Oh($"预甩调度批次号不能为空");
|
|
|
|
|
|
var dispatchInfo = _taskRollingNominationDispatchInfoRepository.AsQueryable()
|
|
|
.First(a => a.BATCH_ID == dispatchBatchId);
|
|
|
|
|
|
if (dispatchInfo == null)
|
|
|
{
|
|
|
throw Oops.Oh($"获取预甩调度信息失败,不存在或已作废");
|
|
|
}
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(dispatchInfo.SHARE_LINK_KEY))
|
|
|
throw Oops.Oh($"链接访问KEY不存在,请生成分享链接");
|
|
|
|
|
|
|
|
|
string[] statusArg = new string[] { RollingNominationDispatchStatusEnum.CANCEL.ToString(),
|
|
|
RollingNominationDispatchStatusEnum.EXPIRE.ToString() };
|
|
|
|
|
|
if (statusArg.Any(a => a.Equals(dispatchInfo.STATUS, StringComparison.OrdinalIgnoreCase)))
|
|
|
throw Oops.Oh($"链接访问KEY状态不可用");
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
result.ext = dispatchInfo.SHARE_LINK_KEY;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取Status是load的可配载的列表
|
|
|
/// <summary>
|
|
|
/// 获取Status是load的可配载的列表
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">预甩货任务主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetLoadStatusDetailList")]
|
|
|
public async Task<TaskManageOrderResultDto> GetLoadStatusDetailList(string taskPkId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var withDispatchList =
|
|
|
_taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((nom,detail)=> nom.PK_ID == detail.NOM_ID)
|
|
|
.LeftJoin<TaskRollingNominationDispatchInfo>((nom,detail, dispatch) =>
|
|
|
detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false)
|
|
|
.Where((nom,detail, dispatch) =>
|
|
|
nom.TASK_ID == taskPkId && detail.IsDeleted == false && string.IsNullOrWhiteSpace(dispatch.TASK_ID))
|
|
|
.Select((nom, detail, dispatch) => new { Detail = detail}).ToList();
|
|
|
|
|
|
if (withDispatchList.Count > 0)
|
|
|
{
|
|
|
result.ext = withDispatchList.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取提单号下预甩货的单票明细
|
|
|
/// <summary>
|
|
|
/// 获取提单号下预甩货的单票明细
|
|
|
/// </summary>
|
|
|
/// <param name="nominationId">预甩货主键</param>
|
|
|
/// <param name="shipmentNo">提单号</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetPreBillDetailList")]
|
|
|
public async Task<TaskManageOrderResultDto> GetPreBillDetailList([FromQuery] string nominationId, [FromQuery] string shipmentNo)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var withDispatchList =
|
|
|
_taskRollingNominationInfoRepository.AsQueryable()
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
|
|
|
.Where((nom, detail) =>
|
|
|
nom.PK_ID == nominationId && detail.IsDeleted == false && detail.SHIPMENT == shipmentNo)
|
|
|
.Select((nom, detail) => new { Detail = detail }).ToList();
|
|
|
|
|
|
if (withDispatchList.Count > 0)
|
|
|
{
|
|
|
result.ext = withDispatchList.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"获取提单号下预甩货的单票明细异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 保存预甩货明细箱型信息
|
|
|
/// <summary>
|
|
|
/// 保存预甩货明细箱型信息(处理没有给箱型高度或者未能翻译的箱型,进行人工修正)
|
|
|
/// </summary>
|
|
|
/// <param name="model">保存预甩货明细箱型请求</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/SaveDetailContainer")]
|
|
|
public async Task<TaskManageOrderResultDto> SaveDetailContainer(SaveDetailContainerDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.ctnCode))
|
|
|
{
|
|
|
throw Oops.Oh($"请求的箱型代码不能为空");
|
|
|
}
|
|
|
|
|
|
var detailInfo = _taskRollingNominationDetailInfoRepository.AsQueryable()
|
|
|
.First(a => a.PK_ID == model.detailPKId && a.IsDeleted == false);
|
|
|
|
|
|
if (detailInfo == null)
|
|
|
throw Oops.Oh($"预甩货明细主键{model.detailPKId}无法获取业务信息");
|
|
|
|
|
|
|
|
|
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
|
|
|
|
|
|
var ctnCodeModel = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
|
|
|
a.Code.Equals(model.ctnCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (ctnCodeModel == null)
|
|
|
throw Oops.Oh($"请求的箱型代码基础数据不存在,请修改");
|
|
|
|
|
|
|
|
|
detailInfo.CTNCODE = ctnCodeModel.Code;
|
|
|
detailInfo.CTNALL = ctnCodeModel.Name;
|
|
|
|
|
|
detailInfo.UpdatedTime = DateTime.Now;
|
|
|
detailInfo.UpdatedUserId = UserManager.UserId;
|
|
|
detailInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _taskRollingNominationDetailInfoRepository.AsUpdateable(detailInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.CTNCODE,
|
|
|
it.CTNALL,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"保存预甩货明细箱型信息异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 生成访问链接
|
|
|
/// <summary>
|
|
|
/// 生成访问链接
|
|
|
/// </summary>
|
|
|
/// <param name="model">创建分享链接请求</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/GenShareLink")]
|
|
|
public async Task<TaskManageOrderResultDto> GenShareLink(RollingNominationGenShareLinkDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.dispatchBatchId))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩调度批次ID不能为空");
|
|
|
}
|
|
|
|
|
|
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
|
|
|
.Where(a => a.BATCH_ID == model.dispatchBatchId).ToList();
|
|
|
|
|
|
if(list.Count == 0)
|
|
|
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
|
|
|
|
|
|
var taskInfo = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == list.FirstOrDefault().TASK_ID);
|
|
|
|
|
|
ShareLinkRequestDto reqDto = new ShareLinkRequestDto {
|
|
|
businessId = model.dispatchBatchId,
|
|
|
businessType = "NOMI_DISPATCH",
|
|
|
expireDate = list.FirstOrDefault().CONFIRM_DEAD_LINE.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
isUserFeedBack = true,
|
|
|
taskType = taskInfo.TASK_BASE_TYPE,
|
|
|
isRenew = model.isRenew
|
|
|
};
|
|
|
|
|
|
var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService));
|
|
|
result = await service.CreateShareLink(reqDto);
|
|
|
|
|
|
if(result.succ)
|
|
|
{
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
string shareKey = result.ext.ToString();
|
|
|
|
|
|
list.ForEach(p => {
|
|
|
p.SHARE_LINK_KEY = shareKey;
|
|
|
p.CREATE_SHARE_LINK_DATE = nowDate;
|
|
|
p.UpdatedTime = nowDate;
|
|
|
p.UpdatedUserId = UserManager.UserId;
|
|
|
p.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
_taskRollingNominationDispatchInfoRepository.AsUpdateable(p)
|
|
|
.UpdateColumns(it => new
|
|
|
{
|
|
|
it.SHARE_LINK_KEY,
|
|
|
it.CREATE_SHARE_LINK_DATE,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"生成访问链接异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 取消访问链接
|
|
|
/// <summary>
|
|
|
/// 取消访问链接
|
|
|
/// </summary>
|
|
|
/// <param name="dispatchBatchId">预甩调度批次ID</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/CancelShareLink")]
|
|
|
public async Task<TaskManageOrderResultDto> CancelShareLink(string dispatchBatchId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(dispatchBatchId))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩调度批次ID不能为空");
|
|
|
}
|
|
|
|
|
|
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
|
|
|
.Where(a => a.BATCH_ID == dispatchBatchId).ToList();
|
|
|
|
|
|
if (list.Count == 0)
|
|
|
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
|
|
|
|
|
|
var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService));
|
|
|
result = await service.CancelShareLink(dispatchBatchId);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"取消访问链接异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取用户反馈信息
|
|
|
/// <summary>
|
|
|
/// 获取用户反馈信息
|
|
|
/// </summary>
|
|
|
/// <param name="dispatchBatchId">预甩调度批次ID</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/GetUserFeedBack")]
|
|
|
public async Task<TaskManageOrderResultDto> GetUserFeedBack(string dispatchBatchId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(dispatchBatchId))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩调度批次ID不能为空");
|
|
|
}
|
|
|
|
|
|
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
|
|
|
.Where(a => a.BATCH_ID == dispatchBatchId).ToList();
|
|
|
|
|
|
if (list.Count == 0)
|
|
|
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
|
|
|
|
|
|
result.succ = true;
|
|
|
result.ext = new
|
|
|
{
|
|
|
userOpinion = list.FirstOrDefault().USER_OPINION,
|
|
|
userOpinionTxt = list.FirstOrDefault().USER_OPINION_TXT
|
|
|
};
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"获取用户反馈信息异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发送预甩的通知
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/SendRollingNominationNotice")]
|
|
|
public async Task<TaskManageOrderResultDto> SendRollingNominationNotice(RollingNominationNoticeDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.taskId))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩任务ID不能为空");
|
|
|
}
|
|
|
|
|
|
var printTemplate = await _repPrintTemplate.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == model.templateId && x.TenantId == UserManager.TENANT_ID);
|
|
|
if (printTemplate == null)
|
|
|
{
|
|
|
throw Oops.Bah(BookingErrorCode.BOOK115);
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(printTemplate.CateCode) || !printTemplate.CateCode.Contains("rolling_nomination_notice_template"))
|
|
|
{
|
|
|
throw Oops.Bah("模板类型分类错误,当前只支持预甩邮件通知");
|
|
|
}
|
|
|
|
|
|
string html = string.Empty;
|
|
|
|
|
|
var list = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationInfo>((detail, norm) => detail.NOM_ID == norm.PK_ID)
|
|
|
.Where((detail, norm) => norm.TASK_ID == model.taskId && detail.IsDeleted == false && norm.IsDeleted == false)
|
|
|
.Select((detail, norm) => detail).ToList();
|
|
|
|
|
|
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable().Filter(null, true).Where(p => (p.PK_ID.Equals(model.fromShipPKId) || p.PK_ID.Equals(model.toShipPKId))
|
|
|
&& p.IsDeleted == false).ToList();
|
|
|
|
|
|
var fromShipInfo = shipList.FirstOrDefault(p => p.PK_ID == model.fromShipPKId);
|
|
|
|
|
|
if (fromShipInfo == null)
|
|
|
throw Oops.Bah("当前预甩原船信息获取失败");
|
|
|
|
|
|
var toShipInfo = shipList.FirstOrDefault(p => p.PK_ID == model.toShipPKId);
|
|
|
|
|
|
if (fromShipInfo == null)
|
|
|
throw Oops.Bah("当前预甩换船信息获取失败");
|
|
|
|
|
|
BookingOrder bookingOrderEntity = null;
|
|
|
|
|
|
if (list.Any(p => p.BOOKING_ID.HasValue))
|
|
|
{
|
|
|
var bookingId = list.FirstOrDefault().BOOKING_ID.Value;
|
|
|
//读取订舱数据
|
|
|
bookingOrderEntity = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
.First(a => a.Id == bookingId);
|
|
|
}
|
|
|
|
|
|
if (bookingOrderEntity == null)
|
|
|
throw Oops.Bah("当前预甩没有对应的订舱信息,请先生成订舱订单才能转发邮件");
|
|
|
|
|
|
SysUser opUserInfo = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID) && Regex.IsMatch(bookingOrderEntity.OPID, "[0-9]+"))
|
|
|
{
|
|
|
opUserInfo = _sysUserRepository.AsQueryable().Filter(null, true).First(u => u.Id == long.Parse(bookingOrderEntity.OPID));
|
|
|
}
|
|
|
|
|
|
if (opUserInfo == null)
|
|
|
throw Oops.Bah("当前预甩对应的订舱信息未指定操作OP,不能转发邮件");
|
|
|
|
|
|
html = GenerateTemplateHtml(printTemplate.FilePath, fromShipInfo, toShipInfo, opUserInfo, UserManager.TENANT_NAME);
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(html))
|
|
|
throw Oops.Bah("生成预甩邮件通知正文失败,未生成有效信息");
|
|
|
|
|
|
//TO 邮件接收人
|
|
|
string toEmail = string.Empty;
|
|
|
//订舱OP的邮箱
|
|
|
string opEmail = string.Empty;
|
|
|
|
|
|
var bookingContactList = _bookingOrderContactRepository.AsQueryable().Filter(null, true)
|
|
|
.Where(a => a.BookingId == bookingOrderEntity.Id).ToList();
|
|
|
|
|
|
if (bookingContactList == null || bookingContactList.Count == 0)
|
|
|
{
|
|
|
_logger.LogInformation($"当前订舱未指定的联系人,toEmail={toEmail}");
|
|
|
}
|
|
|
|
|
|
toEmail = string.Join(";", bookingContactList.Select(x => x.Email.Trim()).Distinct().ToArray());
|
|
|
|
|
|
//获取操作OP的邮箱
|
|
|
if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID))
|
|
|
{
|
|
|
var opId = long.Parse(bookingOrderEntity.OPID);
|
|
|
var opUser = _sysUserRepository.AsQueryable().Filter(null, true).First(a => a.Id == opId);
|
|
|
|
|
|
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Email))
|
|
|
{
|
|
|
opEmail = opUser.Email.Trim();
|
|
|
|
|
|
_logger.LogInformation($"获取操作OP的邮箱,opEmail={opEmail} id={opId} name={opUser.Name}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//推送邮件
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
var dirAbs = opt.basePath;
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
{
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
}
|
|
|
|
|
|
string emailTitle = $"【预甩通知】{list.FirstOrDefault().SHIPMENT} 原船名/航次 {fromShipInfo.VESSEL}/{fromShipInfo.VOYNO}";
|
|
|
|
|
|
var sendRlt = await SendEmail(emailTitle, html, toEmail, opEmail, list.FirstOrDefault().SHIPMENT);
|
|
|
|
|
|
if (sendRlt.succ)
|
|
|
{
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = sendRlt.msg;
|
|
|
|
|
|
new EmailNoticeHelper().SendEmailNotice($"MBLNO={list.FirstOrDefault().SHIPMENT} 发送预甩的通知失败", $"MBLNO={list.FirstOrDefault().SHIPMENT} 发送预甩的通知失败,原因:{sendRlt.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"发送预甩的通知失败,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
#region 获取预甩的通知预览
|
|
|
/// <summary>
|
|
|
/// 获取预甩的通知预览
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/TaskManageRollingNomination/GetRollingNominationNoticeReview")]
|
|
|
public async Task<TaskManageOrderResultDto> GetRollingNominationNoticeReview(RollingNominationNoticeDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.taskId))
|
|
|
{
|
|
|
throw Oops.Oh($"预甩任务ID不能为空");
|
|
|
}
|
|
|
|
|
|
var printTemplate = await _repPrintTemplate.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == model.templateId && x.TenantId == UserManager.TENANT_ID);
|
|
|
if (printTemplate == null)
|
|
|
{
|
|
|
throw Oops.Bah(BookingErrorCode.BOOK115);
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(printTemplate.CateCode) || !printTemplate.CateCode.Contains("rolling_nomination_notice_template"))
|
|
|
{
|
|
|
throw Oops.Bah("模板类型分类错误,当前只支持预甩邮件通知");
|
|
|
}
|
|
|
|
|
|
string html = string.Empty;
|
|
|
|
|
|
var list = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationInfo>((detail, norm) => detail.NOM_ID == norm.PK_ID)
|
|
|
.Where((detail, norm) => norm.TASK_ID == model.taskId && detail.IsDeleted == false && norm.IsDeleted == false)
|
|
|
.Select((detail, norm) => detail).ToList();
|
|
|
|
|
|
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable().Filter(null, true).Where(p => (p.PK_ID.Equals(model.fromShipPKId) || p.PK_ID.Equals(model.toShipPKId))
|
|
|
&& p.IsDeleted == false).ToList();
|
|
|
|
|
|
var fromShipInfo = shipList.FirstOrDefault(p => p.PK_ID == model.fromShipPKId);
|
|
|
|
|
|
if (fromShipInfo == null)
|
|
|
throw Oops.Bah("当前预甩原船信息获取失败");
|
|
|
|
|
|
var toShipInfo = shipList.FirstOrDefault(p => p.PK_ID == model.toShipPKId);
|
|
|
|
|
|
if (fromShipInfo == null)
|
|
|
throw Oops.Bah("当前预甩换船信息获取失败");
|
|
|
|
|
|
BookingOrder bookingOrderEntity = null;
|
|
|
|
|
|
if (list.Any(p => p.BOOKING_ID.HasValue))
|
|
|
{
|
|
|
var bookingId = list.FirstOrDefault().BOOKING_ID.Value;
|
|
|
//读取订舱数据
|
|
|
bookingOrderEntity = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
.First(a => a.Id == bookingId);
|
|
|
}
|
|
|
|
|
|
if (bookingOrderEntity == null)
|
|
|
throw Oops.Bah("当前预甩没有对应的订舱信息,请先生成订舱订单才能转发邮件");
|
|
|
|
|
|
SysUser opUserInfo = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID) && Regex.IsMatch(bookingOrderEntity.OPID, "[0-9]+"))
|
|
|
{
|
|
|
opUserInfo = _sysUserRepository.AsQueryable().Filter(null, true).First(u => u.Id == long.Parse(bookingOrderEntity.OPID));
|
|
|
}
|
|
|
|
|
|
if (opUserInfo == null)
|
|
|
throw Oops.Bah("当前预甩对应的订舱信息未指定操作OP,不能转发邮件");
|
|
|
|
|
|
html = GenerateTemplateHtml(printTemplate.FilePath, fromShipInfo, toShipInfo, opUserInfo, UserManager.TENANT_NAME);
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
result.ext = html;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"取消获取预甩的通知预览异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取换船选择列表
|
|
|
/// <summary>
|
|
|
/// 获取换船选择列表
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">任务ID</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpGet("/TaskManageRollingNomination/GetToShipSelect")]
|
|
|
public async Task<TaskManageOrderResultDto> GetToShipSelect(string taskPkId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
List<TaskRollingNominationShipFromToDto> fromToList = new List<TaskRollingNominationShipFromToDto>();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var list = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
|
|
|
.InnerJoin<TaskRollingNominationInfo>((detail, norm) => detail.NOM_ID == norm.PK_ID)
|
|
|
.Where((detail, norm) => norm.TASK_ID == taskPkId && detail.IsDeleted == false && norm.IsDeleted == false)
|
|
|
.Select((detail, norm) => detail).ToList();
|
|
|
|
|
|
if (list.Count == 0)
|
|
|
throw Oops.Oh($"预甩货任务主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
TaskRollingNominationShowDto model = new TaskRollingNominationShowDto();
|
|
|
|
|
|
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable()
|
|
|
.Where(a => a.NOM_ID == list.FirstOrDefault().NOM_ID && a.IsDeleted == false).ToList();
|
|
|
|
|
|
var fromEntity = shipList.Where(a =>
|
|
|
a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
|
|
|
if (fromEntity.Count > 0)
|
|
|
model.From = fromEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
|
|
|
model.LoadDetailList = list.Select(a => a.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
|
|
|
|
|
|
if (model.From != null && model.From.Count > 1)
|
|
|
{
|
|
|
var firstLoadDetail = model.LoadDetailList.FirstOrDefault();
|
|
|
|
|
|
if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port)))
|
|
|
{
|
|
|
model.From = model.From.Where(a => a.Terminal.Contains(firstLoadDetail.LoadPortName?.Trim())).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
model.From = model.From.Where(a => a.Port.Equals(firstLoadDetail.LoadPortName?.Trim(),StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE, "To(\\s+[0-9]+)?"
|
|
|
, RegexOptions.IgnoreCase)).ToList();
|
|
|
|
|
|
if (toEntity.Count > 0)
|
|
|
model.To = toEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
//优先PORT关联FROM和TO,也有PORT为空的情况,这种就需要用Terminal来关联
|
|
|
if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port)))
|
|
|
{
|
|
|
//这里为了前端原船和换船做了根据Terminal对应
|
|
|
fromToList = model.From.GroupJoin(model.To, l => l.Terminal?.Trim(), r => r.Terminal?.Trim(), (l, r) =>
|
|
|
{
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
{
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
{
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
}
|
|
|
|
|
|
return dto;
|
|
|
}).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//这里为了前端原船和换船做了根据PORT对应
|
|
|
fromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) =>
|
|
|
{
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
{
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
{
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
}
|
|
|
|
|
|
return dto;
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
List<Tuple<string, int>> tuples = new List<Tuple<string, int>>();
|
|
|
|
|
|
model.FromToList = new List<TaskRollingNominationShipFromToDto>();
|
|
|
|
|
|
if (model.LoadDetailList.Count > 0)
|
|
|
{
|
|
|
model.TotalLoadCtnStat = string.Join(",", model.LoadDetailList.GroupBy(x => x.CtnAll)
|
|
|
.Select(x =>
|
|
|
$"{x.Key}*{x.Sum(t => t.CtnNum)}").ToArray());
|
|
|
|
|
|
string rollRegex = "Roll\\s+to\\s+\\w+\\s+\\w{3,}\\/\\w+,\\s?if\\s+cannot\\s+catch\\s?,\\s+roll\\s+to\\s+\\w{3,}\\s+next\\s+sailing";
|
|
|
string rollontoRegex = "Roll\\s+onto\\s+\\w{3,}\\s+\\w+,\\s+[0-9]+\\s+days\\s+delay\\.";
|
|
|
|
|
|
bool isSelectRoll = false;
|
|
|
bool isRoll = false;
|
|
|
bool isRollOnto = false;
|
|
|
|
|
|
model.LoadDetailList.ForEach(p =>
|
|
|
{
|
|
|
string vslCode = string.Empty;
|
|
|
string voyNo = string.Empty;
|
|
|
string strCode = string.Empty;
|
|
|
string strCode2 = string.Empty;
|
|
|
|
|
|
if (Regex.IsMatch(p.Status, rollRegex, RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
string currS = Regex.Match(p.Status, "(?<=Roll\\sto\\s\\w+\\s)\\w{3,}\\/\\w+(?=,)").Value;
|
|
|
vslCode = Regex.Split(currS, "\\/")[0]?.Trim();
|
|
|
voyNo = Regex.Split(currS, "\\/")[1]?.Trim();
|
|
|
|
|
|
strCode = Regex.Match(p.Status, "(?<=if\\scannot\\scatch\\s?,\\sroll\\sto\\s)\\w{3,}(?=\\s+next\\s+sailing)").Value?.Trim();
|
|
|
|
|
|
isSelectRoll = true;
|
|
|
}
|
|
|
else if (p.Status.Trim().Equals("roll", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
isRoll = true;
|
|
|
}
|
|
|
else if (Regex.IsMatch(p.Status, rollontoRegex, RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
vslCode = Regex.Match(p.Status, "(?<=Roll\\sonto\\s)\\w{3,}(?=\\s+\\w+,)").Value?.Trim();
|
|
|
|
|
|
isRollOnto = true;
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < fromToList.Count; i++)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(fromToList[i].FromShip.Port))
|
|
|
{
|
|
|
if (fromToList[i].FromShip.Port.Equals(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
var fromInfo = fromToList[i].FromShip.Adapt<TaskRollingNominationShipDto>();
|
|
|
|
|
|
List<TaskRollingNominationShipDto> toShipList = new List<TaskRollingNominationShipDto>();
|
|
|
|
|
|
if (isSelectRoll)
|
|
|
{
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
{
|
|
|
if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
}
|
|
|
else if (fromToList[i].ToShipList[j].ShipString.Equals(strCode, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (isRoll)
|
|
|
{
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
{
|
|
|
if (fromToList[i].ToShipList[j].Port.Equals(p.PlaceOfDelivery?.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (toShipList.Count == 0)
|
|
|
{
|
|
|
if (fromToList[i].ToShipList.Count == 1)
|
|
|
{
|
|
|
toShipList.Add(fromToList[i].ToShipList.FirstOrDefault().Adapt<TaskRollingNominationShipDto>());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
model.FromToList.Add(new TaskRollingNominationShipFromToDto
|
|
|
{
|
|
|
FromShip = fromInfo,
|
|
|
ToShipList = toShipList
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (fromToList[i].FromShip.Terminal.Contains(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
var fromInfo = fromToList[i].FromShip.Adapt<TaskRollingNominationShipDto>();
|
|
|
|
|
|
List<TaskRollingNominationShipDto> toShipList = new List<TaskRollingNominationShipDto>();
|
|
|
|
|
|
if (isRollOnto)
|
|
|
{
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
{
|
|
|
if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
model.FromToList.Add(new TaskRollingNominationShipFromToDto
|
|
|
{
|
|
|
FromShip = fromInfo,
|
|
|
ToShipList = toShipList
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.ext = fromToList;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"获取换船选择列表异常,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 通过邮件模板生成预甩邮件通知内容
|
|
|
/// <summary>
|
|
|
/// 通过邮件模板生成预甩邮件通知内容
|
|
|
/// </summary>
|
|
|
/// <param name="filePath">文件路径</param>
|
|
|
/// <param name="fromShipInfo">原船详情</param>
|
|
|
/// <param name="toShipInfo">换船详情</param>
|
|
|
/// <param name="opUserInfo">操作OP详情</param>
|
|
|
/// <param name="tenantName">租户名称</param>
|
|
|
/// <returns>返回生成后邮件正文</returns>
|
|
|
private string GenerateTemplateHtml(string filePath, TaskRollingNominationShipInfo fromShipInfo, TaskRollingNominationShipInfo toShipInfo,
|
|
|
SysUser opUserInfo, string tenantName)
|
|
|
{
|
|
|
string result = string.Empty;
|
|
|
string baseHtml = string.Empty;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var opt = App.GetOptions<PrintTemplateOptions>();
|
|
|
var dirAbs = opt.basePath;
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
{
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
}
|
|
|
|
|
|
var fileAbsPath = Path.Combine(dirAbs, filePath);
|
|
|
_logger.LogInformation($"查找模板文件:{fileAbsPath}");
|
|
|
|
|
|
if (!File.Exists(fileAbsPath))
|
|
|
{
|
|
|
throw Oops.Bah(BookingErrorCode.BOOK115);
|
|
|
}
|
|
|
|
|
|
baseHtml = File.ReadAllText(fileAbsPath);
|
|
|
|
|
|
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Name))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#opname#", opUserInfo.Name);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#opname#", "操作");
|
|
|
}
|
|
|
|
|
|
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Email))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#opemail#", opUserInfo.Email);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#opemail#", "");
|
|
|
}
|
|
|
|
|
|
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Phone))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Phone);
|
|
|
}
|
|
|
else if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Tel);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#optel#", "");
|
|
|
}
|
|
|
//原船
|
|
|
if (fromShipInfo.ETD.HasValue && fromShipInfo.ETD.Value != DateTime.MinValue)
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#ETD#", fromShipInfo.ETD.Value.ToString("yyyy-MM-dd"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#ETD#", "");
|
|
|
}
|
|
|
//原船
|
|
|
if (!string.IsNullOrWhiteSpace(fromShipInfo.VESSEL) && !string.IsNullOrWhiteSpace(fromShipInfo.VOYNO))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#VesselVoyno#", $"{fromShipInfo.VESSEL}/{fromShipInfo.VOYNO}");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#VesselVoyno#", "");
|
|
|
}
|
|
|
|
|
|
//换船
|
|
|
if (toShipInfo.ETD.HasValue && toShipInfo.ETD.Value != DateTime.MinValue)
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#newETD#", toShipInfo.ETD.Value.ToString("yyyy-MM-dd"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#newETD#", "");
|
|
|
}
|
|
|
//换船
|
|
|
if (!string.IsNullOrWhiteSpace(toShipInfo.VESSEL) && !string.IsNullOrWhiteSpace(toShipInfo.VOYNO))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#newVesselVoyno#", $"{toShipInfo.VESSEL}/{toShipInfo.VOYNO}");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#newVesselVoyno#", "");
|
|
|
}
|
|
|
//换船
|
|
|
if (toShipInfo.SI_CUT_DATE.HasValue && toShipInfo.SI_CUT_DATE.Value != DateTime.MinValue)
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#CutSingleTime#", toShipInfo.SI_CUT_DATE.Value.ToString("yyyy-MM-dd"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#CutSingleTime#", "");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(tenantName))
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#TenantCompanyName#", tenantName);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
baseHtml = baseHtml.Replace("#TenantCompanyName#", "");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"生成预甩通知邮件正文失败,原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"生成预甩通知邮件正文失败,原因:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
result = baseHtml;
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送邮件
|
|
|
/// <summary>
|
|
|
/// 发送邮件
|
|
|
/// </summary>
|
|
|
/// <param name="emailTitle">邮件标题</param>
|
|
|
/// <param name="emailHtml">邮件正文</param>
|
|
|
/// <param name="toEmail">邮件接收人</param>
|
|
|
/// <param name="opEmail">邮件抄送人</param>
|
|
|
/// <param name="mblNo">提单号</param>
|
|
|
/// <param name="usePersonalEmailSend">是否使用个人邮箱</param>
|
|
|
/// <returns>返回发送回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> SendEmail(string emailTitle,string emailHtml,string toEmail,string opEmail,string mblNo,bool usePersonalEmailSend = false)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//提取当前公共邮箱的配置
|
|
|
DjyUserMailAccount publicMailAccount = null;
|
|
|
|
|
|
if (usePersonalEmailSend)
|
|
|
{
|
|
|
publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.CreatedUserId == UserManager.UserId
|
|
|
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//这个是公共邮箱配置
|
|
|
publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == UserManager.TENANT_ID && x.ShowName == "PublicSend"
|
|
|
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
|
|
|
}
|
|
|
|
|
|
if (publicMailAccount == null)
|
|
|
{
|
|
|
throw Oops.Oh($"提取公共邮箱配置失败,请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱");
|
|
|
}
|
|
|
|
|
|
_logger.LogInformation($"提取当前公共邮箱的配置完成,id={publicMailAccount.Id}");
|
|
|
|
|
|
|
|
|
EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto
|
|
|
{
|
|
|
SendTo = toEmail,
|
|
|
//CCTo = opEmail,
|
|
|
Title = emailTitle,
|
|
|
Body = emailHtml,
|
|
|
Account = publicMailAccount.MailAccount?.Trim(),
|
|
|
Password = publicMailAccount.Password?.Trim(),
|
|
|
Server = publicMailAccount.SmtpServer?.Trim(),
|
|
|
Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465,
|
|
|
UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true,
|
|
|
Attaches = new List<AttachesInfo>()
|
|
|
};
|
|
|
|
|
|
//如果配置了租户参数(AUTO_TRANS_EMAIL_OP_CCTO-自动转发是否默认抄送操作=ENABLE)发送邮件时自动抄送操作
|
|
|
DjyTenantParamValueOutput paramConfig = _djyTenantParamService.GetParaCodeWithValue(new[] { "AUTO_TRANS_EMAIL_OP_CCTO" }).GetAwaiter().GetResult().FirstOrDefault();
|
|
|
|
|
|
if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
emailApiUserDefinedDto.CCTo = opEmail;
|
|
|
|
|
|
}
|
|
|
|
|
|
_logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}");
|
|
|
|
|
|
string filePath = string.Empty;
|
|
|
//推送邮件
|
|
|
var emailRlt = await PushEmail(emailApiUserDefinedDto, filePath);
|
|
|
|
|
|
_logger.LogInformation($"推送邮件完成,结果:{JSON.Serialize(emailRlt)}");
|
|
|
|
|
|
if (emailRlt.succ)
|
|
|
{
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = emailRlt.msg;
|
|
|
|
|
|
new EmailNoticeHelper().SendEmailNotice($"MBLNO={mblNo} 转发预甩通知邮件失败", $"MBLNO={mblNo} 转发预甩通知邮件失败,原因:{emailRlt.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"推送邮件失败,原因:{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 推送邮件
|
|
|
/// <summary>
|
|
|
/// 推送邮件
|
|
|
/// </summary>
|
|
|
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
|
|
|
/// <param name="filePath">文件路径</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<CommonWebApiResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto, string filePath)
|
|
|
{
|
|
|
CommonWebApiResult result = new CommonWebApiResult { succ = true };
|
|
|
|
|
|
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
|
|
|
|
|
|
var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value;
|
|
|
|
|
|
if (emailUrl == null)
|
|
|
throw Oops.Bah("字典未配置 url_set->email_api_url 请联系管理员");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(filePath))
|
|
|
{
|
|
|
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
|
int SplitSize = 5242880;//5M分片长度
|
|
|
int index = 1; //序号 第几片
|
|
|
long StartPosition = 5242880 * (index - 1);
|
|
|
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
|
|
|
if (lastLens < 5242880)
|
|
|
{
|
|
|
SplitSize = (int)lastLens;
|
|
|
}
|
|
|
byte[] heByte = new byte[SplitSize];
|
|
|
file.Seek(StartPosition, SeekOrigin.Begin);
|
|
|
//第一个参数是 起始位置
|
|
|
file.Read(heByte, 0, SplitSize);
|
|
|
//第三个参数是 读取长度(剩余长度)
|
|
|
file.Close();
|
|
|
|
|
|
string base64Str = Convert.ToBase64String(heByte);
|
|
|
|
|
|
emailApiUserDefinedDto.Attaches.Add(new AttachesInfo
|
|
|
{
|
|
|
AttachName = Path.GetFileName(filePath).Replace("_MODIFY", ""),
|
|
|
AttachContent = base64Str
|
|
|
});
|
|
|
}
|
|
|
|
|
|
emailList.Add(emailApiUserDefinedDto);
|
|
|
|
|
|
//string strJoin = System.IO.File.ReadAllText(filePath);
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
HttpResponseMessage res = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
res = await emailUrl.SetBody(emailList, "application/json").PostAsync();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"发送邮件异常:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
//_logger.LogInformation($"邮件上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,");
|
|
|
|
|
|
_logger.LogInformation($"发送邮件返回:{JSON.Serialize(res)}");
|
|
|
|
|
|
if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
|
|
|
{
|
|
|
Success = false,
|
|
|
Message = string.Empty,
|
|
|
Code = -9999,
|
|
|
});
|
|
|
|
|
|
result.succ = respObj.Success;
|
|
|
result.msg = respObj.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|