You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/Myshipping.Application/Service/BookingTruck/BookingTruckService.cs

2056 lines
86 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
{
/// <summary>
/// 派车服务
/// </summary>
[ApiDescriptionSettings("Application", Name = "BookingTruck", Order = 9)]
public class BookingTruckService : IBookingTruckService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger<BookingTruckService> _logger;
private readonly SqlSugarRepository<BookingTruck> _bookingTruckRepository;
private readonly SqlSugarRepository<BookingTruckCtn> _bookingTruckContaRepository;
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly SqlSugarRepository<BookingCtn> _bookingCtnRepository;
private readonly SqlSugarRepository<BookingPrintTemplate> _bookingPrintTemplateRepository;
private readonly SqlSugarRepository<DjyUserConfig> _djyUserConfigConfig;
private readonly SqlSugarRepository<BookingExcelTemplate> _bookingExcelTemplateRepository;
private readonly SqlSugarRepository<SysUser> _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<BookingTruckService> logger,
SqlSugarRepository<BookingTruck> bookingTruckRepository,
SqlSugarRepository<BookingTruckCtn> bookingTruckContaRepository,
SqlSugarRepository<BookingOrder> bookingOrderRepository,
SqlSugarRepository<BookingCtn> bookingCtnRepository,
SqlSugarRepository<BookingPrintTemplate> bookingPrintTemplateTemplate,
SqlSugarRepository<DjyUserConfig> djyUserConfigConfig,
SqlSugarRepository<BookingExcelTemplate> bookingExcelTemplateRepository,
SqlSugarRepository<SysUser> 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;
}
/// <summary>
/// 保存派车
/// </summary>
/// <param name="info">派车信息</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/Save")]
public async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 保存内部方法
/// </summary>
/// <param name="info">派车信息</param>
/// <param name="isCallBack">是否回写</param>
/// <returns>返回派车Id</returns>
[SqlSugarUnitOfWork]
private async Task<long> InnerSave(BookingTruckDto info, bool isCallBack = false)
{
BookingTruck entity = info.Adapt<BookingTruck>();
if (entity == null)
throw Oops.Oh($"派车信息不能为空", typeof(InvalidOperationException));
List<BookingTruckCtn> entityCtnList = info.ContaList.Adapt<List<BookingTruckCtn>>();
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;
}
/// <summary>
/// 获取派车详情
/// </summary>
/// <param name="id">派车主键</param>
/// <returns>返回回执</returns>
[HttpGet("/BookingTruck/GetInfo")]
public async Task<TaskManageOrderResultDto> 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<BookingTruckShowDto>();
if (truckCtnList.Count > 0)
model.ContaList = truckCtnList.Adapt<List<BookingTruckCtnDto>>();
result.succ = true;
result.ext = model;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"获取派车详情异常,原因:{ex.Message}";
}
return result;
}
/// <summary>
/// 订舱生成派车初始信息
/// </summary>
/// <param name="bookingId">订舱主键</param>
/// <returns>返回派车初始信息</returns>
[HttpGet("/BookingTruck/InitFromBookingOrder")]
public async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 派车台账查询
/// </summary>
/// <param name="QuerySearch">派车台账查询请求</param>
/// <returns>返回结果</returns>
[HttpPost("/BookingTruck/GetPage")]
public async Task<SqlSugarPagedList<BookingTruckPageDto>> GetPageAsync([FromBody] QueryBookingTruckDto QuerySearch)
{
List<string> contaList = new List<string>();
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<BookingTruckDto, BookingTruck>(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 ? " asc " : " desc "))
.ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize);
return entities.Adapt<SqlSugarPagedList<BookingTruckPageDto>>();
}
/// <summary>
/// 订舱主键获取相关派车列表
/// </summary>
/// <param name="bookingId">订舱主键</param>
/// <returns>返回派车列表</returns>
[HttpGet("/BookingTruck/GetTruckListByBooking")]
public async Task<List<BookingTruckShowDto>> GetTruckListByBookingAsync(long bookingId)
{
var list = _bookingTruckRepository.AsQueryable().Where(a => a.BookingId == bookingId).ToList();
return list.Adapt<List<BookingTruckShowDto>>();
}
private async Task<BookingTruckShowDto> 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<BookingTruckCtnDto>();
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,
});
}
}
});
}
return model;
}
/// <summary>
/// 引入订舱详情生成派车信息
/// </summary>
/// <param name="bookingId">订舱主键</param>
/// <returns>返回派车初始信息</returns>
[HttpGet("/BookingTruck/PullInBookingOrder")]
public async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 引入订舱集装箱详情生成派车信息
/// </summary>
/// <param name="bookingId">订舱主键</param>
/// <returns>返回派车集装箱初始信息</returns>
[HttpGet("/BookingTruck/PullInBookingOrderConta")]
public async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 提交派车
/// </summary>
/// <param name="info">派车信息</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/Submit")]
public async Task<TaskManageOrderResultDto> 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 提交内部方法
/// <summary>
/// 提交内部方法
/// </summary>
/// <param name="info">派车信息</param>
/// <param name="batchNo">批次号</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> 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<TaskManageOrderTruckInfo>(),
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<List<TaskManageOrderTruckContaInfo>>();
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 批量提交派车
/// <summary>
/// 批量提交派车
/// </summary>
/// <param name="ids">派车主键组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/SubmitBatch")]
public async Task<TaskManageOrderResultDto> 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<Task<TaskManageOrderResultDto>> taskList = new List<Task<TaskManageOrderResultDto>>();
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<string> msgList = new List<string>();
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
/// <summary>
/// 撤销派车
/// </summary>
/// <param name="id">派车主键</param>
/// <returns>返回回执</returns>
[HttpGet("/BookingTruck/Cancel")]
public async Task<TaskManageOrderResultDto> Cancel(long id)
{
/*
撤销派车流程
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);
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage();
}
return result;
}
/// <summary>
/// 批量撤销派车
/// </summary>
/// <param name="ids">派车主键组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/CancelBatch")]
public async Task<TaskManageOrderResultDto> 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<Task<TaskManageOrderResultDto>> taskList = new List<Task<TaskManageOrderResultDto>>();
list.ForEach(async tk =>
{
taskList.Add(InnerCancel(tk.Id, batchNo));
});
//等待所有结果
Task.WaitAll(taskList.ToArray(), 20000);
result.succ = true;
result.msg = "撤销成功";
List<string> msgList = new List<string>();
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 内部撤销派车
/// <summary>
/// 内部撤销派车
/// </summary>
/// <param name="id">派车主键</param>
/// <param name="batchNo">批次号</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> InnerCancel(long id, string batchNo)
{
/*
撤销派车流程
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));
//校验
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<TaskManageOrderTruckInfo>(),
}
};
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>();
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<List<BookingTruckCtnDto>>();
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;
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
/// <summary>
/// 删除派车
/// </summary>
/// <param name="id">派车主键</param>
/// <returns>返回回执</returns>
[HttpGet("/BookingTruck/Delete")]
public async Task<string> 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 "删除成功";
}
/// <summary>
/// 批量删除派车
/// </summary>
/// <param name="ids">派车主键组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/DeleteBatch")]
public async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 获取订舱打印模板列表(带有当前用户打印历史排序)
/// </summary>
/// <param name="cateCode">分类代码使用字典【booking_template_category】中的代码</param>
/// <param name="printType">打印分类10FastReport、20Excel模板</param>
/// <returns></returns>
[HttpGet("/BookingTruck/PrintTemplateWithHistoryList")]
public async Task<dynamic> PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType)
{
var typeCode = printType.ToString();
//当前公司所有已配置的模板
var allList = await _bookingPrintTemplateRepository.AsQueryable()
.Filter(null, true).InnerJoin<BookingPrinttemplateRight>((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<dynamic>();
//当前用户打印历史数据
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;
}
}
/// <summary>
/// 打印派车
/// </summary>
/// <param name="id">派车主键</param>
/// <param name="templateId">打印模板ID</param>
/// <param name="cateCode">分类代码使用字典【booking_template_category】中的代码</param>
/// <param name="printFileType">类型1pdf、2xlsx、3docx</param>
/// <param name="printType">打印类型10FastReport、20Excel模板</param>
/// <returns>返回回执</returns>
[HttpGet("/BookingTruck/Print")]
public async Task<string> 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<TempFileOptions>().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<PrintTemplateOptions>();
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<TempFileOptions>().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"));
}
/// <summary>
/// 生成打印报表文件
/// </summary>
/// <param name="bookingTruckId">派车ID</param>
/// <param name="printTemplate">打印模板</param>
/// <param name="printType">文档类型1pdf、2xlsx、3docx</param>
/// <returns>返回文件流</returns>
[NonAction]
private async Task<byte[]> 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<BookingTruckPrintDto>();
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<List<BookingTruckCtnPrintDto>>();
_logger.LogInformation($"bookingTruckId={bookingTruckId} 请求打印 JSON={JSON.Serialize(model)}");
return await PrintHelper.GeneratePrintFile(JSON.Serialize(model), reportUrl, PRINT_DATASOURCE_KEY,
printFileType, printTemplate);
}
#region 校验派车
/// <summary>
/// 校验派车
/// </summary>
/// <param name="operateType">操作类型</param>
/// <param name="entityArg">派车信息列表</param>
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
/// <summary>
/// 派车任务回写派车详情
/// </summary>
/// <param name="info">派车详情</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingTruck/TruckDispatchCompleteCallBack")]
public async Task<TaskManageOrderResultDto> 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<BookingTruckSyncMessageMainInfo>();
bookingTruckSyncDto.ContaList = info.ContaList.Adapt<List<BookingTruckCtnDto>>();
if (info.CallBackStatus == BookingTruckStatus.CANCEL_DISPATCH.ToString())
{
bookingTruckSyncDto.OperType = "Delete";
var bookingOrder = _bookingOrderRepository.AsQueryable()
.First(a => a.Id == bookingTruckInfo.BookingId.Value);
if (bookingOrder != null)
{
_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();
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);
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();
//这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获
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("发送MQrlt={rlt}", JSON.Serialize(mqRlt));
result.succ = true;
result.msg = "保存成功";
result.ext = id;
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.GetMessage("派车任务回写失败");
}
return result;
}
/// <summary>
/// 同步MQ推送派车信息到东胜6
/// </summary>
/// <param name="bookingTruckSyncMessageInfo">同步详情</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> 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;
}
/// <summary>
/// 获取场站数据
/// </summary>
/// <param name="bookingTruckId"></param>
/// <param name="isWeb"></param>
/// <returns>返回场站详情</returns>
[HttpGet("/BookingTruck/GetYardData")]
public async Task<string> 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;
}
}
}