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/BookingOrder/BookingOrderService.cs

2187 lines
98 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 Myshipping.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Linq;
using System.Threading.Tasks;
using Myshipping.Application.Entity;
using Microsoft.AspNetCore.Authorization;
using Furion;
using Microsoft.AspNetCore.Http;
using Furion.DataEncryption;
using System.Collections.Generic;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Furion.FriendlyException;
using Furion.Logging;
using System;
using Microsoft.Extensions.Logging;
using System.Reflection;
using System.ComponentModel;
using Myshipping.Application.Service.BookingOrder.Dto;
using Myshipping.Application.ConfigOption;
using System.IO;
using Yitter.IdGenerator;
using Myshipping.Core.Entity;
using Furion.RemoteRequest.Extensions;
using System.Net.Http;
using Myshipping.Core.Service;
using Myshipping.Application.EDI;
using System.Text;
using System.Web;
using Newtonsoft.Json.Linq;
using Myshipping.Core.Helper;
using Myshipping.Application.Enum;
using Org.BouncyCastle.Asn1.X500;
using System.Drawing.Drawing2D;
using StackExchange.Profiling.Internal;
using Myshipping.Application;
using Myshipping.Application.EDI.PIL;
using Newtonsoft.Json;
using Myshipping.Application.EDI.TSL;
using Myshipping.Application.EDI.WY;
using Myshipping.Application.EDI.YML;
using Myshipping.Application.EDI.YT;
using System.Runtime.InteropServices;
using System.Threading;
using Furion.JsonSerialization;
using System.Xml.Linq;
namespace Myshipping.Application
{
/// <summary>
/// 订舱服务
/// </summary>
[ApiDescriptionSettings("Application", Name = "BookingOrder", Order = 1)]
public class BookingOrderService : IBookingOrderService, IDynamicApiController, ITransient
{
private readonly SqlSugarRepository<BookingOrder> _rep;
private readonly SqlSugarRepository<BookingCtn> _repCtn;
private readonly SqlSugarRepository<BookingCtnDetail> _ctndetailrep;
private readonly SqlSugarRepository<BookingLog> _bookinglog;
private readonly SqlSugarRepository<BookingLogDetail> _bookinglogdetail;
private readonly SqlSugarRepository<BookingRemark> _bookingremark;
private readonly SqlSugarRepository<BookingFile> _bookingfile;
private readonly SqlSugarRepository<DjyWebsiteAccountConfig> _repWebAcc;
private readonly SqlSugarRepository<SysDictData> _dicdata;
private readonly SqlSugarRepository<BookingPrintTemplate> _repPrint;
private readonly ILogger<BookingOrderService> _logger;
private readonly ISysCacheService _cache;
private readonly SqlSugarRepository<BookingStatusLog> _repStatuslog;
private readonly SqlSugarRepository<BookingStatusLogDetail> _statuslogdetail;
private readonly SqlSugarRepository<BookingPrintTemplate> _repPrintTemplate;
private readonly SqlSugarRepository<BookingLetteryard> _repLetterYard;
private readonly SqlSugarRepository<SysUser> _repUser;
private readonly SqlSugarRepository<BookingOrderUrl> _repOrderUrl;
private readonly SqlSugarRepository<BookingOrderContact> _repOrderContact;
private readonly SqlSugarRepository<BookingSampleBill> _repSampleBill;
private readonly SqlSugarRepository<DjyUserMailAccount> _repUserMail;
private readonly SqlSugarRepository<SysTenant> _repTenant;
private readonly SqlSugarRepository<BookingStatus> _repBookingStatus;
const string CONST_MAPPING_MODULE = "BOOK_OR_CLOSING";
const string CONST_MAPPING_MODULE_ROUTE = "BOOK_OR_CLOSING_RT";
public BookingOrderService(SqlSugarRepository<BookingOrder> rep, SqlSugarRepository<BookingCtn> repCtn, SqlSugarRepository<BookingCtnDetail> ctndetailrep,
SqlSugarRepository<BookingLog> bookinglog, SqlSugarRepository<BookingLogDetail> bookinglogdetail, SqlSugarRepository<BookingRemark> bookingremark,
SqlSugarRepository<BookingFile> bookingfile, SqlSugarRepository<DjyWebsiteAccountConfig> webconfig, SqlSugarRepository<BookingPrintTemplate> repPrint,
SqlSugarRepository<SysDictData> dicdata, SqlSugarRepository<BookingStatusLog> statuslog, SqlSugarRepository<BookingStatusLogDetail> statuslogdetail,
ILogger<BookingOrderService> logger, ISysCacheService cache,
SqlSugarRepository<BookingPrintTemplate> repPrintTemplate, SqlSugarRepository<BookingLetteryard> repLetterYard, SqlSugarRepository<SysUser> repUser,
SqlSugarRepository<BookingOrderUrl> repOrderUrl, SqlSugarRepository<BookingOrderContact> repOrderContact, SqlSugarRepository<BookingSampleBill> repSampleBill,
SqlSugarRepository<DjyUserMailAccount> repUserMail, SqlSugarRepository<SysTenant> repTenant, SqlSugarRepository<BookingStatus> repBookingStatus)
{
this._logger = logger;
this._rep = rep;
this._repCtn = repCtn;
this._ctndetailrep = ctndetailrep;
this._bookinglog = bookinglog;
this._bookinglogdetail = bookinglogdetail;
this._bookingremark = bookingremark;
this._bookingfile = bookingfile;
this._repWebAcc = webconfig;
this._repPrint = repPrint;
this._dicdata = dicdata;
this._cache = cache;
this._repStatuslog = statuslog;
this._statuslogdetail = statuslogdetail;
this._repPrintTemplate = repPrintTemplate;
this._repLetterYard = repLetterYard;
this._repUser = repUser;
this._repOrderUrl = repOrderUrl;
this._repOrderContact = repOrderContact;
this._repSampleBill = repSampleBill;
this._repUserMail = repUserMail;
this._repTenant = repTenant;
this._repBookingStatus = repBookingStatus;
}
////传id 返回分单信息
#region 主表和箱信息
/// <summary>
/// 分页查询订舱主表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/Page")]
public async Task<dynamic> Page([FromQuery] BookingOrderInput input)
{
List<long> userlist = await DataFilterExtensions.GetDataScopeIdList();
var entities = await _rep.AsQueryable().Where(x => x.ParentId == 0)
.WhereIF(!string.IsNullOrWhiteSpace(input.BSSTATUS), u => u.BSSTATUS == input.BSSTATUS)
.WhereIF(!string.IsNullOrWhiteSpace(input.MBLNO), u => input.MBLNO.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Contains(u.MBLNO))
.WhereIF(!string.IsNullOrWhiteSpace(input.HBLNO), u => input.HBLNO.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Contains(u.HBLNO))
.WhereIF(!string.IsNullOrWhiteSpace(input.BOOKINGNO), u => u.BOOKINGNO.IndexOf(input.BOOKINGNO) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.CONTRACTNO), u => u.CONTRACTNO.IndexOf(input.CONTRACTNO) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.SERVICECONTRACTNO), u => u.SERVICECONTRACTNO.IndexOf(input.SERVICECONTRACTNO) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPER), u => u.SHIPPER.Contains(input.SHIPPER))
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEE), u => u.CONSIGNEE.Contains(input.CONSIGNEE))
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTY), u => u.NOTIFYPARTY.Contains(input.NOTIFYPARTY))
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTY2), u => u.NOTIFYPARTY2.Contains(input.NOTIFYPARTY2))
.WhereIF(!string.IsNullOrWhiteSpace(input.YARDID), u => u.YARDID == input.YARDID)
.WhereIF(!string.IsNullOrWhiteSpace(input.YARD), u => u.YARD == input.YARD)
.WhereIF(!string.IsNullOrWhiteSpace(input.VESSELID), u => u.VESSELID.IndexOf(input.VESSELID) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.VESSEL), u => u.VESSEL.ToLower().IndexOf(u.VESSEL.ToLower()) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.VOYNO), u => u.VOYNO.IndexOf(input.VOYNO) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.VOYNOINNER), u => u.VOYNOINNER.IndexOf(input.VOYNOINNER) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.PLACERECEIPT), u => u.PLACERECEIPT.Contains(input.PLACERECEIPT))
.WhereIF(!string.IsNullOrWhiteSpace(input.PLACERECEIPTID), u => u.PLACERECEIPTID == input.PLACERECEIPTID)
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTLOAD), u => u.PORTLOAD.IndexOf(input.PORTLOAD) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTDISCHARGE), u => u.PORTDISCHARGE.IndexOf(input.PORTDISCHARGE) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.PLACEDELIVERY), u => u.PLACEDELIVERY.Contains(input.PLACEDELIVERY))
.WhereIF(!string.IsNullOrWhiteSpace(input.PLACEDELIVERYID), u => u.PLACEDELIVERYID == input.PLACEDELIVERYID)
.WhereIF(!string.IsNullOrWhiteSpace(input.DESTINATION), u => u.DESTINATION.Contains(input.DESTINATION))
.WhereIF(!string.IsNullOrWhiteSpace(input.DESTINATIONID), u => u.DESTINATIONID == input.DESTINATIONID)
.WhereIF(!string.IsNullOrWhiteSpace(input.NOBILL), u => u.NOBILL == input.NOBILL)
.WhereIF(!string.IsNullOrWhiteSpace(input.COPYNOBILLL), u => u.COPYNOBILL == input.COPYNOBILLL)
.WhereIF(!string.IsNullOrWhiteSpace(input.ISSUETYPE), u => u.ISSUETYPE == input.ISSUETYPE)
.WhereIF(!string.IsNullOrWhiteSpace(input.ISSUEPLACE), u => u.ISSUEPLACE.Contains(input.ISSUEPLACE))
.WhereIF(!string.IsNullOrWhiteSpace(input.ISSUEPLACEID), u => u.ISSUEPLACEID == input.ISSUEPLACEID)
.WhereIF(!string.IsNullOrWhiteSpace(input.BLFRT), u => u.BLFRT == input.BLFRT)
.WhereIF(!string.IsNullOrWhiteSpace(input.PREPARDATID), u => u.PREPARDATID == input.PREPARDATID)
.WhereIF(!string.IsNullOrWhiteSpace(input.PREPARDAT), u => u.PREPARDAT == input.PREPARDAT)
.WhereIF(!string.IsNullOrWhiteSpace(input.PAYABLEAT), u => u.PAYABLEAT.Contains(input.PAYABLEAT))
.WhereIF(!string.IsNullOrWhiteSpace(input.PAYABLEATID), u => u.PAYABLEATID == input.PAYABLEATID)
.WhereIF(!string.IsNullOrWhiteSpace(input.SERVICE), u => u.SERVICE.Contains(input.SERVICE))
.WhereIF(!string.IsNullOrWhiteSpace(input.MARKS), u => u.MARKS.Contains(input.MARKS))
.WhereIF(!string.IsNullOrWhiteSpace(input.HSCODE), u => u.HSCODE.IndexOf(input.HSCODE) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.DESCRIPTION), u => u.DESCRIPTION.Contains(input.DESCRIPTION))
.WhereIF(!string.IsNullOrWhiteSpace(input.KINDPKGS), u => u.KINDPKGS == input.KINDPKGS)
.WhereIF(!string.IsNullOrWhiteSpace(input.CNTRTOTAL), u => u.CNTRTOTAL == input.CNTRTOTAL)
.WhereIF(!string.IsNullOrWhiteSpace(input.CARRIERID), u => u.CARRIERID == input.CARRIERID)
.WhereIF(!string.IsNullOrWhiteSpace(input.CARRIER), u => u.CARRIER.Contains(input.CARRIER))
.WhereIF(!string.IsNullOrWhiteSpace(input.CARGOID), u => u.CARGOID == input.CARGOID)
.WhereIF(!string.IsNullOrWhiteSpace(input.DCLASS), u => u.DCLASS == input.DCLASS)
.WhereIF(!string.IsNullOrWhiteSpace(input.DUNNO), u => u.DUNNO == input.DUNNO)
.WhereIF(!string.IsNullOrWhiteSpace(input.DPAGE), u => u.DPAGE == input.DPAGE)
.WhereIF(!string.IsNullOrWhiteSpace(input.DLABEL), u => u.DLABEL == input.DLABEL)
.WhereIF(!string.IsNullOrWhiteSpace(input.LINKMAN), u => u.LINKMAN == input.LINKMAN)
.WhereIF(!string.IsNullOrWhiteSpace(input.TEMPID), u => u.TEMPID == input.TEMPID)
.WhereIF(!string.IsNullOrWhiteSpace(input.TEMPSET), u => u.TEMPSET == input.TEMPSET)
.WhereIF(!string.IsNullOrWhiteSpace(input.REEFERF), u => u.REEFERF == input.REEFERF)
.WhereIF(!string.IsNullOrWhiteSpace(input.HUMIDITY), u => u.HUMIDITY == input.HUMIDITY)
.WhereIF(!string.IsNullOrWhiteSpace(input.TEMPMIN), u => u.TEMPMIN == input.TEMPMIN)
.WhereIF(!string.IsNullOrWhiteSpace(input.TEMPMAX), u => u.TEMPMAX == input.TEMPMAX)
.WhereIF(input.ISCONTAINERSOC != null, u => u.ISCONTAINERSOC == input.ISCONTAINERSOC)
.WhereIF(!string.IsNullOrWhiteSpace(input.SOREMARK), u => u.SOREMARK.Contains(input.SOREMARK))
.WhereIF(!string.IsNullOrWhiteSpace(input.SIREMARK), u => u.SIREMARK.Contains(input.SIREMARK))
.WhereIF(!string.IsNullOrWhiteSpace(input.YARDREMARK), u => u.YARDREMARK.Contains(input.YARDREMARK))
.WhereIF(!string.IsNullOrWhiteSpace(input.COMPID), u => u.COMPID == input.COMPID)
.WhereIF(!string.IsNullOrWhiteSpace(input.COMPNAME), u => u.COMPNAME.IndexOf(input.COMPNAME) > -1)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERNAME), u => u.SHIPPERNAME.Contains(input.SHIPPERNAME))
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERCITY), u => u.SHIPPERCITY.Contains(input.SHIPPERCITY))
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERPROVINCE), u => u.SHIPPERPROVINCE == input.SHIPPERPROVINCE)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERPOSTCODE), u => u.SHIPPERPOSTCODE == input.SHIPPERPOSTCODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERCOUNTRY), u => u.SHIPPERCOUNTRY == input.SHIPPERCOUNTRY)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERATTN), u => u.SHIPPERATTN.Contains(input.SHIPPERATTN))
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPPERTEL), u => u.SHIPPERTEL == input.SHIPPERTEL)
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEENAME), u => u.CONSIGNEENAME.Contains(input.CONSIGNEENAME))
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEECITY), u => u.CONSIGNEECITY.Contains(input.CONSIGNEECITY))
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEEPROVINCE), u => u.CONSIGNEEPROVINCE == input.CONSIGNEEPROVINCE)
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEEPOSTCODE), u => u.CONSIGNEEPOSTCODE == input.CONSIGNEEPOSTCODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEERCOUNTRY), u => u.CONSIGNEERCOUNTRY == input.CONSIGNEERCOUNTRY)
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEEATTN), u => u.CONSIGNEEATTN.Contains(input.CONSIGNEEATTN))
.WhereIF(!string.IsNullOrWhiteSpace(input.CONSIGNEETEL), u => u.CONSIGNEETEL == input.CONSIGNEETEL)
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYNAME), u => u.NOTIFYPARTYNAME.Contains(input.NOTIFYPARTYNAME))
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYCITY), u => u.NOTIFYPARTYCITY.Contains(input.NOTIFYPARTYCITY))
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYPROVINCE), u => u.NOTIFYPARTYPROVINCE == input.NOTIFYPARTYPROVINCE)
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYPOSTCODE), u => u.NOTIFYPARTYPOSTCODE == input.NOTIFYPARTYPOSTCODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYCOUNTRY), u => u.NOTIFYPARTYCOUNTRY == input.NOTIFYPARTYCOUNTRY)
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYATTN), u => u.NOTIFYPARTYATTN.Contains(input.NOTIFYPARTYATTN))
.WhereIF(!string.IsNullOrWhiteSpace(input.NOTIFYPARTYTEL), u => u.NOTIFYPARTYTEL == input.NOTIFYPARTYTEL)
.WhereIF(!string.IsNullOrWhiteSpace(input.PONO), u => u.PONO == input.PONO)
.WhereIF(!string.IsNullOrWhiteSpace(input.OPID), u => u.OPID == input.OPID)
.WhereIF(!string.IsNullOrWhiteSpace(input.DOCID), u => u.DOCID == input.DOCID)
.WhereIF(!string.IsNullOrWhiteSpace(input.OP), u => u.OP == input.OP)
.WhereIF(!string.IsNullOrWhiteSpace(input.DOC), u => u.DOC == input.DOC)
.WhereIF(!string.IsNullOrWhiteSpace(input.SALEID), u => u.SALEID == input.SALEID)
.WhereIF(!string.IsNullOrWhiteSpace(input.SALE), u => u.SALE.Contains(input.SALE))
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTSERVICEID), u => u.CUSTSERVICEID == input.CUSTSERVICEID)
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTSERVICE), u => u.CUSTSERVICE.Contains(input.CUSTSERVICE))
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTOMERNAME), u => u.CUSTOMERNAME.Contains(input.CUSTOMERNAME))
.WhereIF(input.CUSTOMERID != null, u => u.CUSTOMERID == input.CUSTOMERID)
.WhereIF(!string.IsNullOrWhiteSpace(input.FORWARDER), u => u.FORWARDER.Contains(input.FORWARDER))
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTSERVICE), u => u.CUSTSERVICE == input.CUSTSERVICE)
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTOMERNAME), u => u.CUSTOMERNAME == input.CUSTOMERNAME)
.WhereIF(!string.IsNullOrWhiteSpace(input.FORWARDER), u => u.FORWARDER == input.FORWARDER)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPAGENCY), u => u.SHIPAGENCY == input.SHIPAGENCY)
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTOMSER), u => u.CUSTOMSER == input.CUSTOMSER)
.WhereIF(!string.IsNullOrWhiteSpace(input.TRUCKER), u => u.TRUCKER == input.TRUCKER)
.WhereIF(!string.IsNullOrWhiteSpace(input.AGENTID), u => u.AGENTID == input.AGENTID)
.WhereIF(!string.IsNullOrWhiteSpace(input.FORWARDERID), u => u.FORWARDERID == input.FORWARDERID)
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPAGENCY), u => u.SHIPAGENCY.Contains(input.SHIPAGENCY))
.WhereIF(!string.IsNullOrWhiteSpace(input.SHIPAGENCYID), u => u.SHIPAGENCYID == input.SHIPAGENCYID)
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTOMSER), u => u.CUSTOMSER.Contains(input.CUSTOMSER))
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTOMSERID), u => u.CUSTOMSERID == input.CUSTOMSERID)
.WhereIF(!string.IsNullOrWhiteSpace(input.TRUCKER), u => u.TRUCKER.Contains(input.TRUCKER))
.WhereIF(!string.IsNullOrWhiteSpace(input.TRUCKERID), u => u.TRUCKERID == input.TRUCKERID)
.WhereIF(!string.IsNullOrWhiteSpace(input.AGENTNAME), u => u.AGENTNAME.Contains(input.AGENTNAME))
.WhereIF(!string.IsNullOrWhiteSpace(input.AGENTID), u => u.AGENTID == input.AGENTID)
.WhereIF(!string.IsNullOrWhiteSpace(input.WEITUO), u => u.WEITUO.Contains(input.WEITUO))
.WhereIF(!string.IsNullOrWhiteSpace(input.SCACCODE), u => u.SCACCODE == input.SCACCODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.ITNCODE), u => u.ITNCODE == input.ITNCODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.CUSTNO), u => u.CUSTNO.Contains(input.CUSTNO))
.WhereIF(!string.IsNullOrWhiteSpace(input.TRANSPORTID), u => u.TRANSPORTID == input.TRANSPORTID)
.WhereIF(!string.IsNullOrWhiteSpace(input.TRANSPORT), u => u.TRANSPORT.Contains(input.TRANSPORT))
.WhereIF(!string.IsNullOrWhiteSpace(input.YARDCONTRACTTEL), u => u.YARDCONTRACTTEL == input.YARDCONTRACTTEL)
.WhereIF(!string.IsNullOrWhiteSpace(input.YARDCONTRACTEMAIL), u => u.YARDCONTRACTEMAIL == input.YARDCONTRACTEMAIL)
.WhereIF(!string.IsNullOrWhiteSpace(input.LANECODE), u => u.LANECODE == input.LANECODE)
.WhereIF(!string.IsNullOrWhiteSpace(input.LANENAME), u => u.LANENAME.Contains(input.LANENAME))
.WhereIF(!string.IsNullOrWhiteSpace(input.FREIGHTPAYER), u => u.FREIGHTPAYER.Contains(input.FREIGHTPAYER))
.Where(u => userlist.Contains((long)u.CreatedUserId))
.ToPagedListAsync(input.PageNo, input.PageSize);
return entities.XnPagedResult();
}
/// <summary>
/// 增加订舱
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[SqlSugarUnitOfWork]
[HttpPost("/BookingOrder/Add")]
public async Task Add(AddBookingOrderInput input)
{
if (input.ParentId == 0)
{
if (string.IsNullOrWhiteSpace(input.HBLNO))
{
throw Oops.Bah("主单不需要填写分单号");
}
}
else
{
if (string.IsNullOrWhiteSpace(input.MBLNO))
{
throw Oops.Bah("请填写主提单号");
}
}
JsonUtil.PropToUpper(input, "ORDNO", "BSSTATUS", "YardContract", "YardContractTel", "YardContractEmail");
JsonUtil.TrimFields(input);
if (input.ctnInputs != null)
{
var groupList = input.ctnInputs.Where(x => x.CTNNUM > 0).GroupBy(c => c.CTNALL).Select(g => $"{g.Key}*{g.Sum(gg => gg.CTNNUM)}");
input.CNTRTOTAL = string.Join(" / ", groupList);
}
var entity = input.Adapt<BookingOrder>();
await _rep.InsertAsync(entity);
if (input.ctnInputs != null)
{
foreach (var item in input.ctnInputs)
{
var ctnentity = item.Adapt<BookingCtn>();
ctnentity.BILLID = entity.Id;
await _repCtn.InsertAsync(ctnentity);
foreach (var it in item.ctnDetailInputs)
{
var ctndetail = it.Adapt<BookingCtnDetail>();
ctndetail.CTNID = ctnentity.Id;
await _ctndetailrep.InsertAsync(ctndetail);
}
}
}
////添加booking日志
await _bookinglog.InsertAsync(new BookingLog
{
Type = "Add",
BookingId = entity.Id,
TenantId = Convert.ToInt64(UserManager.TENANT_ID),
CreatedTime = DateTime.Now,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name
});
////分单不调用
if (!string.IsNullOrWhiteSpace(input.YARDID) && !string.IsNullOrWhiteSpace(input.YARD) && !string.IsNullOrWhiteSpace(input.MBLNO))
{
await SendTrace(entity.Id.ToString(), entity.YARDID, entity.YARD, entity.MBLNO);
}
}
/// <summary>
/// 删除订舱
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[SqlSugarUnitOfWork]
[HttpPost("/BookingOrder/Delete")]
public async Task Delete(long Id)
{
var ctnlist = await _repCtn.AsQueryable().Where(x => x.BILLID == Id).Select(x => x.Id).ToListAsync();
await _repCtn.UpdateAsync(x => x.BILLID == Id, x => new BookingCtn { IsDeleted = true });
await _ctndetailrep.UpdateAsync(x => ctnlist.Contains((long)x.CTNID), x => new BookingCtnDetail { IsDeleted = true });
_logger.LogInformation(Id + "删除成功!");
}
/// <summary>
/// 更新订舱
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[SqlSugarUnitOfWork]
[HttpPost("/BookingOrder/Update")]
public async Task Update(UpdateBookingOrderInput input)
{
if (input.ParentId == 0)
{
if (!string.IsNullOrWhiteSpace(input.HBLNO))
{
throw Oops.Bah("主单不需要填写分单号");
}
}
else
{
if (!string.IsNullOrWhiteSpace(input.MBLNO))
{
throw Oops.Bah("请填写主提单号");
}
}
JsonUtil.PropToUpper(input, "ORDNO", "BSSTATUS", "YardContract", "YardContractTel", "YardContractEmail");
JsonUtil.TrimFields(input);
if (input.ctnInputs != null)
{
var groupList = input.ctnInputs.Where(x => x.CTNNUM > 0).GroupBy(c => c.CTNALL).Select(g => $"{g.Key}*{g.Sum(gg => gg.CTNNUM)}");
input.CNTRTOTAL = string.Join(" / ", groupList);
}
var main = await _rep.FirstOrDefaultAsync(u => u.Id == input.Id);
var entity = input.Adapt<BookingOrder>();
await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
var ctnlist = await _repCtn.AsQueryable().Where(x => x.BILLID == input.Id).Select(x => x.Id).ToListAsync();
await _repCtn.DeleteAsync(x => x.BILLID == input.Id);
await _ctndetailrep.DeleteAsync(x => ctnlist.Contains((long)x.CTNID));
if (input.ctnInputs != null)
{
foreach (var item in input.ctnInputs)
{
var ctnentity = item.Adapt<BookingCtn>();
ctnentity.BILLID = entity.Id;
await _repCtn.InsertAsync(ctnentity);
foreach (var it in item.ctnDetailInputs)
{
var ctndetail = it.Adapt<BookingCtnDetail>();
ctndetail.CTNID = ctnentity.Id;
await _ctndetailrep.InsertAsync(ctndetail);
}
}
}
bool flag = true;
long bid = 0;
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(entity))
{
string name = descriptor.Name;
if (name == "TenantId" || name == "CreatedTime" || name == "UpdatedTime" || name == "CreatedUserId" || name == "CreatedUserName")
{
continue;
}
object value = descriptor.GetValue(entity);
var oldvalue = main.GetType().GetProperty(name).GetValue(main, null);
if (name == "KGS" || name == "CBM")
{
if (Convert.ToDecimal(value) == Convert.ToDecimal(oldvalue))
{
continue;
}
}
string _oldvalue = oldvalue != null ? oldvalue.ToString() : "";
string _value = value != null ? value.ToString() : "";
if (_oldvalue != _value)
{
if (flag)
{
////添加booking日志
bid = await _bookinglog.InsertReturnSnowflakeIdAsync(new BookingLog
{
Type = "Edit",
BookingId = entity.Id,
TenantId = Convert.ToInt64(UserManager.TENANT_ID),
CreatedTime = DateTime.Now,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name
});
flag = false;
}
await _bookinglogdetail.InsertReturnSnowflakeIdAsync(new BookingLogDetail
{
PId = bid,
Field = descriptor.Description,
OldValue = _oldvalue,
NewValue = _value,
});
if (descriptor.Name == "YARDID" || descriptor.Name == "YARD" || descriptor.Name == "MBLNO")
{
if (!string.IsNullOrWhiteSpace(input.YARDID) && !string.IsNullOrWhiteSpace(input.YARD) && !string.IsNullOrWhiteSpace(input.MBLNO))
{
await SendTrace(entity.Id.ToString(), entity.YARDID, entity.YARD, entity.MBLNO);
}
}
}
}
}
/// <summary>
/// 获取订舱明细
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/Get")]
public async Task<BookingOrderOutput> Get(long Id)
{
BookingOrderOutput ordOut = new BookingOrderOutput();
var main = await _rep.FirstOrDefaultAsync(u => u.Id == Id);
if (main != null)
{
ordOut = main.Adapt<BookingOrderOutput>();
var ctnlist = await _repCtn.AsQueryable().Where(x => x.BILLID == Id).ToListAsync();
var ctninput = ctnlist.Adapt<List<BookingCtnDto>>();
foreach (var item in ctninput)
{
var ctndetaillist = await _ctndetailrep.AsQueryable().Where(x => x.CTNID == item.Id).ToListAsync();
item.ctnDetailInputs = ctndetaillist.Adapt<List<BookingCtnDetailDto>>();
}
ordOut.ctnInputs = ctninput;
var ordUrl = _repOrderUrl.FirstOrDefault(x => x.BookingId == Id);
if (ordUrl != null)
{
ordOut.Link = new BookingOrderUrlOutput()
{
LinkUrlTxxp = ordUrl.UrlTxxp,
LinkUrlVgm = ordUrl.UrlVgm,
LinkUrlVmgSi = ordUrl.UrlVgmSi,
};
}
}
List<BookingOrderDto> HbList = new List<BookingOrderDto>();
var _hblist = await _rep.AsQueryable().Where(x => x.ParentId == Id).ToListAsync();
if (_hblist != null)
{
HbList = _hblist.Adapt<List<BookingOrderDto>>();
foreach (var item in HbList)
{
var ctnlist = await _repCtn.AsQueryable().Where(x => x.BILLID == item.Id).ToListAsync();
var ctninput = ctnlist.Adapt<List<BookingCtnDto>>();
foreach (var it in ctninput)
{
var ctndetaillist = await _ctndetailrep.AsQueryable().Where(x => x.CTNID == it.Id).ToListAsync();
it.ctnDetailInputs = ctndetaillist.Adapt<List<BookingCtnDetailDto>>();
}
item.ctnInputs = ctninput;
}
ordOut.HbList = HbList;
}
return ordOut;
}
#endregion
#region 日志、备注、附件、货运动态等
/// <summary>
/// 获取日志明细
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/GetLog")]
public async Task<List<BookingLogDto>> GetLog(long Id)
{
List<BookingLogDto> list = new List<BookingLogDto>();
var main = await _bookinglog.AsQueryable().Where(u => u.BookingId == Id).ToListAsync();
list = main.Adapt<List<BookingLogDto>>();
if (list != null)
{
foreach (var item in list)
{
var details = await _bookinglogdetail.AsQueryable().Where(x => x.PId == item.Id).ToListAsync();
item.details = details;
}
}
return list;
}
/// <summary>
/// 获取备注
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/GetRemark")]
public async Task<List<BookingRemark>> GetRemark(long Id)
{
var list = await _bookingremark.AsQueryable().Where(u => u.PId == Id).ToListAsync();
return list;
}
/// <summary>
/// 增加备注
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[SqlSugarUnitOfWork]
[HttpPost("/BookingOrder/AddRemark")]
public async Task AddRemark(BookingRemarkDto dto)
{
var entity = dto.Adapt<BookingRemark>();
await _bookingremark.InsertAsync(entity);
}
/// <summary>
/// 增加订舱附件
/// </summary>
/// <param name="file"></param>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("/BookingOrder/AddFile")]
public async Task AddFile(IFormFile file, [FromForm] BookingFileDto dto)
{
//未上传打印模板文件
if (file == null || file.Length == 0)
{
throw Oops.Bah(BookingErrorCode.BOOK200);
}
var opt = App.GetOptions<BookingAttachOptions>();
var originalFilename = file.FileName; // 文件原始名称
var fileSuffix = Path.GetExtension(file.FileName).ToLower(); // 文件后缀
if (!opt.fileType.Contains(fileSuffix))
{
throw Oops.Bah(BookingErrorCode.BOOK114);
}
var dirAbs = string.Empty;
if (string.IsNullOrEmpty(opt.basePath))
{
dirAbs = Path.Combine(App.WebHostEnvironment.WebRootPath, opt.relativePath);
}
else
{
dirAbs = Path.Combine(opt.basePath, opt.relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
// 先存库获取Id
var id = YitIdHelper.NextId();
var fileSaveName = $"{id}{fileSuffix}".ToLower();
var fileRelaPath = Path.Combine(opt.relativePath, fileSaveName).ToLower();
var fileAbsPath = Path.Combine(dirAbs, fileSaveName).ToLower();
var newFile = new BookingFile
{
Id = id,
FileName = originalFilename,
FilePath = fileRelaPath,
TypeCode = dto.TypeCode,
TypeName = dto.TypeName,
BookingId = dto.BookingId
};
await _bookingfile.InsertAsync(newFile);
using (var stream = File.Create(fileAbsPath))
{
await file.CopyToAsync(stream);
}
}
/// <summary>
/// 获取附件
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/GetFile")]
public async Task<List<BookingFile>> GetFile(long Id)
{
var list = await _bookingfile.AsQueryable().Where(u => u.BookingId == Id).ToListAsync();
return list;
}
/// <summary>
/// 获取货运动态
/// </summary>
[HttpGet("/BookingOrder/GetStatusLog")]
public async Task<List<BookingStatusLogDto>> GetBookingStatusLog(long Id)
{
var statuslog = await _repStatuslog.AsQueryable().Where(x => x.BookingId == Id).ToListAsync();
var dto = statuslog.Adapt<List<BookingStatusLogDto>>();
foreach (var item in dto)
{
var detail = await _statuslogdetail.AsQueryable().Where(x => x.PId == item.Id).ToListAsync();
item.detail = detail.Adapt<List<BookingStatusLogDetailDto>>();
}
return dto;
}
/// <summary>
/// 下载文件
/// </summary>
/// <returns></returns>
[HttpGet("/BookingOrder/download")]
public async Task<IActionResult> Download(long id)
{
var printFile = await _bookingfile.FirstOrDefaultAsync(u => u.Id == id);
if (printFile == null)
{
throw Oops.Oh(BookingErrorCode.BOOK200);
}
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
var fileFullPath = Path.Combine(dirAbs, printFile.FilePath);
if (!File.Exists(fileFullPath))
{
throw Oops.Oh(BookingErrorCode.BOOK115);
}
var fileName = HttpUtility.UrlEncode(printFile.FileName, Encoding.GetEncoding("UTF-8"));
var result = new FileStreamResult(new FileStream(fileFullPath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
return result;
}
#endregion
#region 运踪
/// <summary>
/// 调用运踪接口
/// </summary>
[NonAction]
public async Task SendTrace(string BusinessId, string YARDID, string YARD, string MBLNO)
{
_logger.LogInformation("提单号:" + MBLNO + " 调用运踪接口");
var key = _repWebAcc.FirstOrDefault(x => x.TenantId == Convert.ToInt64(UserManager.TENANT_ID) && x.TypeCode == "seae_billtraceurl");
var url = _cache.GetAllDictData().Result;
BillTraceDto billdto = new BillTraceDto();
List<BillTraceList> billTraceList = new List<BillTraceList>();
billTraceList.Add(new BillTraceList
{
BusinessId = BusinessId,
MBLNO = MBLNO,
YARD = YARD,
YardCode = YARDID,
CARRIER = null,
CARRIERID = null,
isBook = false
});
billdto.Children = billTraceList;
billdto.Key = key.Account;
billdto.PWD = key.Password;
billdto.url = url.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "response_seae_billtraceurl").Value;
billdto.Gid = UserManager.DjyUserId;
var json = billdto.ToJsonString();
var html = await url.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "request_seae_billtraceurl").Value.SetHttpMethod(HttpMethod.Post).SetQueries(new { msg = json }).SetRetryPolicy(3, 5000).SendAsAsync<RespCommon>();
_logger.LogInformation("提单号:" + MBLNO + " 调用运踪接口返回" + html.ToJsonString());
}
/// <summary>
/// 插入货运动态
/// </summary>
[AllowAnonymous]
[SqlSugarUnitOfWork]
[NonAction]
public async Task AddBookingStatusLog(List<BookingStatusLogDto> all)
{
foreach (var item in all)
{
//清空原有数据
var old = await _repStatuslog.AsQueryable().Where(x => x.BookingId == item.BookingId && x.Category == "ship").ToListAsync();
await _repStatuslog.DeleteAsync(x => x.BookingId == item.BookingId && x.Category == "ship");
foreach (var ot in old)
{
await _statuslogdetail.DeleteAsync(x => x.PId == ot.Id);
}
//新增数据
var bookingStatusLog = new BookingStatusLog();
bookingStatusLog.BookingId = item.BookingId;
bookingStatusLog.Category = "ship";
bookingStatusLog.CreatedTime = DateTime.Now;
bookingStatusLog.Status = item.Status;
bookingStatusLog.OpTime = item.OpTime;
bookingStatusLog.MBLNO = item.MBLNO;
var id = await _repStatuslog.InsertReturnSnowflakeIdAsync(bookingStatusLog);
if (item.detail != null && item.detail.Count > 0)
{
foreach (var dt in item.detail)
{
var BookingStatusLogDetail = new BookingStatusLogDetail();
BookingStatusLogDetail.PId = id;
BookingStatusLogDetail.Status = dt.Status;
BookingStatusLogDetail.CNTRNO = dt.CNTRNO;
BookingStatusLogDetail.OPTime = dt.OPTime;
await _statuslogdetail.InsertAsync(BookingStatusLogDetail);
}
}
}
}
#endregion
#region 放舱(入货通知)
/// <summary>
/// 获取放舱信息
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/LetterYard")]
public async Task<UpdateBookingLetteryardOutput> LetterYard(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
var letterYard = await _repLetterYard.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (letterYard == null)
{
var user = _repUser.FirstOrDefault(x => x.Id == UserManager.UserId);
letterYard = new BookingLetteryard()
{
BookingId = bookingId,
Description = order.DESCRIPTION,
FromName = user.Name,
FromTel = user.Tel,
FromMail = user.Email,
};
}
var output = letterYard.Adapt<UpdateBookingLetteryardOutput>();
//链接信息
var urlModel = _repOrderUrl.FirstOrDefault(x => x.BookingId == bookingId);
if (urlModel != null)
{
output.OrderUrl = urlModel.Adapt<BookingOrderUrlLetterYardOutput>();
}
return output;
}
/// <summary>
/// 保存(新增或修改)放舱
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/BookingLetteryard/Save")]
public async Task LetteryardSave(UpdateBookingLetteryardInput input)
{
if (input.Id == 0)
{
var entity = input.Adapt<BookingLetteryard>();
await _repLetterYard.InsertAsync(entity);
}
else
{
var entity = _repLetterYard.FirstOrDefault(x => x.BookingId == input.Id);
entity = input.Adapt(entity);
await _repLetterYard.UpdateAsync(entity);
}
var order = _rep.FirstOrDefault(x => x.Id == input.BookingId);
//生成提箱小票
var allowCarrier = _cache.GetAllDictData().Result.Where(x => x.TypeCode == "txxp_carrier_list").Select(x => x.Code).ToList();
if (allowCarrier.Contains(order.CARRIERID))
{
var txxpLink = await TxxpLink(input.BookingId);
}
//vgm链接
allowCarrier = _cache.GetAllDictData().Result.Where(x => x.TypeCode == "vgm_carrier_list").Select(x => x.Code).ToList();
if (!allowCarrier.Contains(order.CARRIERID))
{
await VgmLink(input.BookingId);
}
}
/// <summary>
/// 放舱发送
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpPost("/BookingLetteryard/SendLetterYard")]
public async Task SendLetterYard(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
var user = await _repUser.FirstOrDefaultAsync(u => u.Id == order.CreatedUserId);
var tenant = await _repTenant.FirstOrDefaultAsync(t => t.Id == order.TenantId);
var letterYard = await _repLetterYard.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (letterYard == null)
{
throw Oops.Bah("放舱信息未找到,请先保存数据");
}
var mailAcc = await _repUserMail.FirstOrDefaultAsync(x => x.CreatedUserId == user.Id && x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
if (mailAcc == null)
{
throw Oops.Bah("用户邮箱未设置或smtp未正确配置");
}
var orderUrl = await _repOrderUrl.FirstOrDefaultAsync(u => u.BookingId == bookingId);
if (orderUrl == null)
{
throw Oops.Bah("未生成链接信息,请重新保存数据");
}
if (string.IsNullOrEmpty(letterYard.AttnMail))
{
throw Oops.Bah("ATTN MAIL未正确填写");
}
#region 保存放舱文件,并挂载到订舱附件
var fileBytes = await GetReportFile(bookingId, "fangcang");
var opt = App.GetOptions<BookingAttachOptions>();
var fileSaveName = $"放舱_{order.MBLNO}_{DateTime.Now.Ticks}.pdf"; // 文件原始名称
var dirAbs = string.Empty;
if (string.IsNullOrEmpty(opt.basePath))
{
dirAbs = Path.Combine(App.WebHostEnvironment.WebRootPath, opt.relativePath);
}
else
{
dirAbs = Path.Combine(opt.basePath, opt.relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
var fileRelaPath = Path.Combine(opt.relativePath, fileSaveName).ToLower();
var fileAbsPath = Path.Combine(dirAbs, fileSaveName).ToLower();
File.WriteAllBytes(fileAbsPath, fileBytes);
var newFile = new BookingFile
{
FileName = fileSaveName,
FilePath = fileRelaPath,
TypeCode = "ruhuotongzhi",
TypeName = ".pdf",
};
await _bookingfile.InsertAsync(newFile);
#endregion
//货运动态
var bsl = new BookingStatusLog();
bsl.BookingId = bookingId;
bsl.Status = $"放舱给客户";
bsl.OpTime = DateTime.Now;
bsl.Category = "ship";
bsl.MBLNO = order.MBLNO;
await _repStatuslog.InsertAsync(bsl);
//订舱状态
await SaveBookingStatus(bookingId, "sta_letter_yard", "放舱");
#region 发送邮件
var mailSubject = $"放舱信息:{order.MBLNO}/{order.CARRIERID}/{order.VESSEL}/{order.VOYNO}/PO:{order.PONO}/{order.TenantName}";
var extContent = string.Empty;
if (order.CARGOID == "R") //冻柜
{
extContent = $"温度:{order.TEMPSET}{order.TEMPID} <br/>通风:{order.REEFERF} <br/>湿度:{order.HUMIDITY}<br/>";
}
else if (order.CARGOID == "D") //危险品
{
extContent = $"危险品等级:{order.DCLASS} <br/>危险品编号:{order.DUNNO}<br/>";
}
var mailContent = $@"TO:{order.CUSTOMERNAME} 贵司委托我司代理订舱出口的货物信息如下,详情请见附件,谢谢!<br/>
提单号:{order.MBLNO}<br/>
船名航次:{order.VESSEL}/{order.VOYNO}<br/>
目的港:{order.PORTDISCHARGE}<br/>
预计船期:{(order.ETD.HasValue ? order.ETD.Value.Date.ToString("yyyy-MM-dd") : "")}<br/>
{order.YARD}<br/>
{order.SHIPAGENCY}<br/>
{order.CLOSINGDATE}<br/>
{order.CLOSEDOCDATE}<br/>
VGM{order.CLOSEVGMDATE}<br/>
{extContent}
{order.YARDREMARK}<br/>
<a href='{orderUrl.UrlTxxp}'>{orderUrl.UrlTxxp}</a><br/>
VGM<a href='{orderUrl.UrlVgm}'>{orderUrl.UrlVgm}</a><br/>
<br/>
<span style='color:red;'></span><br/>
<span style='color:red;'></span><br/>
<span style='color:red;'></span><br/>
<span style='color:red;'>VGMVGMVGM</span><br/>
<br/>
{UserManager.Name}<br/>
{user.Tel} {user.Phone}<br/>
{user.Email}
<br/>";
var sendResult = await MailSendHelper.SendMail(mailAcc, mailSubject, mailContent, letterYard.AttnMail);
if (!sendResult.Key)
{
_logger.LogError($"放舱邮件发送失败:从{mailAcc.MailAccount}到{letterYard.AttnMail},主题 {mailSubject}");
throw Oops.Bah($"邮件发送失败:{sendResult.Value}");
}
#endregion
}
/// <summary>
/// 获取放舱pdf
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/LetterYardPdf")]
public async Task<IActionResult> LetterYardPdf(long bookingId)
{
var letterYard = await _repLetterYard.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (letterYard == null)
{
throw Oops.Bah("放舱信息未找到,请先保存数据");
}
var bs = await GetReportFile(bookingId, "fangcang", 1);
var fileName = HttpUtility.UrlEncode($"{bookingId}_{DateTime.Now.Ticks}.pdf", Encoding.GetEncoding("UTF-8"));
var result = new FileContentResult(bs, "application/octet-stream") { FileDownloadName = fileName };
return result;
}
/// <summary>
/// 获取放舱excel
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/LetterYardXlsx")]
public async Task<IActionResult> LetterYardXlsx(long bookingId)
{
var letterYard = await _repLetterYard.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (letterYard == null)
{
throw Oops.Bah("放舱信息未找到,请先保存数据");
}
var bs = await GetReportFile(bookingId, "fangcang", 2);
var fileName = HttpUtility.UrlEncode($"{bookingId}_{DateTime.Now.Ticks}.xlsx", Encoding.GetEncoding("UTF-8"));
var result = new FileContentResult(bs, "application/octet-stream") { FileDownloadName = fileName };
return result;
}
/// <summary>
/// 生成报表文件
/// </summary>
/// <param name="bookingId"></param>
/// <param name="type">类型1pdf、2xlsx</param>
/// <param name="typeCode">报表类型代码例如fangcang、samplebill等</param>
/// <returns></returns>
[NonAction]
private async Task<byte[]> GetReportFile(long bookingId, string typeCode, int type = 1)
{
//打印报表服务地址
var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "url_report_generate").Value;
if (!reportUrl.EndsWith("/"))
{
reportUrl += "/";
}
//订舱数据
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
if (order == null)
{
throw Oops.Bah(BookingErrorCode.BOOK001);
}
var printTemplate = _repPrintTemplate.FirstOrDefault(x => x.TenantId == order.TenantId && x.TypeCode == typeCode);
if (printTemplate == null)
{
throw Oops.Bah(BookingErrorCode.BOOK115);
}
var opt = App.GetOptions<PrintTemplateOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath);
if (!File.Exists(fileAbsPath))
{
throw Oops.Bah(BookingErrorCode.BOOK115);
}
_logger.LogInformation($"准备调用报表生成id{bookingId},文件:{printTemplate.FileName}");
var genUrl = $"{reportUrl}Report/BookingReport?bookingId={bookingId}&type={type}";
var rtn = await genUrl
.SetContentType("multipart/form-data")
.SetBodyBytes(("file", File.ReadAllBytes(fileAbsPath), HttpUtility.UrlEncode(printTemplate.FileName, Encoding.GetEncoding("UTF-8"))))
.PostAsStringAsync();
var jobjRtn = JObject.Parse(rtn);
_logger.LogInformation($"调用报表生成返回:{rtn}");
if (jobjRtn.GetBooleanValue("Success"))
{
//调用读取文件
var fn = jobjRtn.GetStringValue("Data");
_logger.LogInformation($"准备调用读取报表文件id{bookingId},文件名:{fn}");
var readFileUrl = $"{reportUrl}Report/GetFile?fileName={fn}";
var bs = await readFileUrl.GetAsByteArrayAsync();
_logger.LogInformation($"调用读取报表文件返回:{bs.Length}");
return bs;
}
else
{
throw Oops.Bah($"生成报表文件失败:{jobjRtn.GetStringValue("Message")}");
}
}
#endregion
#region 下货纸
/// <summary>
/// 发送下货纸
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpPost("/BookingOrder/SendXHZ")]
public async Task SendXHZ(long bookingId)
{
var rtn = await XiahuozhiHelpler.Send(bookingId, "9");
if (!rtn.Key)
{
throw Oops.Bah($"发送失败:{rtn.Value}");
}
//订舱状态
await SaveBookingStatus(bookingId, "sta_xhz", "下货纸");
}
#endregion
#region 样单(提单确认)
/// <summary>
/// 样单
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/SampleBill")]
public async Task<BookingSampleBillOutput> SampleBill(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
var samp = await _repSampleBill.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (samp == null)
{
var user = _repUser.FirstOrDefault(x => x.Id == UserManager.UserId);
samp = new BookingSampleBill()
{
BookingId = bookingId,
Description = order.DESCRIPTION,
FromName = user.Name,
FromTel = user.Tel,
FromMail = user.Email,
};
}
var output = samp.Adapt<BookingSampleBillOutput>();
return output;
}
/// <summary>
/// 保存(新增或修改)样单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/BookingSampleBill/Save")]
public async Task SampleBillSave(UpdateBookingSampleBillInput input)
{
if (input.Id == 0)
{
var entity = input.Adapt<BookingSampleBill>();
await _repSampleBill.InsertAsync(entity);
}
else
{
var entity = _repSampleBill.FirstOrDefault(x => x.BookingId == input.Id);
entity = input.Adapt(entity);
await _repSampleBill.UpdateAsync(entity);
}
}
/// <summary>
/// 获取样单pdf
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/SampleBillPdf")]
public async Task<IActionResult> SampleBillPdf(long bookingId)
{
var samp = await _repSampleBill.FirstOrDefaultAsync(x => x.BookingId == bookingId);
if (samp == null)
{
throw Oops.Bah("请先保存提单确认数据后再继续");
}
var bs = await GetReportFile(bookingId, "tidanqueren");
var fileName = HttpUtility.UrlEncode($"{bookingId}_{DateTime.Now.Ticks}.xlsx", Encoding.GetEncoding("UTF-8"));
var result = new FileContentResult(bs, "application/octet-stream") { FileDownloadName = fileName };
return result;
}
#endregion
#region 小票链接
/// <summary>
/// 获取提箱小票链接
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/TxxpLink")]
public async Task<string> TxxpLink(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
if (order == null)
{
throw Oops.Bah(BookingErrorCode.BOOK001);
}
var ordUrl = _repOrderUrl.FirstOrDefault(x => x.BookingId == bookingId);
if (ordUrl == null)
{
ordUrl = new BookingOrderUrl();
ordUrl.BookingId = bookingId;
await _repOrderUrl.InsertAsync(ordUrl);
}
if (!string.IsNullOrEmpty(ordUrl.UrlTxxp))
{
return ordUrl.UrlTxxp;
}
//校验船公司
if (string.IsNullOrEmpty(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK118);
}
//判断船公司是否支持
var allowCarrier = _cache.GetAllDictData().Result.Where(x => x.TypeCode == "txxp_carrier_list").Select(x => x.Code).ToList();
if (!allowCarrier.Contains(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK117);
}
//亿通账号
var ytAcc = _repWebAcc.FirstOrDefault(x => x.CreatedUserId == UserManager.UserId && x.TypeCode == "YitongWeb");
if (ytAcc == null)
{
throw Oops.Bah(BookingErrorCode.BOOK119);
}
//场站转换
var yardset = _cache.GetAllMappingYard().Result.FirstOrDefault(y => y.Code == order.YARDID && y.Module == "BookingTxxp");
if (yardset == null)
{
throw Oops.Bah(BookingErrorCode.BOOK120, order.YARDID);
}
var ctns = await _repCtn.Where(x => x.BILLID == bookingId).ToListAsync();
//校验箱子数据录入
if (ctns.Where(c => string.IsNullOrEmpty(c.CTNALL) || !c.CTNNUM.HasValue).Count() > 0)
{
throw Oops.Bah(BookingErrorCode.BOOK121);
}
//箱型映射
var ctnMapping = await _cache.GetAllMappingCtn();
ctnMapping = ctnMapping.Where(x => x.Module == "BookingTxxp").ToList();
if (ctnMapping.Count == 0)
{
throw Oops.Bah(BookingErrorCode.BOOK122);
}
var expCode = ctns.Select(x => x.CTNCODE).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
if (expCode.Count > 0)
{
throw Oops.Bah(BookingErrorCode.BOOK123, string.Join(',', expCode));
}
var user = await _repUser.FirstOrDefaultAsync(x => x.Id == UserManager.UserId);
//调用小票服务
var dicUrlTxxp = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "txxp_service");
var postObj = new
{
SystemCode = "djy_hechuan",
CarrierCode = order.CARRIERID,
billOrderId = order.Id.ToString(),
sendOrderCode = order.MBLNO,
userId = UserManager.DjyUserId,
customerId = order.CUSTOMERID.ToString(),
// userName = currUser.CODENAME,
//userPassword = currUser.PASSWORD,
operatorName = UserManager.Name,
depotCode = yardset.MapCode,
depotName = yardset.MapName,
AgentName = UserManager.TENANT_NAME,
linkName = UserManager.Name,
linkMobile = user.Tel,
CustomerName = $"{UserManager.TENANT_NAME}+{UserManager.Name}", //公司名称+用户姓名
memo = string.Empty,
boxInfo = ctns.Select(c =>
{
return new
{
boxType = ctnMapping.First(x => x.Code == c.CTNCODE).MapCode,
boxCount = c.CTNNUM.Value
};
}),
sysLoginName = ytAcc.Account,
sysPsssword = ytAcc.Password
};
string strPostObj = postObj.ToJsonString();
_logger.LogInformation($"调用提箱小票接口传递数据:{strPostObj}");
var strResp = await dicUrlTxxp.Value.SetBody(postObj).PostAsStringAsync();
_logger.LogInformation($"调用提箱小票接口返回:{strResp}");
var jobjResp = JObject.Parse(strResp);
int respCode = jobjResp.GetIntValue("code");
if (respCode != 200)
{
throw Oops.Bah(BookingErrorCode.BOOK124, jobjResp.GetStringValue("message"));
}
//保存url
var txxpUrl = jobjResp.GetStringValue("data");
ordUrl.UrlTxxp = txxpUrl;
await _repOrderUrl.UpdateAsync(ordUrl);
//货运动态
var bsl = new BookingStatusLog();
bsl.BookingId = bookingId;
bsl.Status = $"生成提箱小票链接";
bsl.OpTime = DateTime.Now;
bsl.Category = "ship";
bsl.MBLNO = order.MBLNO;
await _repStatuslog.InsertAsync(bsl);
return txxpUrl;
}
#endregion
#region VGM及VMG链接
/// <summary>
/// 获取VGM、VGM SI链接
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpGet("/BookingOrder/VgmLink")]
public async Task<string[]> VgmLink(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
if (order == null)
{
throw Oops.Bah(BookingErrorCode.BOOK001);
}
var ordUrl = _repOrderUrl.FirstOrDefault(x => x.BookingId == bookingId);
if (ordUrl == null)
{
ordUrl = new BookingOrderUrl();
ordUrl.BookingId = bookingId;
await _repOrderUrl.InsertAsync(ordUrl);
}
if (!string.IsNullOrEmpty(ordUrl.UrlVgm))
{
return new string[] { ordUrl.UrlVgm, ordUrl.UrlVgmSi };
}
//校验船公司
if (string.IsNullOrEmpty(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK118);
}
var ctns = await _repCtn.Where(x => x.BILLID == bookingId).ToListAsync();
//判断船公司是否支持
var allowCarrier = _cache.GetAllDictData().Result.Where(x => x.TypeCode == "vgm_carrier_list").Select(x => x.Code).ToList();
if (!allowCarrier.Contains(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK117);
}
//船公司网站账号
var carrWebAccMap = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "carrier_web_account_mapping" && x.Code == order.CARRIERID);
var webacc = _repWebAcc.FirstOrDefault(x => x.TypeCode == carrWebAccMap.Value && x.CreatedUserId == UserManager.UserId);
if (webacc == null)
{
throw Oops.Bah(BookingErrorCode.BOOK125);
}
//场站转换
var yardset = _cache.GetAllMappingYard().Result.FirstOrDefault(y => y.Code == order.YARDID && y.Module == "BookingVgm");
if (yardset == null)
{
throw Oops.Bah(BookingErrorCode.BOOK120, order.YARDID);
}
//校验箱子数据录入
if (ctns.Where(c => string.IsNullOrEmpty(c.CTNALL) || !c.CTNNUM.HasValue).Count() > 0)
{
throw Oops.Bah(BookingErrorCode.BOOK121);
}
//箱型映射
var ctnMapping = await _cache.GetAllMappingCtn();
ctnMapping = ctnMapping.Where(x => x.Module == "BookingVgm").ToList();
if (ctnMapping.Count == 0)
{
throw Oops.Bah(BookingErrorCode.BOOK122);
}
var expCode = ctns.Select(x => x.CTNCODE).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
if (expCode.Count > 0)
{
throw Oops.Bah(BookingErrorCode.BOOK123, string.Join(',', expCode));
}
//接收反馈地址
var dicUrlVgmResp = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_reponse" && x.Code == "vgm_si_post_reponse");
var dicUrlSiResp = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_reponse" && x.Code == "si_post_response");
var user = await _repUser.FirstOrDefaultAsync(x => x.Id == UserManager.UserId);
//调用vgm链接服务
var dicUrl = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "vgm_link_service");
var postObj = new
{
SystemCode = "djy_hechuan",
billOrderId = order.Id.ToString(),
sendOrderCode = order.MBLNO,
customerName = $"{UserManager.TENANT_NAME}+{UserManager.Name}", //公司名称+用户姓名
customerId = order.CUSTOMERID.ToString(),
agentName = string.IsNullOrEmpty(order.FORWARDER) ? UserManager.TENANT_NAME : order.FORWARDER,
carrierCode = order.CARRIERID,
userName = webacc.Account,
userPassword = webacc.Password,
depotCode = yardset.MapCode,
depotName = order.YARD,
linkName = UserManager.Name,
linkMobile = user.Tel,
linkEmail = user.Email,
userId = UserManager.DjyUserId,
returnUrl = dicUrlVgmResp?.Value,
shipName = order.VESSEL,
voyNo = order.VOYNO,
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
potrSend = order.PORTLOAD,
potrGoal = order.PORTDISCHARGE,
boxinfoStr = order.CNTRTOTAL,
vgmEndTimeStr = order.CLOSEVGMDATE.HasValue ? order.CLOSEVGMDATE.Value.ToString("yyyy-MM-dd") : string.Empty,
returnOkUrl = "",
SiReturnUrl = dicUrlSiResp?.Value,
DataInfoJson = new
{
order.SHIPPER,
order.CONSIGNEE,
order.NOTIFYPARTY,
order.MARKS,
order.DESCRIPTION,
order.BLFRT,
order.SERVICE,
order.ISSUETYPE,
order.TRANSPORT,
order.TRANSPORTID,
order.DESTINATION,
order.DESTINATIONID,
order.KINDPKGS,
order.THIRDPAYADDR,
order.PORTLOAD,
order.PORTLOADID,
order.PORTDISCHARGE,
order.PORTDISCHARGEID
}
};
string strPostObj = postObj.ToJsonString();
_logger.LogInformation($"调用VGM链接接口 {dicUrl.Value} 传递数据:{strPostObj}");
var strResp = await dicUrl.Value.SetBody(postObj).PostAsStringAsync();
_logger.LogInformation($"调用VGM链接接口返回{strResp}");
var jobjResp = JObject.Parse(strResp);
int respCode = jobjResp.GetIntValue("code");
if (respCode != 200)
{
throw Oops.Bah(BookingErrorCode.BOOK126, jobjResp.GetStringValue("message"));
}
//保存url
var memoData = jobjResp.GetJObjectValue("memoData");
ordUrl.UrlVgm = memoData.GetStringValue("vgmUrl");
ordUrl.UrlVgmSi = memoData.GetStringValue("vgmAndSiUrl");
await _repOrderUrl.UpdateAsync(ordUrl);
//货运动态
var bsl = new BookingStatusLog();
bsl.BookingId = bookingId;
bsl.Status = $"生成VGM链接";
bsl.OpTime = DateTime.Now;
bsl.Category = "ship";
bsl.MBLNO = order.MBLNO;
await _repStatuslog.InsertAsync(bsl);
return new string[] { ordUrl.UrlVgm, ordUrl.UrlVgmSi };
}
/// <summary>
/// 直发VGM单票
/// </summary>
/// <param name="bookingId"></param>
/// <returns></returns>
[HttpPost("/BookingOrder/VgmSend")]
public async Task VgmSend(long bookingId)
{
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
var ctns = _repCtn.Where(x => x.BILLID == bookingId).ToList();
var dicUrlVgm = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "vgm_service_single");
//船公司
if (string.IsNullOrEmpty(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK118);
}
//判断船公司是否支持
var allowCarrier = _cache.GetAllDictData().Result.Where(x => x.TypeCode == "vgm_carrier_list").Select(x => x.Code).ToList();
if (!allowCarrier.Contains(order.CARRIERID))
{
throw Oops.Bah(BookingErrorCode.BOOK117);
}
//船公司网站账号
var carrWebAccMap = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "carrier_web_account_mapping" && x.Code == order.CARRIERID);
var webacc = _repWebAcc.FirstOrDefault(x => x.TypeCode == carrWebAccMap.Value && x.CreatedUserId == UserManager.UserId);
if (webacc == null)
{
throw Oops.Bah(BookingErrorCode.BOOK125);
}
//提单号不能为空
if (string.IsNullOrEmpty(order.MBLNO))
{
throw Oops.Bah(BookingErrorCode.BOOK127);
}
//箱型映射
var ctnMapping = await _cache.GetAllMappingCtn();
ctnMapping = ctnMapping.Where(x => x.Module == "BookingVgm").ToList();
if (ctnMapping.Count == 0)
{
throw Oops.Bah(BookingErrorCode.BOOK122);
}
var expCode = ctns.Select(x => x.CTNCODE).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
if (expCode.Count > 0)
{
throw Oops.Bah(BookingErrorCode.BOOK123, string.Join(',', expCode));
}
#region 箱信息校验2022-7-1修改【累加】的必须有重量、皮重和称重重量【总重】的只需要称重重量不为空
if (ctns.Where(c => c.WEIGHTYPE == "累加" &&
(
string.IsNullOrEmpty(c.CNTRNO)
|| !c.WEIGHKGS.HasValue
|| c.WEIGHKGS == 0
|| !c.TAREWEIGHT.HasValue
|| c.TAREWEIGHT == 0
|| !c.KGS.HasValue
|| c.KGS == 0)
).Count() > 0)
{
throw Oops.Bah("称重方式为累加时,箱号、重量、箱皮重以及称重重量都不能为空");
}
if (ctns.Where(c => c.WEIGHTYPE == "总重" &&
(
string.IsNullOrEmpty(c.CNTRNO)
|| !c.WEIGHKGS.HasValue
|| c.WEIGHKGS == 0)
).Count() > 0)
{
throw Oops.Bah("称重方式为总重时,箱号和称重重量都不能为空");
}
#endregion
//场站转换
var yardset = _cache.GetAllMappingYard().Result.FirstOrDefault(y => y.Code == order.YARDID && y.Module == "BookingVgm");
if (yardset == null)
{
throw Oops.Bah(BookingErrorCode.BOOK120, order.YARDID);
}
var user = await _repUser.FirstOrDefaultAsync(x => x.Id == UserManager.UserId);
int idx = 1;
//调用接口
var dicUrl = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "vgm_service_single");
var sendObj = new
{
SystemCode = "djy_hechuan",
billOrderId = order.Id.ToString(),
sendOrderCode = order.MBLNO,
customerName = $"{UserManager.TENANT_NAME}+{UserManager.Name}", //公司名称+用户姓名
customerId = order.CUSTOMERID.ToString(),
agentName = string.IsNullOrEmpty(order.FORWARDER) ? UserManager.TENANT_NAME : order.FORWARDER,
carrierCode = order.CARRIERID,
userName = webacc.Account,
userPassword = webacc.Password,
depotCode = yardset.MapCode,
depotName = yardset.MapName,
linkName = UserManager.Name,
linkMobile = user.Tel,
linkEmail = user.Email,
userId = user.DjyUserId,
returnUrl = "",
shipName = order.VESSEL,
voyNo = order.VOYNO,
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
potrSend = order.PORTLOAD,
potrGoal = order.PORTDISCHARGE,
boxinfoStr = order.CNTRTOTAL,
vgmEndTimeStr = order.CLOSEVGMDATE.HasValue ? order.CLOSEVGMDATE.Value.ToString("yyyy-MM-dd") : string.Empty,
BoxInfo = ctns.Select(c => new
{
index = idx++,
boxType = c.CTNALL,
boxcount = c.CTNNUM.HasValue ? c.CTNNUM.Value : 0,
code = c.CNTRNO,
sealCode = c.SEALNO,
weigth = c.KGS,
weigthTare = c.TAREWEIGHT,
weigthTotal = c.WEIGHKGS,
weigthType = c.WEIGHTYPE == "累加" ? "SM2" : "SM1"
}).ToList(),
returnOkUrl = ""
};
string strPostObj = sendObj.ToJsonString();
_logger.LogInformation($"调用VGM直发接口 {dicUrl.Value} 传递数据:{strPostObj}");
var strResp = await dicUrl.Value.SetBody(sendObj).PostAsStringAsync();
_logger.LogInformation($"调用VGM直发接口返回{strResp}");
var jobjResp = JObject.Parse(strResp);
int respCode = jobjResp.GetIntValue("code");
if (respCode != 200)
{
throw Oops.Bah(BookingErrorCode.BOOK128, jobjResp.GetStringValue("message"));
}
//货运动态
var bsl = new BookingStatusLog();
bsl.BookingId = bookingId;
bsl.Status = $"直发VGM";
bsl.OpTime = DateTime.Now;
bsl.Category = "ship";
bsl.MBLNO = order.MBLNO;
await _repStatuslog.InsertAsync(bsl);
}
#endregion
#region 订舱、截单EDI
/// <summary>
/// 发送订舱、截单EDI
/// </summary>
/// <param name="model">订舱、截单EDI请求</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingOrder/SendBookingOrClosingEDI")]
public async Task<string> SendBookingOrClosingEDI(BookingOrClosingEDIOrderDto model)
{
/*
发送订舱和截单EDI的流程
1、通过订单号获取订单信息。
2、检查订单的必填信息。
3、根据船公司ID获取对应的路由枚举。
4、获取EDI转换参数。集装箱型号、包装方式
5、读取EDI的配置信息获取船公司相关的EDI配置。
6、检查详细信息。
7、生成订舱或者截单EDI报文并返回文件保存绝对路径。
*/
if (model.Id == 0)
throw Oops.Bah("订单Id不能为空");
var order = _rep.FirstOrDefault(a => a.Id == model.Id);
if (order == null)
throw Oops.Bah($"获取订单信息失败");
CheckBookingOrClosingEDI(order);
EDIRouteEnum ediRouteEnum = GetEDIRoute(order.CARRIERID);
if (ediRouteEnum == EDIRouteEnum.NULL)
throw Oops.Bah($"当前船公司没有对应的请求路由配置");
//集装箱型
var ediCtnList = _cache.GetAllMappingCtn().GetAwaiter().GetResult()
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
//包装
var ediPkgsList = _cache.GetAllMappingPackage().GetAwaiter().GetResult()
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
//EDI SO\SI代码
var ediSOSICfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult()
.FirstOrDefault(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
&& t.Code.Equals(order.CARRIERID, StringComparison.OrdinalIgnoreCase));
if (ediSOSICfg == null || string.IsNullOrWhiteSpace(ediSOSICfg.MapCode))
throw Oops.Bah($"CARRIERID={order.CARRIERID} 发送SO(SI)的船公司EDI代码未找到");
var ediModel = new EDIBaseModel();
var ftpSet = _cache.GetAllEdiSetting().GetAwaiter().GetResult()
.FirstOrDefault(a => a.EDICODE.Equals(ediRouteEnum.ToString(), StringComparison.OrdinalIgnoreCase));
if (ftpSet == null)
throw Oops.Bah($"获取EDICODE={ediRouteEnum.ToString()}的EDI参数设置失败");
ediModel.SENDCODE = ftpSet.SENDCODE;
ediModel.SENDNAME = ftpSet.SENDNAME;
ediModel.RECEIVECODE = ftpSet.RECEIVECODE;
ediModel.filetype = model.sendType; //订舱
ediModel.filerole = model.fileRole;
//读取文件配置
var fileCfg = App.GetOptions<BookingAttachOptions>();
string filePath = $"{Path.Combine(!string.IsNullOrWhiteSpace(fileCfg.basePath) ? fileCfg.basePath : App.WebHostEnvironment.WebRootPath, fileCfg.relativePath)}/edifiles/{order.BSNO}";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
filePath = filePath.Replace("\\", "/");
//预先创建目录
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
ediModel.filerpath = filePath;
ediModel.UseForWarderCode = model.useForwarderCode;
ediModel.ForWarderCode = model.forwarderCode;
ediModel.ForWarderName = model.forwarderName;
ediModel.BSLIST = new List<MsOpSeaeEDIBaseModel>();
var primaryModel = order.Adapt<MsOpSeaeEDIBaseModel>();
primaryModel.CARRIEREDICODE = ediSOSICfg.MapCode;
var ediPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(order.KINDPKGS, StringComparison.OrdinalIgnoreCase));
if (ediPkgs == null || string.IsNullOrWhiteSpace(ediPkgs.MapCode))
throw Oops.Bah($"包装{order.KINDPKGS}的EDI代码未找到");
primaryModel.KINDPKGS_EDI_CODE = ediPkgs.MapCode?.Trim();
//箱信息
var contaList = _repCtn.AsQueryable().Where(t => t.BILLID == order.Id).ToList();
primaryModel.CTNLIST = new List<MsOpSeaeCtnEDIBaseModel>();
//集装箱
foreach (var conta in contaList)
{
var contaModel = conta.Adapt<MsOpSeaeCtnEDIBaseModel>();
//EDI箱型
var currConta = ediCtnList.FirstOrDefault(x => x.Code.Equals(conta.CTNCODE, StringComparison.OrdinalIgnoreCase));
if (currConta == null)
throw Oops.Oh($"箱型{conta.CTNCODE}的EDI代码未找到");
contaModel.CTNALLCODE = currConta.MapCode;
//EDI包装
var ediContaPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(conta.KINDPKGS, StringComparison.OrdinalIgnoreCase));
if (currConta == null)
throw Oops.Oh($"集装箱包装{conta.KINDPKGS}的EDI代码未找到");
contaModel.KINDPKGS_EDI_CODE = ediContaPkgs.MapCode;
primaryModel.CTNLIST.Add(contaModel);
}
//多品名
var cargoList = _ctndetailrep.AsQueryable().Where(t => contaList.Select(a => a.Id).ToArray().Contains(t.CTNID.Value)).ToList();
primaryModel.CTNGOODSLIST = new List<MsOpSeaeCtnDetailEDIBaseModel>();
foreach (var cargo in cargoList)
{
MsOpSeaeCtnDetailEDIBaseModel cargoModel = cargo.Adapt<MsOpSeaeCtnDetailEDIBaseModel>();
cargoModel.CNTRNO = contaList.FirstOrDefault(a => a.Id == cargo.CTNID.Value).CNTRNO;
var ediDetailPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(cargo.KINDPKGS, StringComparison.OrdinalIgnoreCase));
if (ediDetailPkgs == null)
throw Oops.Oh($"货明细的包装{cargo.KINDPKGS}的EDI代码未找到");
cargoModel.KINDPKGS_EDI_CODE = ediDetailPkgs.MapCode;
primaryModel.CTNGOODSLIST.Add(cargoModel);
}
//这里临时赋值,等明确对应的扩展表字段后赋值
#if DEBUG
primaryModel.MasterBOLIndicator = "A1";
primaryModel.ConsigneeEdiCode = "CEE1";
primaryModel.ShipperEdiCode = "SHIP1";
primaryModel.SalesRepCode = "SALE1";
primaryModel.ACIHBL = String.Empty;
primaryModel.S0CC0C = String.Empty;
primaryModel.EDIREMARK = String.Empty;
primaryModel.AMSCONSIGNEE = String.Empty;
primaryModel.AMSNOTIFYPARTY = String.Empty;
primaryModel.EDIATTN = "CEE1";
primaryModel.EDIATTNTEL = "CEE1";
primaryModel.EDIATTNEMAIL = "CEE1";
primaryModel.OpEName = "CEE1";
primaryModel.OpTel = "CEE1";
primaryModel.OpEmail = "CEE1";
#endif
ediModel.BSLIST.Add(primaryModel);
var result = await InnerSendBookingOrClosingEDI(model, ediModel, ediRouteEnum);
if (!result.succ)
{
throw Oops.Bah(result.msg);
}
//上传FTP
var sendStatus = await InnerSendBookingOrClosingEDIToFTP(result.extra.ToString(), ftpSet);
return result.extra.ToString();
}
#endregion
/// <summary>
/// 上传FTP
/// </summary>
/// <param name="filePath">EDI文件路径</param>
/// <param name="ediCfg">FTP配置</param>
/// <returns>true-成功 false-失败</returns>
private async Task<bool> InnerSendBookingOrClosingEDIToFTP(string filePath, DjyEdiSetting ediCfg)
{
CancellationTokenSource cts = new CancellationTokenSource();
//后续发送
var ftpPostObj = new
{
host = ediCfg.SERVERIP,
username = ediCfg.USERNAME,
pwd = ediCfg.PASSWORD,
path = ediCfg.FOLDERNAME
};
var ftpSpiderUrl = _cache.GetAllDictData().GetAwaiter().GetResult().FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "booking_edi_ftp_server").Value;
var fileInfo = new FileInfo(filePath);
Log.Information($"准备请求发送ftp{ftpSpiderUrl} ,参数:{ftpPostObj.ToJsonString()},文件:{filePath}");
string strJoin = System.IO.File.ReadAllText(filePath);
DateTime bDate = DateTime.Now;
_logger.LogInformation("FTP 开始上传");
var res = await ftpSpiderUrl
.SetContentType("multipart/form-data")
.SetBody(ftpPostObj)
.SetBodyBytes(("file", Encoding.UTF8.GetBytes(strJoin), fileInfo.Name))
.PostAsStringAsync();
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation($"FTP 上传完成 上传文件大小:{fileInfo.Length} 用时:{timeDiff}ms.,{strJoin}");
Log.Information($"发送ftp返回{res}");
var jobjRetn = JObject.Parse(res);
if (jobjRetn.GetStringValue("status") != "1")
{
return false;
}
return true;
}
/// <summary>
/// 触发订舱
/// </summary>
/// <param name="model"></param>
/// <param name="ediModel"></param>
/// <param name="ediRouteEnum"></param>
/// <returns></returns>
[NonAction]
private async Task<CommonWebApiResult> InnerSendBookingOrClosingEDI(BookingOrClosingEDIOrderDto model, EDIBaseModel ediModel, EDIRouteEnum ediRouteEnum)
{
CommonWebApiResult result = new CommonWebApiResult();
try
{
if (ediRouteEnum == EDIRouteEnum.PIL)
{
#region PIL
string strCheck = PILEdiHelper.IsCreatePILEDI(ediModel);
_logger.LogInformation($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
if (!string.IsNullOrWhiteSpace(strCheck))
throw Oops.Bah($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
var currRlt = PILEdiHelper.CreateEdiPIL(ediModel);
#endregion
result.succ = currRlt.succ;
result.extra = currRlt.succ ? currRlt.extra.ToString() : "";
}
else if (ediRouteEnum == EDIRouteEnum.TSL)
{
#region TSL
string strCheck = TSLEdiHelper.IsCreateTSL(ediModel);
_logger.LogInformation($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
if (!string.IsNullOrWhiteSpace(strCheck))
throw Oops.Bah($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
CommonWebApiResult currRlt = new CommonWebApiResult();
if (model.sendType == "B")
{
currRlt = TSLEdiHelper.CreateEdiTSL(ediModel);
}
else if (model.sendType == "E")
{
currRlt = TSLEdiHelper.CreateEdiTSLSI(ediModel);
}
#endregion
result.succ = currRlt.succ;
result.extra = currRlt.succ ? currRlt.extra.ToString() : "";
//鐩存帴鍙戦€佹姤鏂囧埌FTP鏈嶅姟鍣?
if (model.send)
{
}
}
else if (ediRouteEnum == EDIRouteEnum.WY)
{
#region WY
string strCheck = WYEdiHelper.IsCreateWYEDI(ediModel);
_logger.LogInformation($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
if (!string.IsNullOrWhiteSpace(strCheck))
throw Oops.Bah($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
var currRlt = WYEdiHelper.CreateEdiWY(ediModel);
#endregion
result.succ = currRlt.succ;
result.extra = currRlt.succ ? currRlt.extra.ToString() : "";
}
else if (ediRouteEnum == EDIRouteEnum.YML)
{
#region YML
string strCheck = YMLEdiHelper.IsCreateYMLEDI(ediModel);
_logger.LogInformation($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
if (!string.IsNullOrWhiteSpace(strCheck))
throw Oops.Bah($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
CommonWebApiResult currRlt = new CommonWebApiResult();
if (model.sendType == "B")
{
currRlt = YMLEdiHelper.CreateEdiYML(ediModel);
}
else if (model.sendType == "E")
{
currRlt = YMLEdiHelper.CreateEdiYMLSI(ediModel);
}
#endregion
result.succ = currRlt.succ;
result.extra = currRlt.succ ? currRlt.extra.ToString() : "";
}
else if (ediRouteEnum == EDIRouteEnum.YT)
{
#region YT
string strCheck = YTEdiHelper.IsCreateYTEDI(ediModel);
_logger.LogInformation($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
if (!string.IsNullOrWhiteSpace(strCheck))
throw Oops.Bah($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
CommonWebApiResult currRlt = YTEdiHelper.CreateEdiYT(ediModel);
#endregion
result.succ = currRlt.succ;
result.extra = currRlt.succ ? currRlt.extra.ToString() : "";
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.Message;
}
return result;
}
/// <summary>
/// 检查订舱、截单EDI订单信息
/// </summary>
/// <param name="order"></param>
[NonAction]
private void CheckBookingOrClosingEDI(BookingOrder order)
{
if (string.IsNullOrWhiteSpace(order.CARRIERID))
throw Oops.Bah("船公司必须填写");
if (string.IsNullOrWhiteSpace(order.OPID))
throw Oops.Bah("未填写操作人");
if (string.IsNullOrWhiteSpace(order.KINDPKGS))
throw Oops.Bah("包装种类未填写");
}
/// <summary>
/// 根据船公司ID获取EDI的路由枚举
/// </summary>
/// <param name="carrierId">船公司ID</param>
/// <returns>返回适用的路由枚举</returns>
[NonAction]
private EDIRouteEnum GetEDIRoute(string carrierId)
{
EDIRouteEnum routeEnum = EDIRouteEnum.NULL;
var ediRouteCfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult()
.FirstOrDefault(t => t.Module.Equals(CONST_MAPPING_MODULE_ROUTE, StringComparison.OrdinalIgnoreCase)
&& t.Code.Equals(carrierId, StringComparison.OrdinalIgnoreCase));
if (ediRouteCfg != null && !string.IsNullOrWhiteSpace(ediRouteCfg.MapCode))
routeEnum = (EDIRouteEnum)System.Enum.Parse(typeof(EDIRouteEnum), ediRouteCfg.MapCode);
//switch (carrierId.ToUpper())
//{
// case "PIL":
// routeEnum = EDIRouteEnum.PIL;
// break;
// case "ONE":
// routeEnum = EDIRouteEnum.YT;
// break;
// case "TSL":
// routeEnum = EDIRouteEnum.TSL;
// break;
// case "YML":
// routeEnum = EDIRouteEnum.YML;
// break;
// case "WY":
// routeEnum = EDIRouteEnum.WY;
// break;
//}
return routeEnum;
}
#region 其他
/// <summary>
/// 获取用户报表的json
/// </summary>
/// <param name="id"></param>
[HttpGet("/BookingOrder/GenReportJson")]
public async Task<IActionResult> GenReportJson(long id)
{
var jsonUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "url_report_generate").Value;
if (!jsonUrl.EndsWith("/"))
{
jsonUrl += "/";
}
jsonUrl += "Report/BookingReportJson?bookingId=" + id;
var rtn = await jsonUrl.SetHttpMethod(HttpMethod.Get).GetAsStringAsync();
var fileName = HttpUtility.UrlEncode($"{id}.json", Encoding.GetEncoding("UTF-8"));
var result = new FileContentResult(Encoding.UTF8.GetBytes(rtn), "application/octet-stream") { FileDownloadName = fileName };
return result;
}
/// <summary>
/// 生成报表文件
/// </summary>
/// <param name="id"></param>
/// <param name="type">类型,对应字典中的【订舱打印模板类型】</param>
/// <returns></returns>
[HttpGet("/BookingOrder/GenReportFile")]
public async Task<IActionResult> GenReportFile(long id, string type)
{
//打印报表服务地址
var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "url_report_generate").Value;
if (!reportUrl.EndsWith("/"))
{
reportUrl += "/";
}
//订舱数据
var order = _rep.FirstOrDefault(x => x.Id == id);
if (order == null)
{
throw Oops.Bah(BookingErrorCode.BOOK001);
}
//打印模板
var printTemplate = _repPrint.FirstOrDefault(x => x.TenantId == order.TenantId && x.TypeCode == type);
if (printTemplate == null)
{
throw Oops.Bah(BookingErrorCode.BOOK112);
}
//读取配置路劲
var opt = App.GetOptions<PrintTemplateOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
//读取模板并调用接口
var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath).ToLower();
if (!File.Exists(fileAbsPath))
{
throw Oops.Bah(BookingErrorCode.BOOK112);
}
_logger.LogInformation($"准备调用报表生成id{id},文件:{printTemplate.FileName}");
var genUrl = reportUrl + "Report/BookingReport?bookingId=" + id;
var rtn = await genUrl
.SetContentType("multipart/form-data")
.SetBodyBytes(("file", File.ReadAllBytes(fileAbsPath), HttpUtility.UrlEncode(printTemplate.FileName, Encoding.GetEncoding("UTF-8"))))
.PostAsStringAsync();
var jobjRtn = JObject.Parse(rtn);
_logger.LogInformation($"调用报表生成返回:{rtn}");
if (jobjRtn.GetBooleanValue("Success"))
{
//调用读取文件
var fn = jobjRtn.GetStringValue("Data");
_logger.LogInformation($"准备调用读取文件id{id},文件名:{fn}");
var readFileUrl = reportUrl + "Report/GetFile?fileName=" + fn;
var bs = await readFileUrl.GetAsByteArrayAsync();
_logger.LogInformation($"调用读取文件返回:{bs.Length}");
var fileName = HttpUtility.UrlEncode($"{id}_{type}_{DateTime.Now.Ticks}.pdf", Encoding.GetEncoding("UTF-8"));
var result = new FileContentResult(bs, "application/octet-stream") { FileDownloadName = fileName };
return result;
}
else
{
throw Oops.Bah($"生成报表文件失败:{jobjRtn.GetStringValue("Message")}");
}
}
/// <summary>
/// 记录或更新订舱状态
/// </summary>
/// <param name="bookingId"></param>
/// <param name="code"></param>
/// <param name="name"></param>
/// <returns></returns>
[NonAction]
public async Task SaveBookingStatus(long bookingId, string code, string name)
{
var bookSta = _repBookingStatus.FirstOrDefault(x => x.BookingId == bookingId && x.StaCode == code);
if (bookSta == null)
{
//记录状态
bookSta = new BookingStatus();
bookSta.BookingId = bookingId;
bookSta.StaCode = code;
bookSta.StaName = name;
bookSta.StaTime = DateTime.Now;
await _repBookingStatus.InsertAsync(bookSta);
}
else
{
bookSta.StaTime = DateTime.Now;
await _repBookingStatus.UpdateAsync(bookSta);
}
}
#endregion
}
}