using Furion;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using Mapster;
using MathNet.Numerics.LinearAlgebra.Factorization;
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.Core;
using Myshipping.Core.Entity;
using Myshipping.Core.Helper;
using Myshipping.Core.Service;
using MySqlX.XDevAPI.Common;
using NetTaste;
using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Crypto;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
namespace Myshipping.Application
{
///
/// 派车服务
///
[ApiDescriptionSettings("Application", Name = "BookingTruck", Order = 9)]
public class BookingTruckService : IBookingTruckService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger _logger;
private readonly SqlSugarRepository _bookingTruckRepository;
private readonly SqlSugarRepository _bookingTruckContaRepository;
private readonly SqlSugarRepository _bookingOrderRepository;
private readonly SqlSugarRepository _bookingCtnRepository;
private readonly SqlSugarRepository _bookingPrintTemplateRepository;
private readonly SqlSugarRepository _djyUserConfigConfig;
private readonly SqlSugarRepository _bookingExcelTemplateRepository;
private readonly SqlSugarRepository _sysUserRepository;
private readonly ITaskManageExternalService _taskManageExternalService;
private readonly ISysUserService _sysUserService;
private readonly IDjyCustomerService _djyCustomerService;
private readonly IBookingOrderService _bookingOrderService;
const string PRINT_LIST_TYPE_KEY = "booking_truck_print_list";
const string PRINT_DATASOURCE_KEY = "booking_order";
const string MQ_EXCHANGE_NAME = "djy.output.booktruck.ds6";
const string MQ_QUEUE_NAME = "djy.output.booktruck.ds6";
public BookingTruckService(ISysCacheService cache, ILogger logger,
SqlSugarRepository bookingTruckRepository,
SqlSugarRepository bookingTruckContaRepository,
SqlSugarRepository bookingOrderRepository,
SqlSugarRepository bookingCtnRepository,
SqlSugarRepository bookingPrintTemplateTemplate,
SqlSugarRepository djyUserConfigConfig,
SqlSugarRepository bookingExcelTemplateRepository,
SqlSugarRepository sysUserRepository,
ISysUserService sysUserService, IDjyCustomerService djyCustomerService,
IBookingOrderService bookingOrderService,
ITaskManageExternalService taskManageExternalService)
{
_cache = cache;
_logger = logger;
_bookingTruckRepository = bookingTruckRepository;
_bookingTruckContaRepository = bookingTruckContaRepository;
_bookingOrderRepository = bookingOrderRepository;
_bookingCtnRepository = bookingCtnRepository;
_taskManageExternalService = taskManageExternalService;
_bookingPrintTemplateRepository = bookingPrintTemplateTemplate;
_djyUserConfigConfig = djyUserConfigConfig;
_bookingExcelTemplateRepository = bookingExcelTemplateRepository;
_sysUserRepository = sysUserRepository;
_sysUserService = sysUserService;
_djyCustomerService = djyCustomerService;
_bookingOrderService = bookingOrderService;
}
///
/// 保存派车
///
/// 派车信息
/// 返回回执
[HttpPost("/BookingTruck/Save")]
public async Task Save(BookingTruckDto info)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var id = await InnerSave(info);
result.succ = true;
result.msg = "保存成功";
result.ext = id;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"保存派车异常,原因:{ex.Message}";
}
return result;
}
///
/// 保存内部方法
///
/// 派车信息
/// 是否回写
/// 返回派车Id
[SqlSugarUnitOfWork]
private async Task InnerSave(BookingTruckDto info, bool isCallBack = false)
{
BookingTruck entity = info.Adapt();
if (entity == null)
throw Oops.Oh($"派车信息不能为空", typeof(InvalidOperationException));
List entityCtnList = info.ContaList.Adapt>();
if (entityCtnList != null && entityCtnList.Count > 0)
{
//保存时默认统计箱型箱量
entity.CntrTotal = string.Join(";", entityCtnList.GroupBy(a => a.CTNALL)
.Select(a =>
{
return $"{a.Key}*{a.ToList().Sum(b => b.CTNNUM.HasValue ? b.CTNNUM.Value : 1)}";
}).ToArray());
}
if (entity.DispatcherId.HasValue && entity.DispatcherId.Value > 0)
{
var dispatchUser = _sysUserRepository.AsQueryable().First(a => a.Id == entity.DispatcherId.Value);
if (dispatchUser != null)
entity.DispatcherName = dispatchUser.Name;
}
if (entity.Id == 0 && !isCallBack)
{
entity.Status = BookingTruckStatus.TEMP.ToString();
_bookingTruckRepository.Insert(entity);
if (entityCtnList != null && entityCtnList.Count > 0)
{
entityCtnList.ForEach(async ctn =>
{
ctn.TruckId = entity.Id;
await _bookingTruckContaRepository.InsertAsync(ctn);
});
}
}
else
{
var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == entity.Id);
if (model == null)
throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException));
if (!isCallBack)
{
//校验
ValidateTruck(OperateTypeEnum.Save, new BookingTruck[] { model });
entity.UpdatedTime = DateTime.Now;
entity.UpdatedUserId = UserManager.UserId;
entity.UpdatedUserName = UserManager.Name;
await _bookingTruckRepository.AsUpdateable(entity).IgnoreColumns(it => new
{
it.TenantId,
it.CreatedTime,
it.CreatedUserId,
it.CreatedUserName,
it.IsDeleted,
it.BookingId,
it.TruckId,
it.TruckName,
it.TruckCode,
it.Status,
it.TruckFlowNo,
it.TaskNo
}).ExecuteCommandAsync();
}
else
{
ValidateTruck(OperateTypeEnum.DispatchBackSave, new BookingTruck[] { model });
entity.UpdatedTime = DateTime.Now;
entity.UpdatedUserId = UserManager.UserId;
entity.UpdatedUserName = UserManager.Name;
entity.Status = info.CallBackStatus;
await _bookingTruckRepository.AsUpdateable(entity).IgnoreColumns(it => new
{
it.TenantId,
it.CreatedTime,
it.CreatedUserId,
it.CreatedUserName,
it.IsDeleted,
it.BookingId,
it.TruckFlowNo,
it.TaskNo
}).ExecuteCommandAsync();
}
await _bookingTruckContaRepository.DeleteAsync(x => x.TruckId == model.Id);
if (entityCtnList != null && entityCtnList.Count > 0)
{
entityCtnList.ForEach(async ctn =>
{
ctn.TruckId = entity.Id;
await _bookingTruckContaRepository.InsertAsync(ctn);
});
}
}
return entity.Id;
}
///
/// 获取派车详情
///
/// 派车主键
/// 返回回执
[HttpGet("/BookingTruck/GetInfo")]
public async Task GetInfo(long id)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == id);
if (truckOrder == null)
throw Oops.Oh($"派车主键{id}无法获取业务信息");
var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == id).ToList();
BookingTruckShowDto model = truckOrder.Adapt();
if (truckCtnList.Count > 0)
model.ContaList = truckCtnList.Adapt>();
result.succ = true;
result.ext = model;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"获取派车详情异常,原因:{ex.Message}";
}
return result;
}
///
/// 订舱生成派车初始信息
///
/// 订舱主键
/// 返回派车初始信息
[HttpGet("/BookingTruck/InitFromBookingOrder")]
public async Task InitFromBookingOrder(long bookingId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var model = await InnerCreateTruckFromBookingOrder(bookingId);
result.succ = true;
result.ext = model;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"订舱生成派车初始信息异常,原因:{ex.Message}";
}
return result;
}
///
/// 派车台账查询
///
/// 派车台账查询请求
/// 返回结果
[HttpPost("/BookingTruck/GetPage")]
public async Task> GetPageAsync([FromBody] QueryBookingTruckDto QuerySearch)
{
List contaList = new List();
if (!string.IsNullOrWhiteSpace(QuerySearch.ContaNo))
{
if (Regex.IsMatch(QuerySearch.ContaNo, "(\\t|\\n\\r|\\n)"))
{
contaList = Regex.Replace(QuerySearch.ContaNo, "(\\t |\\n\\r |\\n)", "#").Split(new char[] { '#' }).Select(t => t?.Trim()).ToList();
}
else
{
contaList.Add(QuerySearch.ContaNo.Trim());
}
}
//制单日期
DateTime createBegin = DateTime.MinValue;
DateTime createEnd = DateTime.MinValue;
//派车日期
DateTime truckDateBegin = DateTime.MinValue;
DateTime truckDateEnd = DateTime.MinValue;
//截单日期
DateTime closeDateBegin = DateTime.MinValue;
DateTime closeDateEnd = DateTime.MinValue;
//提货日期
DateTime pickUpTimeBegin = DateTime.MinValue;
DateTime pickUpTimeEnd = DateTime.MinValue;
//返场时间
DateTime returnTimeBegin = DateTime.MinValue;
DateTime returnTimeEnd = DateTime.MinValue;
//要求到达时间
DateTime needArriveTimeBegin = DateTime.MinValue;
DateTime needArriveTimeEnd = DateTime.MinValue;
#region 查询条件
//制单日期
if (!string.IsNullOrWhiteSpace(QuerySearch.CreateBegin))
{
if (!DateTime.TryParse(QuerySearch.CreateBegin, out createBegin))
throw Oops.Oh($"创建起始日期格式错误,{QuerySearch.CreateBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.CreateEnd))
{
if (!DateTime.TryParse(QuerySearch.CreateEnd, out createEnd))
throw Oops.Oh($"创建结束日期格式错误,{QuerySearch.CreateEnd}");
createEnd = createEnd.AddDays(1);
}
//派车日期
if (!string.IsNullOrWhiteSpace(QuerySearch.TruckTimeBegin))
{
if (!DateTime.TryParse(QuerySearch.TruckTimeBegin, out truckDateBegin))
throw Oops.Oh($"派车起始日期格式错误,{QuerySearch.TruckTimeBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.TruckTimeEnd))
{
if (!DateTime.TryParse(QuerySearch.TruckTimeEnd, out truckDateEnd))
throw Oops.Oh($"派车结束日期格式错误,{QuerySearch.TruckTimeEnd}");
truckDateEnd = truckDateEnd.AddDays(1);
}
//截单日期
if (!string.IsNullOrWhiteSpace(QuerySearch.ClosingTimeBegin))
{
if (!DateTime.TryParse(QuerySearch.ClosingTimeBegin, out closeDateBegin))
throw Oops.Oh($"截单起始日期格式错误,{QuerySearch.ClosingTimeBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.ClosingTimeEnd))
{
if (!DateTime.TryParse(QuerySearch.ClosingTimeEnd, out closeDateEnd))
throw Oops.Oh($"截单结束日期格式错误,{QuerySearch.ClosingTimeEnd}");
closeDateEnd = closeDateEnd.AddDays(1);
}
//提货日期
if (!string.IsNullOrWhiteSpace(QuerySearch.PickUpTimeBegin))
{
if (!DateTime.TryParse(QuerySearch.PickUpTimeBegin, out pickUpTimeBegin))
throw Oops.Oh($"提货起始日期格式错误,{QuerySearch.PickUpTimeBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.PickUpTimeEnd))
{
if (!DateTime.TryParse(QuerySearch.ClosingTimeEnd, out pickUpTimeEnd))
throw Oops.Oh($"提货结束日期格式错误,{QuerySearch.PickUpTimeEnd}");
pickUpTimeEnd = pickUpTimeEnd.AddDays(1);
}
//返场时间
if (!string.IsNullOrWhiteSpace(QuerySearch.ReturnTimeBegin))
{
if (!DateTime.TryParse(QuerySearch.ReturnTimeBegin, out returnTimeBegin))
throw Oops.Oh($"返场起始日期格式错误,{QuerySearch.ReturnTimeBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.ReturnTimeEnd))
{
if (!DateTime.TryParse(QuerySearch.ReturnTimeEnd, out returnTimeEnd))
throw Oops.Oh($"返场结束日期格式错误,{QuerySearch.ReturnTimeEnd}");
returnTimeEnd = returnTimeEnd.AddDays(1);
}
//要求到达时间
if (!string.IsNullOrWhiteSpace(QuerySearch.NeedArriveTimeBegin))
{
if (!DateTime.TryParse(QuerySearch.NeedArriveTimeBegin, out needArriveTimeBegin))
throw Oops.Oh($"返场起始日期格式错误,{QuerySearch.NeedArriveTimeBegin}");
}
if (!string.IsNullOrWhiteSpace(QuerySearch.NeedArriveTimeEnd))
{
if (!DateTime.TryParse(QuerySearch.NeedArriveTimeEnd, out needArriveTimeEnd))
throw Oops.Oh($"返场结束日期格式错误,{QuerySearch.NeedArriveTimeEnd}");
needArriveTimeEnd = needArriveTimeEnd.AddDays(1);
}
#endregion
string entityOrderCol = "CreatedTime";
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
if (!string.IsNullOrWhiteSpace(QuerySearch.SortField))
entityOrderCol = MapsterExtHelper.GetAdaptProperty(QuerySearch.SortField);
var entities = await _bookingTruckRepository.AsQueryable()
.WhereIF(createBegin != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value >= createBegin)
.WhereIF(createEnd != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value < createEnd)
.WhereIF(truckDateBegin != DateTime.MinValue, t => t.TruckTime.HasValue && t.TruckTime.Value >= truckDateBegin)
.WhereIF(truckDateEnd != DateTime.MinValue, t => t.TruckTime.HasValue && t.TruckTime.Value < truckDateEnd)
.WhereIF(closeDateBegin != DateTime.MinValue, t => t.ClosingTime.HasValue && t.ClosingTime.Value >= closeDateBegin)
.WhereIF(closeDateEnd != DateTime.MinValue, t => t.ClosingTime.HasValue && t.ClosingTime.Value < closeDateEnd)
.WhereIF(pickUpTimeBegin != DateTime.MinValue, t => t.PickUpTime.HasValue && t.PickUpTime.Value >= pickUpTimeBegin)
.WhereIF(pickUpTimeEnd != DateTime.MinValue, t => t.PickUpTime.HasValue && t.PickUpTime.Value < pickUpTimeEnd)
.WhereIF(returnTimeBegin != DateTime.MinValue, t => t.ReturnTime.HasValue && t.ReturnTime.Value >= returnTimeBegin)
.WhereIF(returnTimeEnd != DateTime.MinValue, t => t.ReturnTime.HasValue && t.ReturnTime.Value < returnTimeEnd)
.WhereIF(needArriveTimeBegin != DateTime.MinValue, t => t.NeedArriveTime.HasValue && t.NeedArriveTime.Value >= needArriveTimeBegin)
.WhereIF(needArriveTimeEnd != DateTime.MinValue, t => t.NeedArriveTime.HasValue && t.NeedArriveTime.Value < needArriveTimeEnd)
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Yard), t => t.YARDID.Contains(QuerySearch.Yard) || t.YARD.Contains(QuerySearch.Yard))
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.InYard), t => t.InYardID.Contains(QuerySearch.Yard) || t.InYard.Contains(QuerySearch.Yard))
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Status), t => t.Status == QuerySearch.Status)
.OrderBy(entityOrderCol + (QuerySearch.descSort ? " desc ":" asc "))
.ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize);
return entities.Adapt>();
}
///
/// 订舱主键获取相关派车列表
///
/// 订舱主键
/// 返回派车列表
[HttpGet("/BookingTruck/GetTruckListByBooking")]
public async Task> GetTruckListByBookingAsync(long bookingId)
{
var list = _bookingTruckRepository.AsQueryable().Where(a => a.BookingId == bookingId).ToList();
return list.Adapt>();
}
private async Task InnerCreateTruckFromBookingOrder(long bookingId)
{
BookingTruckShowDto model = null;
//取订舱主信息
var orderInfo = _bookingOrderRepository.AsQueryable()
.First(a => a.Id == bookingId);
if (orderInfo == null)
throw Oops.Oh($"订舱主键{bookingId}无法获取业务信息");
model = new BookingTruckShowDto();
model.YARDID = orderInfo.YARDID;
model.YARD = orderInfo.YARD;
model.InYardID = orderInfo.YARDID;
model.InYard = orderInfo.YARD;
model.MBLNo = orderInfo.MBLNO;
model.Vessel = orderInfo.VESSEL;
model.VoyNo = orderInfo.VOYNO;
model.YARDCONTRACT = orderInfo.YARDCONTRACT;
model.YARDCONTRACTTEL = orderInfo.YARDCONTRACTTEL;
model.ClosingTime = orderInfo.CLOSINGDATE;
if (orderInfo.CLOSINGDATE.HasValue)
{
model.ReturnTime = orderInfo.CLOSINGDATE.Value;
}
model.TruckTime = DateTime.Now;
model.FromName = UserManager.Name;
model.FromTel = UserManager.TEl;
model.FromMail = UserManager.Email;
model.FromMobile = UserManager.Phone;
//这里岗位是调度的信息,如果默认只有一条记录,取第一条,其他情况不返回默认值
var userPosInfo = await _sysUserService.QueryUserByPos("", "PCDD");
if (userPosInfo.Count == 1)
{
model.DispatcherId = userPosInfo.FirstOrDefault().SysEmpId;
model.DispatcherName = userPosInfo.FirstOrDefault().SysEmpName;
}
var yardList = await _djyCustomerService.QuerytDjyCustomerInfo("", new string[] { "yard" }, 999);
if (yardList.Count > 0)
{
if ((string.IsNullOrWhiteSpace(model.YARDCONTRACT) || string.IsNullOrWhiteSpace(model.YARDCONTRACTTEL))
&& !string.IsNullOrWhiteSpace(model.YARD))
{
var currYardList = yardList.Select(a =>
{
return new
{
KNum = a.ShortName.IndexOf(model.YARD),
Equls = a.ShortName.Equals(model.YARD, StringComparison.OrdinalIgnoreCase) ? 1 : 0,
Obj = a
};
}).Where(a => a.KNum >= 0).ToList();
if (currYardList.Count > 0)
{
var yardInfo = currYardList
.OrderByDescending(a => a.Equls)
.ThenBy(a => a.KNum)
.FirstOrDefault().Obj;
if (yardInfo != null)
{
if (string.IsNullOrWhiteSpace(model.YARDCONTRACT))
{
model.YARDCONTRACT = yardInfo.Chief?.Trim();
}
if (string.IsNullOrWhiteSpace(model.YARDCONTRACTTEL))
model.YARDCONTRACTTEL = yardInfo.Tel?.Trim();
}
}
}
}
model.InYardContact = model.YARDCONTRACT;
model.InYardContractTel = model.YARDCONTRACTTEL;
if (orderInfo.KGS.HasValue)
{
//计算总吨数
model.KGS = Math.Round(orderInfo.KGS.Value / 1000m, 3);
}
//取订舱箱列表
var ctnList = _bookingCtnRepository.AsQueryable()
.Where(a => a.BILLID == bookingId).ToList();
if (ctnList.Count > 0)
{
model.ContaList = new List();
ctnList.ForEach(b =>
{
if (b.CTNNUM == 1)
{
model.ContaList.Add(new BookingTruckCtnDto
{
CTNCODE = b.CTNCODE,
CTNALL = b.CTNALL,
KGS = b.KGS,
PKGS = b.PKGS,
CBM = b.CBM,
TAREWEIGHT = b.TAREWEIGHT,
CNTRNO = b.CNTRNO,
KINDPKGS = b.KINDPKGS,
SEALNO = b.SEALNO,
TEU = b.TEU,
CTNNUM = 1,
});
}
else
{
for (int i = 0; i < b.CTNNUM; i++)
{
model.ContaList.Add(new BookingTruckCtnDto
{
CTNCODE = b.CTNCODE,
CTNALL = b.CTNALL,
KGS = b.KGS,
PKGS = b.PKGS,
CBM = b.CBM,
TAREWEIGHT = b.TAREWEIGHT,
CNTRNO = b.CNTRNO,
KINDPKGS = b.KINDPKGS,
SEALNO = b.SEALNO,
TEU = b.TEU,
CTNNUM = 1,
});
}
}
});
}
/*
2023-08-14 这里按照调度要求,如果有历史单据,新增时需要读取前一票的部分信息
(实际毛重、开票方式、提货工厂、工厂联系人+电话、工厂地址、派车单备注)
*/
var lastBookingTruckModel = _bookingTruckRepository.AsQueryable()
.Where(a => a.BookingId == bookingId && !a.IsDeleted)
.OrderBy(a => a.CreatedTime).First();
if (lastBookingTruckModel != null)
{
if (lastBookingTruckModel.KGS.HasValue)
model.KGS = lastBookingTruckModel.KGS;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.PayMethod))
model.PayMethod = lastBookingTruckModel.PayMethod;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.PayMethodName))
model.PayMethodName = lastBookingTruckModel.PayMethodName;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.Remark))
model.Remark = lastBookingTruckModel.Remark;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.FactoryContact))
model.FactoryContact = lastBookingTruckModel.FactoryContact;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.FactoryAddr))
model.FactoryAddr = lastBookingTruckModel.FactoryAddr;
if (!string.IsNullOrWhiteSpace(lastBookingTruckModel.FactoryName))
model.FactoryName = lastBookingTruckModel.FactoryName;
if (lastBookingTruckModel.NeedArriveTime.HasValue)
model.NeedArriveTime = lastBookingTruckModel.NeedArriveTime;
}
return model;
}
///
/// 引入订舱详情生成派车信息
///
/// 订舱主键
/// 返回派车初始信息
[HttpGet("/BookingTruck/PullInBookingOrder")]
public async Task PullInBookingOrder(long bookingId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var model = await InnerCreateTruckFromBookingOrder(bookingId);
result.succ = true;
result.ext = model;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"引入订舱详情生成派车信息异常,原因:{ex.Message}";
}
return result;
}
///
/// 引入订舱集装箱详情生成派车信息
///
/// 订舱主键
/// 返回派车集装箱初始信息
[HttpGet("/BookingTruck/PullInBookingOrderConta")]
public async Task PullInBookingOrderConta(long bookingId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var model = await InnerCreateTruckFromBookingOrder(bookingId);
result.succ = true;
if (model != null && model.ContaList != null && model.ContaList.Count > 0)
{
result.ext = model.ContaList;
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"引入订舱详情生成派车信息异常,原因:{ex.Message}";
}
return result;
}
///
/// 提交派车
///
/// 派车信息
/// 返回回执
[HttpPost("/BookingTruck/Submit")]
public async Task Submit(BookingTruckDto info)
{
string batchNo = IDGen.NextID().ToString();
_logger.LogInformation("批次={no}获取提交派车请求 {id}", batchNo, info.Id);
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
result = await InnerSubmit(info, batchNo);
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage();
}
return result;
}
#region 提交内部方法
///
/// 提交内部方法
///
/// 派车信息
/// 批次号
/// 返回回执
private async Task InnerSubmit(BookingTruckDto info, string batchNo, bool isDefaultSave = true)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
/*
提交派车流程
1、先保存一遍派车信息。(需校验当前派车信息未提交,只有暂存的才能保存)
2、调取派车任务接口推送派车任务。
3、派车任务推送成功后更新状态、任务ID。
4、返回结果。
*/
try
{
//先保存
var id = info.Id;
if (isDefaultSave)
id = InnerSave(info).GetAwaiter().GetResult();
//校验
var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == id);
if (model == null)
throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException));
var bookingOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == model.BookingId);
//校验
ValidateTruck(OperateTypeEnum.Submit, new BookingTruck[] { model });
var contaList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == id).ToList();
DateTime bDate = DateTime.Now;
string vesselVoyno = string.Empty;
if (!string.IsNullOrWhiteSpace(bookingOrder.VESSEL))
{
vesselVoyno = bookingOrder.VESSEL;
}
if (!string.IsNullOrWhiteSpace(bookingOrder.VOYNO))
{
vesselVoyno = $"{vesselVoyno}/{bookingOrder.VOYNO}";
}
TaskManageOrderMessageInfo messageInfo = new TaskManageOrderMessageInfo
{
Head = new TaskManageOrderMessageHeadInfo
{
GID = id.ToString(),//直接用派车的主键
MessageType = "TASK",
SenderId = "BookingOrder",
SenderName = "订舱派车",
ReceiverId = "TaskManage",
ReceiverName = "派车任务",
RequestDate = bDate.ToString("yyyy-MM-dd HH:mm:ss.fff"),
Version = "1.0",
RequestAction = "Add"
},
Main = new TaskManageOrderMessageMainInfo
{
TaskType = TaskBaseTypeEnum.TRUCK_DISPATCH,
TruckInfo = model.Adapt(),
MBlNo = bookingOrder.MBLNO,
ETD = bookingOrder.ETD,
VesselVoyno = vesselVoyno,
TaskUserId = UserManager.UserId.ToString(),
TaskUserName = UserManager.Name,
ContaInfo = model.CntrTotal,
YardName = model.InYard,
CarrierId = bookingOrder.CARRIERID,
CustomerId = bookingOrder.CUSTOMERID,
CustomerName = bookingOrder.CUSTOMERNAME
}
};
if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.Vessel)
&& !string.IsNullOrWhiteSpace(bookingOrder.VESSEL))
{
messageInfo.Main.TruckInfo.Vessel = bookingOrder.VESSEL;
}
if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.VoyNo)
&& !string.IsNullOrWhiteSpace(bookingOrder.VOYNO))
{
messageInfo.Main.TruckInfo.VoyNo = bookingOrder.VOYNO;
}
if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.MBLNo)
&& !string.IsNullOrWhiteSpace(bookingOrder.MBLNO))
{
messageInfo.Main.TruckInfo.MBLNo = bookingOrder.MBLNO;
}
if (contaList.Count > 0)
messageInfo.Main.TruckInfo.ContaList = contaList.Adapt>();
messageInfo.Main.TaskUserId = UserManager.UserId.ToString();
messageInfo.Main.TaskUserName = UserManager.Name;
messageInfo.Main.RecvUserId = model.DispatcherId.ToString();
messageInfo.Main.RecvUserName = model.DispatcherName;
messageInfo.Main.TaskTitle = $"{model.TruckFlowNo}_派车任务";
messageInfo.Main.TaskDesp = $"{model.TruckFlowNo}_派车任务";
messageInfo.Main.TaskSource = TaskSourceEnum.CUSTOMER_SUBMIT;
_logger.LogInformation("批次={no} 请求报文msg={msg}", batchNo, JSON.Serialize(messageInfo));
//推送新增派车任务接口
var taskRlt = await _taskManageExternalService.SubmitTruckDispatchAsync(messageInfo);
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(taskRlt));
if (!taskRlt.succ)
{
throw Oops.Oh($"请求派车调度失败,原因={taskRlt.msg}", typeof(InvalidOperationException));
}
//更新派车订单为已提交
model.Status = BookingTruckStatus.SUBMITED.ToString();
model.UpdatedTime = DateTime.Now;
model.UpdatedUserId = UserManager.UserId;
model.UpdatedUserName = UserManager.Name;
//提取任务流水号
if (taskRlt.ext != null)
model.TaskNo = taskRlt.ext.ToString();
await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new
{
it.Status,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.TaskNo
}).ExecuteCommandAsync();
result.succ = true;
result.msg = "提交成功";
//这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获
try
{
//派车后填写货物状态
await _bookingOrderService.SetGoodsStatus("YPC", bookingOrder.Id);
_logger.LogInformation("批次={no} id={id} 更新订舱的货物状态完成", batchNo, bookingOrder.Id);
}
catch (Exception bkException)
{
_logger.LogInformation("批次={no} id={id} 更新订舱的货物状态 YPC异常,原因:{erro}", batchNo, bookingOrder.Id, bkException.Message);
}
//这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获
try
{
//触发发送东胜
var currRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingOrder.Id });
string curMsg = JSON.Serialize(currRlt);
_logger.LogInformation("批次={no} id={id} 触发发送东胜完成 结果={rlt}", batchNo, bookingOrder.Id, curMsg);
}
catch (Exception bkException)
{
_logger.LogInformation("批次={no} id={id} 触发发送东胜完成,原因:{erro}", batchNo, bookingOrder.Id, bkException.Message);
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("提交失败");
}
return result;
}
#endregion
#region 批量提交派车
///
/// 批量提交派车
///
/// 派车主键组
/// 返回回执
[HttpPost("/BookingTruck/SubmitBatch")]
public async Task SubmitBatch([FromBody] long[] ids)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
string batchNo = IDGen.NextID().ToString();
_logger.LogInformation("批次={no}获取提交派车请求 {ids}", batchNo, ids);
try
{
var list = _bookingTruckRepository.AsQueryable()
.Where(a => ids.Contains(a.Id)).ToList();
if (list.Count != ids.Length)
throw Oops.Oh($"部分派车信息获取失败,不能提交,派车信息不存在或已作废");
//校验
ValidateTruck(OperateTypeEnum.Submit, list.ToArray());
List> taskList = new List>();
list.ForEach(async tk =>
{
taskList.Add(InnerSubmit(new BookingTruckDto { Id = tk.Id }, batchNo, false));
});
//等待所有结果
Task.WaitAll(taskList.ToArray(), 20000);
result.succ = true;
result.msg = "提交成功";
List msgList = new List();
taskList.ForEach(async a =>
{
var rlt = a.Result;
if (!rlt.succ)
{
result.succ = false;
msgList.Add($"派车单号:{rlt.ext.ToString()},{rlt.msg}");
result.msg = "提交失败";
}
});
result.ext = msgList;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"批量提交派车异常,原因:{ex.Message}";
}
return result;
}
#endregion
///
/// 撤销派车
///
/// 派车主键
/// 是否撤销后自动删除 true-删除 false-不删除
/// 返回回执
[HttpGet("/BookingTruck/Cancel")]
public async Task Cancel([FromQuery] long id, [FromQuery] bool isAfterDelete = false)
{
/*
撤销派车流程
1、确定当前派车已提交。
2、调取取消派车任务接口,申请撤销派车。
3、取消派车推送成功后更新状态。
4、返回结果。
*/
string batchNo = IDGen.NextID().ToString();
_logger.LogInformation("批次={no}获取撤销派车请求 {id}", batchNo, id);
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
result = await InnerCancel(id, batchNo, isAfterDelete);
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage();
}
return result;
}
///
/// 批量撤销派车
///
/// 派车主键组
/// 返回回执
[HttpPost("/BookingTruck/CancelBatch")]
public async Task CancelBatch([FromBody] long[] ids)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
/*
批量撤销派车流程
1、确定当前派车已提交。
2、调取取消派车任务接口,申请撤销派车。
3、取消派车推送成功后更新状态。
4、返回结果。
*/
string batchNo = IDGen.NextID().ToString();
_logger.LogInformation("批次={no}获取撤销派车请求 {ids}", batchNo, ids);
try
{
var list = _bookingTruckRepository.AsQueryable()
.Where(a => ids.Contains(a.Id)).ToList();
if (list.Count != ids.Length)
throw Oops.Oh($"部分派车信息获取失败,不能撤销,派车信息不存在或已作废");
//校验
ValidateTruck(OperateTypeEnum.Submit, list.ToArray());
List> taskList = new List>();
list.ForEach(async tk =>
{
taskList.Add(InnerCancel(tk.Id, batchNo));
});
//等待所有结果
Task.WaitAll(taskList.ToArray(), 20000);
result.succ = true;
result.msg = "撤销成功";
List msgList = new List();
taskList.ForEach(async a =>
{
var rlt = a.Result;
if (!rlt.succ)
{
result.succ = false;
msgList.Add($"派车单号:{rlt.ext.ToString()},{rlt.msg}");
result.msg = "撤销失败";
}
});
result.ext = msgList;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"撤销派车异常,原因:{ex.Message}";
}
return result;
}
#region 内部撤销派车
///
/// 内部撤销派车
///
/// 派车主键
/// 批次号
/// 是否撤销后自动删除 true-删除 false-不删除
/// 返回回执
private async Task InnerCancel(long id, string batchNo, bool isAfterDelete = false)
{
/*
撤销派车流程
1、确定当前派车已提交。
2、调取取消派车任务接口,申请撤销派车。
3、取消派车推送成功后更新状态。
4、返回结果。
*/
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
//校验
var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == id);
if (model == null)
throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException));
//如果选择了之后删除并且当前派车单是暂存或已撤销,则直接删除
if (isAfterDelete && model.Status == BookingTruckStatus.TEMP.ToString()
|| model.Status == BookingTruckStatus.CANCELED.ToString())
{
model.UpdatedTime = DateTime.Now;
model.UpdatedUserId = UserManager.UserId;
model.UpdatedUserName = UserManager.Name;
await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new
{
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.IsDeleted
}).ExecuteCommandAsync();
result.succ = true;
result.msg = "删除成功";
return result;
}
//校验
ValidateTruck(OperateTypeEnum.Cancel, new BookingTruck[] { model });
DateTime bDate = DateTime.Now;
TaskManageOrderMessageInfo messageInfo = new TaskManageOrderMessageInfo
{
Head = new TaskManageOrderMessageHeadInfo
{
GID = id.ToString(),//直接用派车的主键
MessageType = "TASK",
SenderId = "BookingOrder",
SenderName = "订舱派车",
ReceiverId = "TaskManage",
ReceiverName = "派车任务",
RequestDate = bDate.ToString("yyyy-MM-dd HH:mm:ss.fff"),
Version = "1.0",
RequestAction = "Add"
},
Main = new TaskManageOrderMessageMainInfo
{
TaskType = TaskBaseTypeEnum.TRUCK_DISPATCH,
TruckInfo = model.Adapt(),
}
};
messageInfo.Main.TaskUserId = UserManager.UserId.ToString();
messageInfo.Main.TaskUserName = UserManager.Name;
messageInfo.Main.TaskTitle = $"{model.MBLNo}_派车任务";
messageInfo.Main.TaskDesp = $"{model.MBLNo}_派车任务";
messageInfo.Main.TaskSource = TaskSourceEnum.CUSTOMER_SUBMIT;
_logger.LogInformation("批次={no} 请求报文msg={msg}", batchNo, JSON.Serialize(messageInfo));
//推送取消派车任务接口
var taskRlt = await _taskManageExternalService.CancelTruckDispatchAsync(messageInfo);
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(taskRlt));
if (!taskRlt.succ)
{
throw Oops.Oh($"请求撤销派车调度失败,原因={taskRlt.msg}", typeof(InvalidOperationException));
}
//操作取消派车任务成功后,立即触发清空订舱的车队信息,并触发东胜同步删除
BookingTruckDto bookingTruckDto = model.Adapt();
bookingTruckDto.CallBackStatus = BookingTruckStatus.CANCEL_DISPATCH.ToString();
var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == model.Id).ToList();
if (truckCtnList.Count > 0)
bookingTruckDto.ContaList = truckCtnList.Adapt>();
bookingTruckDto.Id = model.Id;
_logger.LogInformation("批次={no} 准备触发取消回写 报文={msg}", batchNo, JSON.Serialize(bookingTruckDto));
//触发取消回写
var callBackRlt = await TruckDispatchCompleteCallBack(bookingTruckDto);
_logger.LogInformation("批次={no} 准备触发取消回写 结果={msg}", batchNo, JSON.Serialize(callBackRlt));
//更新派车订单为已提交
model.Status = BookingTruckStatus.CANCELED.ToString();
model.UpdatedTime = DateTime.Now;
model.UpdatedUserId = UserManager.UserId;
model.UpdatedUserName = UserManager.Name;
model.TaskNo = null;
//是否删除
if (isAfterDelete)
{
model.IsDeleted = true;
await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new
{
it.Status,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.TaskNo,
it.IsDeleted
}).ExecuteCommandAsync();
}
else
{
await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new
{
it.Status,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.TaskNo
}).ExecuteCommandAsync();
}
result.succ = true;
result.msg = "撤销成功";
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("撤销失败");
}
return result;
}
#endregion
///
/// 删除派车
///
/// 派车主键
/// 返回回执
[HttpGet("/BookingTruck/Delete")]
public async Task Delete(long id)
{
//检索
var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == id);
if (truckOrder == null)
throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException));
//先校验
ValidateTruck(OperateTypeEnum.Delete, new BookingTruck[] { truckOrder });
await _bookingTruckRepository.UpdateAsync(x => x.Id == id,
x => new BookingTruck { IsDeleted = true });
_logger.LogInformation("删除派车成功 id={id} user={usr}", id, UserManager.UserId);
return "删除成功";
}
///
/// 批量删除派车
///
/// 派车主键组
/// 返回回执
[HttpPost("/BookingTruck/DeleteBatch")]
public async Task DeleteBatch([FromBody] long[] ids)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
//检索
var truckOrderList = _bookingTruckRepository.AsQueryable()
.Where(a => ids.Contains(a.Id)).ToList();
if (truckOrderList.Count != ids.Length)
throw Oops.Oh($"部分派车信息获取失败,派车信息不存在或已作废");
//先校验
ValidateTruck(OperateTypeEnum.Delete, truckOrderList.ToArray());
truckOrderList.ForEach(async tk =>
{
await _bookingTruckRepository.UpdateAsync(x => x.Id == tk.Id,
x => new BookingTruck { IsDeleted = true });
});
result.succ = true;
result.msg = "删除成功";
_logger.LogInformation("删除派车成功 ids={id} user={usr}", ids, UserManager.UserId);
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("删除派车异常");
}
return result;
}
///
/// 获取订舱打印模板列表(带有当前用户打印历史排序)
///
/// 分类代码(使用字典【booking_template_category】中的代码)
/// 打印分类,10:FastReport、20:Excel模板
///
[HttpGet("/BookingTruck/PrintTemplateWithHistoryList")]
public async Task PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType)
{
var typeCode = printType.ToString();
//当前公司所有已配置的模板
var allList = await _bookingPrintTemplateRepository.AsQueryable()
.Filter(null, true).InnerJoin((d, t) => d.Id == t.PrintTemplateId && t.SysUserId == UserManager.UserId)
.Where(d => d.TenantId == UserManager.TENANT_ID && d.CateCode.Contains(cateCode) && d.Type == typeCode)
.Select(d => new
{
d.Id,
d.CateCode,
d.CateName,
d.DisplayName
})
.ToListAsync();
var listReult = new List();
//当前用户打印历史数据
var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}";
var usrCfg = await _djyUserConfigConfig.AsQueryable().FirstAsync(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey);
if (usrCfg != null)
{
var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).ToList();
//按顺序加入到结果
arr.ForEach(x =>
{
var find = allList.FirstOrDefault(y => y.Id == x);
if (find != null)
{
listReult.Add(find);
}
});
var listOut = allList.Where(x => !arr.Contains(x.Id)).ToList();
listReult.AddRange(listOut);
return listReult;
}
else
{
return allList;
}
}
///
/// 打印派车
///
/// 派车主键
/// 打印模板ID
/// 分类代码(使用字典【booking_template_category】中的代码)
/// 类型,1:pdf、2:xlsx、3:docx
/// 打印类型,10:FastReport、20:Excel模板
/// 返回回执
[HttpGet("/BookingTruck/Print")]
public async Task Print([FromQuery] long id, [FromQuery] long templateId, [FromQuery] string cateCode, [FromQuery] PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF,
[FromQuery] BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport)
{
var printTemplate = await _bookingPrintTemplateRepository.AsQueryable().Filter(null, true)
.FirstAsync(x => x.Id == templateId);
if (printTemplate == null)
{
throw Oops.Bah(BookingErrorCode.BOOK115);
}
var truckOrder = await _bookingTruckRepository.FirstOrDefaultAsync(x => x.Id == id);
if (!truckOrder.NeedArriveTime.HasValue)
{
throw Oops.Oh("要求送达日期不能为空");
}
//var edi = await _bookingEDIExt.FirstOrDefaultAsync(x => x.BookingId == bookingId);
//if (order == null)
//{
// throw Oops.Bah(BookingErrorCode.BOOK001);
//}
var fileName = string.Empty;
//var dicCate = (await _cache.GetAllDictData()).FirstOrDefault(x => x.Code == cateCode && x.TypeCode == "booking_template_category");
//if (dicCate == null)
//{
// throw Oops.Bah("分类代码参数不正确");
//}
if (printType == BookingPrintTemplateType.FastReport)
{
#region FastReport打印
var bs = await GenPrintFile(id, printTemplate, printFileType);
var fileType = "";
if (printFileType == PrintFileTypeEnum.PDF)
{
fileType = ".pdf";
}
else if (printFileType == PrintFileTypeEnum.XLSX)
{
fileType = ".xlsx";
}
else if (printFileType == PrintFileTypeEnum.DOCX)
{
fileType = ".docx";
}
else
{
throw Oops.Bah("类型参数不正确");
}
fileName = $"{DateTime.Now.Ticks}{fileType}";//名称
////2023-4-3,根据河川操作要求,文件名只带提单号
//if (!string.IsNullOrEmpty(order.MBLNO))
//{
// fileName = $"{order.MBLNO}{fileType}";//名称
//}
//else
//{
// fileName = $"{order.Id}_{DateTime.Now.Ticks}{fileType}";//名称
//}
var opt = App.GetOptions().Path;
var serverpath = Path.Combine(App.WebHostEnvironment.WebRootPath, opt);//服务器路径
if (!Directory.Exists(serverpath))
{
Directory.CreateDirectory(serverpath);
}
var fullPath = Path.Combine(serverpath, fileName);
await File.WriteAllBytesAsync(fullPath, bs);
#endregion
}
/*
else if (printType == BookingPrintTemplateType.ExcelTemplate)
{
#region Excel模板打印
var opt = App.GetOptions();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath);
_logger.LogInformation($"准备调用EXCEL生成:id:{id},文件:{printTemplate.FileName}");
var result = new FileStream(fileAbsPath, FileMode.Open);
var excelwork = new HSSFWorkbook(result);
var sheet = excelwork.GetSheetAt(0);
var entity = await _bookingExcelTemplateRepository.AsQueryable()
.Where(x => x.PId == templateId).OrderBy(x => x.Row).ToListAsync();
if (entity == null)
{
throw Oops.Bah("当前模板未设置");
}
for (int _row = 1; _row <= entity.Max(x => x.Row); _row++)
{
if (entity.Where(x => x.Row == _row).Count() > 0)
{
////获取行
var row = sheet.GetRow(_row - 1);
if (row != null)
{
for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++)
{
if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0)
{
var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault();
if (name.Split('.')[0].ToLower() == "order")
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order))
{
var _name = descriptor.Name.ToLower();
if (name.Split('.')[0].ToLower() == "order" && name.Split('.')[1].ToLower() == _name)
{
var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : "";
ICell cell = row.GetCell(_cellNum - 1);
if (descriptor.PropertyType.FullName.Contains("DateTime"))
{
value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : "";
}
if (cell != null)
{
row.Cells[_cellNum - 1].SetCellValue(value);
}
else
{
row.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
}
if (name.Split('.')[0].ToLower() == "edi")
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi))
{
var _name = descriptor.Name.ToLower();
if (name.Split('.')[0].ToLower() == "edi" && name.Split('.')[1].ToLower() == _name)
{
var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : "";
ICell cell = row.GetCell(_cellNum - 1);
if (descriptor.PropertyType.FullName.Contains("DateTime"))
{
value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : "";
}
if (cell != null)
{
row.Cells[_cellNum - 1].SetCellValue(value);
}
else
{
row.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
}
if (name.Split('.')[0].ToLower() == "userinfo")
{
ICell cell = row.GetCell(_cellNum - 1);
var value = string.Empty;
if (name.Split('.')[1].ToLower() == "username")
{
value = UserManager.Name;
}
if (name.Split('.')[1].ToLower() == "usertel")
{
value = UserManager.TEl;
}
if (name.Split('.')[1].ToLower() == "usermobile")
{
value = UserManager.Phone;
}
if (name.Split('.')[1].ToLower() == "useremail")
{
value = UserManager.Email;
}
if (name.Split('.')[1].ToLower() == "usertenant")
{
value = UserManager.TENANT_NAME;
}
if (cell != null)
{
row.Cells[_cellNum - 1].SetCellValue(value);
}
else
{
row.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
}
}
else
{
////创建行
var srow = NpoiExcelExportHelper._.CreateRow(sheet, _row - 1);
for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++)
{
if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0)
{
var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault();
if (name.Split('.')[0].ToLower() == "order")
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order))
{
var _name = descriptor.Name.ToLower();
if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "order")
{
var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : "";
if (descriptor.PropertyType.FullName.Contains("DateTime"))
{
value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : "";
}
srow.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
if (name.Split('.')[0].ToLower() == "edi")
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi))
{
var _name = descriptor.Name.ToLower();
if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "edi")
{
var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : "";
if (descriptor.PropertyType.FullName.Contains("DateTime"))
{
value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : "";
}
srow.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
if (name.Split('.')[0].ToLower() == "userinfo")
{
var value = string.Empty;
if (name.Split('.')[1].ToLower() == "username")
{
value = UserManager.Name;
}
if (name.Split('.')[1].ToLower() == "usertel")
{
value = UserManager.TEl;
}
if (name.Split('.')[1].ToLower() == "usermobile")
{
value = UserManager.Phone;
}
if (name.Split('.')[1].ToLower() == "useremail")
{
value = UserManager.Email;
}
if (name.Split('.')[1].ToLower() == "usertenant")
{
value = UserManager.TENANT_NAME;
}
srow.CreateCell(_cellNum - 1).SetCellValue(value);
}
}
}
}
}
}
var fileFullPath = Path.Combine(App.WebHostEnvironment.WebRootPath, App.GetOptions().Path);//服务器路径
if (!Directory.Exists(fileFullPath))
{
Directory.CreateDirectory(fileFullPath);
}
fileName = $"{DateTime.Now.Ticks}.xls";//名称
////2023-4-3,根据河川操作要求,文件名只带提单号
//if (!string.IsNullOrEmpty(order.MBLNO))
//{
// fileName = $"{order.MBLNO}.xls";//名称
//}
//else
//{
// fileName = $"{order.Id}_{DateTime.Now.Ticks}.xls";//名称
//}
_logger.LogInformation("导出excel:" + Path.Combine(fileFullPath, fileName));
var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite);
excelwork.Write(filestream);
#endregion
}
*/
//记录打印次数和时间,用于前端动态展示常用的打印类型
var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}";
var usrCfg = _djyUserConfigConfig.AsQueryable().First(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey);
if (usrCfg == null)
{
usrCfg = new DjyUserConfig();
usrCfg.Type = printRecentListKey;
usrCfg.ConfigJson = (new long[] { templateId }).ToJson();
await _djyUserConfigConfig.InsertAsync(usrCfg);
}
else
{
var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).Where(x => x != templateId).ToList();
arr.Insert(0, templateId);
usrCfg.ConfigJson = arr.ToArray().ToJson();
await _djyUserConfigConfig.UpdateAsync(usrCfg);
}
return HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
}
///
/// 生成打印报表文件
///
/// 派车ID
/// 打印模板
/// 文档类型,1:pdf、2:xlsx、3:docx
/// 返回文件流
[NonAction]
private async Task GenPrintFile(long bookingTruckId, BookingPrintTemplate printTemplate,
PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF)
{
//打印报表服务地址
var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set"
&& x.Code == "url_report_generate").Value;
if (!reportUrl.EndsWith("/"))
{
reportUrl += "/";
}
var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == bookingTruckId);
if (truckOrder == null)
throw Oops.Oh($"派车主键{bookingTruckId}无法获取业务信息");
var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == bookingTruckId).ToList();
BookingOrder bookingOrder = null;
if (truckOrder.BookingId.HasValue && truckOrder.BookingId.Value > 0)
{
bookingOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == truckOrder.BookingId.Value);
}
BookingTruckPrintDto model = truckOrder.Adapt();
model.IsGuaJi = truckOrder.IsGuaJi ? "需要挂机" : "无";
if (bookingOrder != null)
{
model.Vessel = bookingOrder.VESSEL;
if (!string.IsNullOrWhiteSpace(bookingOrder.VOYNO))
{
model.VoyNo = bookingOrder.VOYNO;
}
else
{
model.VoyNo = bookingOrder.VOYNOINNER;
}
model.MBLNo = bookingOrder.MBLNO;
model.CarrierID = bookingOrder.CARRIERID;
model.Carrier = bookingOrder.CARRIER;
model.DestinationID = bookingOrder.DESTINATIONID;
model.Destination = bookingOrder.DESTINATION;
model.ETD = bookingOrder.ETD;
}
if (truckCtnList.Count > 0)
model.ContaList = truckCtnList.Adapt>();
_logger.LogInformation($"bookingTruckId={bookingTruckId} 请求打印 JSON={JSON.Serialize(model)}");
return await PrintHelper.GeneratePrintFile(JSON.Serialize(model), reportUrl, PRINT_DATASOURCE_KEY,
printFileType, printTemplate);
}
#region 校验派车
///
/// 校验派车
///
/// 操作类型
/// 派车信息列表
private void ValidateTruck(OperateTypeEnum operateType, BookingTruck[] entityArg)
{
if (operateType == OperateTypeEnum.Save)
{
if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString()
&& a.Status != BookingTruckStatus.CANCELED.ToString()))
{
throw Oops.Oh($"派车状态只有暂存、已撤销才能保存", typeof(InvalidOperationException));
}
}
else if (operateType == OperateTypeEnum.Submit)
{
if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString()
&& a.Status != BookingTruckStatus.CANCELED.ToString()))
{
throw Oops.Oh($"派车状态只有暂存、已撤销才能提交", typeof(InvalidOperationException));
}
if (entityArg.Any(a => !a.DispatcherId.HasValue || (a.DispatcherId.HasValue && a.DispatcherId.Value == 0)))
{
throw Oops.Oh($"未填写调度,不能提交", typeof(InvalidOperationException));
}
if (entityArg.Any(a => !a.NeedArriveTime.HasValue))
{
throw Oops.Oh($"未填写要求送达日期,不能提交", typeof(InvalidOperationException));
}
}
else if (operateType == OperateTypeEnum.Cancel)
{
if (entityArg.Any(a => a.Status != BookingTruckStatus.SUBMITED.ToString()
&& a.Status != BookingTruckStatus.SEND_DISPATCH.ToString()))
{
throw Oops.Oh($"派车状态只有已提交、已派车才能撤销派车", typeof(InvalidOperationException));
}
}
else if (operateType == OperateTypeEnum.Delete)
{
if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString()
&& a.Status != BookingTruckStatus.CANCELED.ToString()))
{
throw Oops.Oh($"派车状态只有暂存、已撤销才能作废", typeof(InvalidOperationException));
}
}
else if (operateType == OperateTypeEnum.DispatchBackSave)
{
if (entityArg.Any(a => a.Status != BookingTruckStatus.SUBMITED.ToString()
&& a.Status != BookingTruckStatus.SEND_DISPATCH.ToString()
&& a.Status != BookingTruckStatus.CANCEL_DISPATCH.ToString()))
{
throw Oops.Oh($"派车状态只有已提交才能回写详情", typeof(InvalidOperationException));
}
}
}
#endregion
///
/// 派车任务回写派车详情
///
/// 派车详情
/// 返回回执
[HttpPost("/BookingTruck/TruckDispatchCompleteCallBack")]
public async Task TruckDispatchCompleteCallBack(BookingTruckDto info)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
result.ext2 = info.Id;
try
{
/*
回写逻辑
1、派车任务完成发送派车后,自动回写派车任务表的详情
2、需校验如果派车不是已提交,不能回写。
3、比较差异留存。
*/
var bookingTruckInfo = _bookingTruckRepository.AsQueryable().First(a => a.Id == info.Id);
if (bookingTruckInfo == null)
throw Oops.Oh($"派车信息不存在", typeof(InvalidOperationException));
if (bookingTruckInfo.Status != BookingTruckStatus.SUBMITED.ToString()
&& bookingTruckInfo.Status != BookingTruckStatus.SEND_DISPATCH.ToString()
&& bookingTruckInfo.Status != BookingTruckStatus.CANCEL_DISPATCH.ToString())
throw Oops.Oh($"当前派车信息不是已提交状态不能接收回写", typeof(InvalidOperationException));
var id = await InnerSave(info, true);
BookingTruckSyncMessageInfo messageInfo = new BookingTruckSyncMessageInfo();
string batchNo = IDGen.NextID().ToString();
messageInfo.Head = new BookingTruckSyncMessageHeadInfo
{
GID = info.Id.ToString(),
MessageType = "TRUCK_SYNC",
SenderId = "BOOKING_TRUCK",
SenderName = "订舱派车",
SenderKey = "BOOKING_TRUCK",
ReceiverId = "DongshengHeChuan",
ReceiverName = "东胜和川",
Version = "1.0",
RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
RequestAction = "Sync",
};
BookingTruckSyncMessageMainInfo bookingTruckSyncDto = info.Adapt();
bookingTruckSyncDto.ContaList = info.ContaList.Adapt>();
if (info.CallBackStatus == BookingTruckStatus.CANCEL_DISPATCH.ToString())
{
bookingTruckSyncDto.OperType = "Delete";
var bookingOrder = _bookingOrderRepository.AsQueryable()
.First(a => a.Id == bookingTruckInfo.BookingId.Value);
if (bookingOrder != null)
{
var oldOrder = bookingOrder.Adapt();
_logger.LogInformation("判断回写需要更新去掉订舱的车队 id={id} truckid={truckid} truck={truck}",
bookingTruckInfo.BookingId.Value, bookingOrder.TRUCKERID, bookingOrder.TRUCKER);
bookingOrder.TRUCKERID = null;
bookingOrder.TRUCKER = null;
//bookingOrder.VERSION = IDGen.NextID().ToString().Replace("-", "");
_bookingOrderRepository.AsUpdateable(bookingOrder).UpdateColumns(it => new
{
it.TRUCKERID,
it.TRUCKER,
//it.VERSION
}).ExecuteCommand();
// 保存日志
await _bookingOrderService.SaveLog(bookingOrder, oldOrder, "派车任务回写");
var syncDongshengRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingTruckInfo.BookingId.Value });
_logger.LogInformation($"推送订舱同步东胜完毕,id={bookingTruckInfo.BookingId.Value} rlt={JSON.Serialize(syncDongshengRlt)}");
_logger.LogInformation("判断回写需要更新去掉订舱的车队,更新完成");
}
}
else
{
bookingTruckSyncDto.OperType = "AddOrUpdate";
//这里增加判断如果派车回写里包含车队信息,自动回写到订舱信息里
if (!string.IsNullOrWhiteSpace(info.TruckCode))
{
var bookingOrder = _bookingOrderRepository.AsQueryable()
.First(a => a.Id == bookingTruckInfo.BookingId.Value);
if (bookingOrder != null)
{
_logger.LogInformation("判断回写需要更新订舱的车队 id={id} truck={truck}", bookingTruckInfo.BookingId.Value, info.TruckName);
var oldOrder = bookingOrder.Adapt();
bookingOrder.TRUCKERID = info.TruckCode;
bookingOrder.TRUCKER = info.TruckName;
//bookingOrder.VERSION = IDGen.NextID().ToString().Replace("-", "");
_bookingOrderRepository.AsUpdateable(bookingOrder).UpdateColumns(it => new
{
it.TRUCKERID,
it.TRUCKER,
//it.VERSION
}).ExecuteCommand();
// 保存日志
await _bookingOrderService.SaveLog(bookingOrder, oldOrder, "派车任务回写");
//这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获
try
{
//触发发送东胜
var syncDongshengRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingTruckInfo.BookingId.Value });
_logger.LogInformation($"推送订舱同步东胜完毕,id={bookingTruckInfo.BookingId.Value} rlt={JSON.Serialize(syncDongshengRlt)}");
}
catch (Exception bkException)
{
_logger.LogInformation("批次={no} id={id} 触发发送东胜完成,原因:{erro}", batchNo, bookingTruckInfo.BookingId.Value, bkException.Message);
}
_logger.LogInformation("判断回写需要更新订舱的车队,更新完成");
}
}
}
messageInfo.Main = bookingTruckSyncDto;
if (bookingTruckInfo.TenantId.HasValue)
messageInfo.Main.TenantId = bookingTruckInfo.TenantId.Value;
var mqRlt = await PushSyncBookingTruckMQToDS6(messageInfo);
_logger.LogInformation("发送MQ,rlt={rlt}", JSON.Serialize(mqRlt));
result.succ = true;
result.msg = "保存成功";
result.ext = id;
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("派车任务回写失败");
}
return result;
}
///
/// 同步MQ推送派车信息到东胜6
///
/// 同步详情
/// 返回回执
private async Task PushSyncBookingTruckMQToDS6(BookingTruckSyncMessageInfo bookingTruckSyncMessageInfo)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var mqUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "BookingOrderMQUri")?.Value;
if (mqUrl == null)
{
_logger.LogInformation("字典未配置 url_set->BookingOrderMQUri 请联系管理员");
throw Oops.Bah("字典未配置 url_set->BookingOrderMQUri 请联系管理员");
}
//请求MQ
var json = JSON.Serialize(bookingTruckSyncMessageInfo);
var mqRlt = MQHelper.SendMQ(json, mqUrl, MQ_EXCHANGE_NAME, MQ_QUEUE_NAME
, bookingTruckSyncMessageInfo.Main.TenantId);
_logger.LogInformation("发送MQ请求完成,结果={rlt}", JSON.Serialize(mqRlt));
if (mqRlt.succ)
{
result.succ = true;
result.msg = "同步东胜完成";
}
else
{
result = mqRlt;
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("同步东胜失败");
}
return result;
}
///
/// 获取场站数据
///
///
///
/// 返回场站详情
[HttpGet("/BookingTruck/GetYardData")]
public async Task GetYardData(long bookingTruckId, bool isWeb = false)
{
//订舱派车数据
var entity = _bookingTruckRepository.AsQueryable().First(x => x.Id == bookingTruckId);
if (entity == null)
throw Oops.Oh($"派车信息不能为空", typeof(InvalidOperationException));
BookingOrder bookingOrder = null;
if (entity.BookingId.HasValue)
{
bookingOrder = _bookingOrderRepository.AsQueryable().First(x => x.Id == entity.BookingId.Value);
}
string yardId = string.Empty;
string mblNo = string.Empty;
if (bookingOrder != null)
{
yardId = bookingOrder.YARDID;
mblNo = bookingOrder.MBLNO;
}
if (string.IsNullOrWhiteSpace(yardId))
yardId = entity.YARDID;
if (string.IsNullOrWhiteSpace(mblNo))
mblNo = entity.MBLNo;
if (string.IsNullOrEmpty(yardId))
{
throw Oops.Bah("场站信息不能为空");
}
if (string.IsNullOrEmpty(mblNo))
{
throw Oops.Bah("提单号不能为空");
}
var rtn = await YardDataHelper.GetYardDataWithTranslateAsync(UserManager.UserId, bookingOrder.TenantId.Value, bookingOrder.TenantName,
mblNo, yardId, isWeb);
return rtn;
}
}
}