|
|
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;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using System.Net;
|
|
|
|
|
|
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;
|
|
|
private readonly SqlSugarRepository<BookingEDIExt> _bookingEDIExt;
|
|
|
|
|
|
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, SqlSugarRepository<BookingEDIExt> bookingEDIExt)
|
|
|
{
|
|
|
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;
|
|
|
this._bookingEDIExt = bookingEDIExt;
|
|
|
}
|
|
|
////传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.BSNO), u => u.BSNO.Contains(input.BSNO))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.BSSTATUS), u => u.BSSTATUS == input.BSSTATUS)
|
|
|
.WhereIF(input.BBSDATE != null, u => u.BSDATE >= input.BBSDATE)
|
|
|
.WhereIF(input.EBSDATE != null, u => u.BSDATE <= input.EBSDATE)
|
|
|
.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.Contains(input.BOOKINGNO))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.CONTRACTNO), u => u.CONTRACTNO.Contains(input.CONTRACTNO))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SERVICECONTRACTNO), u => u.SERVICECONTRACTNO.Contains(input.SERVICECONTRACTNO))
|
|
|
.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.VESSELID), u => u.VESSELID.Contains(input.VESSELID))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.VESSEL), u => u.VESSEL.ToLower().Contains(u.VESSEL.ToLower()))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.VOYNO), u => u.VOYNO.Contains(input.VOYNO))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.VOYNOINNER), u => u.VOYNOINNER.Contains(input.VOYNOINNER))
|
|
|
.WhereIF(input.BETD != null, u => u.ETD >= input.BETD)
|
|
|
.WhereIF(input.EETD != null, u => u.ETD <= input.EETD)
|
|
|
.WhereIF(input.BATD != null, u => u.ATD >= input.BATD)
|
|
|
.WhereIF(input.EATD != null, u => u.ATD <= input.EATD)
|
|
|
.WhereIF(input.BCLOSINGDATE != null, u => u.CLOSINGDATE >= input.BCLOSINGDATE)
|
|
|
.WhereIF(input.ECLOSINGDATE != null, u => u.CLOSINGDATE <= input.ECLOSINGDATE)
|
|
|
|
|
|
.WhereIF(input.BCLOSEDOCDATE != null, u => u.CLOSEDOCDATE >= input.BCLOSEDOCDATE)
|
|
|
.WhereIF(input.ECLOSEDOCDATE != null, u => u.CLOSEDOCDATE <= input.ECLOSEDOCDATE)
|
|
|
.WhereIF(input.BCLOSEVGMDATE != null, u => u.CLOSEVGMDATE >= input.BCLOSEVGMDATE)
|
|
|
.WhereIF(input.ECLOSEVGMDATE != null, u => u.CLOSEVGMDATE <= input.ECLOSEVGMDATE)
|
|
|
.WhereIF(input.BETA != null, u => u.ETA >= input.BETA)
|
|
|
.WhereIF(input.EETA != null, u => u.ETA <= input.EETA)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.PLACERECEIPT), u => u.PLACERECEIPT.Contains(input.PLACERECEIPT))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTLOAD), u => u.PORTLOAD.Contains(input.PORTLOAD))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTLOADID), u => u.PORTLOADID == input.PORTLOADID)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTDISCHARGEID), u => u.PORTDISCHARGEID == input.PORTDISCHARGEID)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.PORTDISCHARGE), u => u.PORTDISCHARGE.Contains(input.PORTDISCHARGE))
|
|
|
|
|
|
.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(input.BISSUEDATE != null, u => u.ISSUEDATE >= input.BISSUEDATE)
|
|
|
.WhereIF(input.EISSUEDATE != null, u => u.ISSUEDATE <= input.EISSUEDATE)
|
|
|
|
|
|
|
|
|
.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.Contains(input.HSCODE))
|
|
|
.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.Contains(input.COMPNAME))
|
|
|
.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 && input.CUSTOMERID != 0, 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<long> Add(AddBookingOrderInput input)
|
|
|
{
|
|
|
|
|
|
if (input.ParentId == 0)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(input.HBLNO))
|
|
|
{
|
|
|
throw Oops.Bah("主单不需要填写分单号");
|
|
|
}
|
|
|
if (string.IsNullOrWhiteSpace(input.MBLNO))
|
|
|
{
|
|
|
throw Oops.Bah("请填写提单号!");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(input.MBLNO))
|
|
|
{
|
|
|
throw Oops.Bah("请填写主提单号");
|
|
|
}
|
|
|
if (string.IsNullOrWhiteSpace(input.HBLNO))
|
|
|
{
|
|
|
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);
|
|
|
|
|
|
//这里保存有可能没有添加多品名,所有箱下没有货物信息
|
|
|
if (item.ctnDetailInputs != null)
|
|
|
{
|
|
|
foreach (var it in item.ctnDetailInputs)
|
|
|
{
|
|
|
var ctndetail = it.Adapt<BookingCtnDetail>();
|
|
|
ctndetail.CTNID = ctnentity.Id;
|
|
|
await _ctndetailrep.InsertAsync(ctndetail);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (input.BookingEDIExt != null)
|
|
|
{
|
|
|
//写入EDI扩展
|
|
|
var ediExtEntity = input.BookingEDIExt.Adapt<BookingEDIExt>();
|
|
|
|
|
|
ediExtEntity.BookingId = entity.Id;
|
|
|
|
|
|
await _bookingEDIExt.InsertAsync(ediExtEntity);
|
|
|
}
|
|
|
|
|
|
////添加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);
|
|
|
}
|
|
|
return entity.Id;
|
|
|
}
|
|
|
|
|
|
/// <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("主单不需要填写分单号");
|
|
|
}
|
|
|
if (string.IsNullOrWhiteSpace(input.MBLNO))
|
|
|
{
|
|
|
throw Oops.Bah("请填写提单号!");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(input.MBLNO))
|
|
|
{
|
|
|
throw Oops.Bah("请填写主提单号");
|
|
|
}
|
|
|
if (string.IsNullOrWhiteSpace(input.HBLNO))
|
|
|
{
|
|
|
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.AsQueryable().Where(x => x.Id == input.Id).FirstAsync();
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (input.BookingEDIExt != null)
|
|
|
{
|
|
|
//检索EDI扩展
|
|
|
var ediExtEntity = await _bookingEDIExt.FirstOrDefaultAsync(u => u.BookingId == input.Id);
|
|
|
|
|
|
if (ediExtEntity == null)
|
|
|
{
|
|
|
//写入EDI扩展
|
|
|
ediExtEntity = input.BookingEDIExt.Adapt<BookingEDIExt>();
|
|
|
ediExtEntity.BookingId = entity.Id;
|
|
|
|
|
|
await _bookingEDIExt.InsertAsync(ediExtEntity);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//更新EDI扩展
|
|
|
var currEdiExtEntity = input.BookingEDIExt.Adapt<BookingEDIExt>();
|
|
|
|
|
|
currEdiExtEntity.Id = ediExtEntity.Id;
|
|
|
currEdiExtEntity.BookingId = ediExtEntity.BookingId;
|
|
|
|
|
|
await _bookingEDIExt.AsUpdateable(ediExtEntity).IgnoreColumns(new string[] { nameof(ediExtEntity.Id),
|
|
|
nameof(ediExtEntity.BookingId) }).ExecuteCommandAsync();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
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 && !string.IsNullOrWhiteSpace(descriptor.Description))
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
//检索EDI扩展
|
|
|
var ediExtEntity = await _bookingEDIExt.FirstOrDefaultAsync(u => u.BookingId == Id);
|
|
|
|
|
|
if (ediExtEntity != null)
|
|
|
{
|
|
|
ordOut.BookingEDIExt = ediExtEntity.Adapt<BookingEDIExtDto>();
|
|
|
}
|
|
|
|
|
|
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");
|
|
|
if (key == null)
|
|
|
{
|
|
|
|
|
|
throw Oops.Bah("调用运踪接口相关账号未维护!");
|
|
|
}
|
|
|
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);
|
|
|
if (order == null)
|
|
|
{
|
|
|
throw Oops.Bah(BookingErrorCode.BOOK001);
|
|
|
}
|
|
|
|
|
|
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;'>若贵司自输VGM,请不要通过VGM链接提交数据,否则我司收取相关VGM申报费用。</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">类型,1:pdf、2:xlsx</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">订舱Id</param>
|
|
|
/// <param name="type">打印模板类型,根据字典传值</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpGet("/BookingOrder/Print")]
|
|
|
public async Task<IActionResult> Print(long bookingId, string type)
|
|
|
{
|
|
|
var bs = await GetReportFile(bookingId, type);
|
|
|
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;
|
|
|
}
|
|
|
#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($"获取订单信息失败");
|
|
|
|
|
|
var ediExtModel = _bookingEDIExt.FirstOrDefault(a => a.BookingId == model.Id);
|
|
|
|
|
|
if (ediExtModel == null)
|
|
|
throw Oops.Bah($"获取EDI信息失败");
|
|
|
|
|
|
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();
|
|
|
|
|
|
//这里是订舱时,默认取SOREMARK赋值到EDIREMARK
|
|
|
if (model.sendType == "B")
|
|
|
primaryModel.EDIREMARK = order.SOREMARK;
|
|
|
|
|
|
primaryModel.S0CC0C = ediExtModel.S0CC0C;
|
|
|
primaryModel.ACIHBL = ediExtModel.ACIHBL;
|
|
|
|
|
|
primaryModel.MasterBOLIndicator = ediExtModel.MasterBolIndicator;
|
|
|
primaryModel.ConsigneeEdiCode = ediExtModel.ConsigneeEdiCode;
|
|
|
primaryModel.ShipperEdiCode = ediExtModel.ShipperEdiCode;
|
|
|
primaryModel.SalesRepCode = ediExtModel.SalerCode;
|
|
|
|
|
|
primaryModel.EDIATTN = ediExtModel.EDIAttn;
|
|
|
primaryModel.EDIATTNTEL = ediExtModel.EDIAttnTel;
|
|
|
primaryModel.EDIATTNEMAIL = ediExtModel.EDIAttnMail;
|
|
|
|
|
|
primaryModel.AMSCONSIGNEE = ediExtModel.AMSConsignee;
|
|
|
primaryModel.AMSNOTIFYPARTY = ediExtModel.AMSNotifyParty;
|
|
|
|
|
|
primaryModel.OpEName = ediExtModel.OpEName;
|
|
|
primaryModel.OpTel = ediExtModel.OpTel;
|
|
|
primaryModel.OpEmail = ediExtModel.OpEmail;
|
|
|
|
|
|
primaryModel.GOODSNAME = ediExtModel.GoodsName;
|
|
|
|
|
|
//箱信息
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
#region 上传FTP
|
|
|
/// <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;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 触发订舱
|
|
|
/// <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;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检查订舱、截单EDI订单信息
|
|
|
/// <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("包装种类未填写");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 根据船公司ID获取EDI的路由枚举
|
|
|
/// <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;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region ocr
|
|
|
|
|
|
/// <summary>
|
|
|
/// 上传ocr文件
|
|
|
/// </summary>
|
|
|
/// <param name="file"></param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/BookingOrder/OcrUpFile")]
|
|
|
public async Task<string> OcrUpFile(IFormFile file)
|
|
|
{
|
|
|
//未上传文件
|
|
|
if (file == null || file.Length == 0)
|
|
|
{
|
|
|
throw Oops.Bah("未上传文件");
|
|
|
}
|
|
|
|
|
|
var originalFilename = file.FileName; // 文件原始名称
|
|
|
var fileSuffix = Path.GetExtension(file.FileName).ToLower(); // 文件后缀
|
|
|
|
|
|
var serverUrl = (await _cache.GetAllDictData()).FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "ocr_api_url").Value;
|
|
|
if (!serverUrl.EndsWith("/"))
|
|
|
{
|
|
|
serverUrl += "/";
|
|
|
}
|
|
|
|
|
|
var ms = new MemoryStream();
|
|
|
await file.CopyToAsync(ms);
|
|
|
_logger.LogInformation($"调用ocr处理文件{originalFilename}");
|
|
|
|
|
|
//Furion框架上传文件名称带有双引号,导致上传失败
|
|
|
//var strRtn = await $"{serverUrl}pdf/upload"
|
|
|
// .SetContentType("multipart/form-data")
|
|
|
// .SetContentEncoding(Encoding.UTF8)
|
|
|
// .SetBodyBytes(("file", ms.GetBuffer(), "test.pdf"))
|
|
|
// .PostAsStringAsync();
|
|
|
//var jobj = strRtn.ToJObject();
|
|
|
//if (jobj.GetIntValue("code") == 0)
|
|
|
//{
|
|
|
// var fn = jobj.GetStringValue("data");
|
|
|
// return fn;
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// throw Oops.Bah(jobj.GetStringValue("message"));
|
|
|
//}
|
|
|
|
|
|
//使用HttpClient方式上传文件
|
|
|
ms.Position = 0;
|
|
|
var formData = new MultipartFormDataContent();
|
|
|
formData.Add(new StreamContent(ms, (int)ms.Length), "file", originalFilename);
|
|
|
var _httpclient = new HttpClient();
|
|
|
var response = await _httpclient.PostAsync($"{serverUrl}pdf/upload", formData);
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
{
|
|
|
var strRtn = response.Content.ReadAsStringAsync().Result;
|
|
|
var jobj = strRtn.ToJObject();
|
|
|
if (jobj.GetIntValue("code") == 0)
|
|
|
{
|
|
|
var fn = jobj.GetStringValue("data");
|
|
|
return fn;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw Oops.Bah(jobj.GetStringValue("message"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
throw Oops.Bah("文件上传失败");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取图片
|
|
|
/// </summary>
|
|
|
/// <param name="fileName">文件名称</param>
|
|
|
/// <param name="scale">缩放比例,默认为1.5</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/BookingOrder/OcrGetImg")]
|
|
|
public async Task<IActionResult> OcrGetImg(string fileName, float scale = 1.5f)
|
|
|
{
|
|
|
var serverUrl = (await _cache.GetAllDictData()).FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "ocr_api_url").Value;
|
|
|
if (!serverUrl.EndsWith("/"))
|
|
|
{
|
|
|
serverUrl += "/";
|
|
|
}
|
|
|
|
|
|
var bs = await $"{serverUrl}pdf/getCanvasImage?fileName={fileName}&scale={scale}"
|
|
|
.GetAsByteArrayAsync();
|
|
|
var result = new FileContentResult(bs, "application/octet-stream") { FileDownloadName = "ocr.jpg" };
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取文字
|
|
|
/// </summary>
|
|
|
/// <param name="fileName">文件名称</param>
|
|
|
/// <param name="scale">缩放比例</param>
|
|
|
/// <param name="x">x坐标</param>
|
|
|
/// <param name="y">y坐标</param>
|
|
|
/// <param name="w">宽度</param>
|
|
|
/// <param name="h">高度</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/BookingOrder/OcrGetText")]
|
|
|
public async Task<string> OcrGetText(string fileName, float scale, int x, int y, int w, int h)
|
|
|
{
|
|
|
var serverUrl = (await _cache.GetAllDictData()).FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "ocr_api_url").Value;
|
|
|
if (!serverUrl.EndsWith("/"))
|
|
|
{
|
|
|
serverUrl += "/";
|
|
|
}
|
|
|
|
|
|
var str = await $"{serverUrl}pdf/getRegionText?fileName={fileName}&scale={scale}&x={x}&y={y}&w={w}&h={h}"
|
|
|
.PostAsStringAsync();
|
|
|
return str;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#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="isWeb"></param>
|
|
|
/// <returns></returns>
|
|
|
[HttpGet("/BookingOrder/GetYardData")]
|
|
|
public async Task<string> GetYardData(long bookingId, bool isWeb = false)
|
|
|
{
|
|
|
//订舱数据
|
|
|
var order = _rep.FirstOrDefault(x => x.Id == bookingId);
|
|
|
if (order == null)
|
|
|
{
|
|
|
throw Oops.Bah(BookingErrorCode.BOOK001);
|
|
|
}
|
|
|
|
|
|
var rtn = await YardDataHelper.GetYardData(order.TenantId.Value, order.TenantName, order.MBLNO, order.YARDID, isWeb);
|
|
|
if (!rtn.Key)
|
|
|
{
|
|
|
throw Oops.Bah(rtn.Value);
|
|
|
}
|
|
|
|
|
|
return rtn.Value;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <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
|
|
|
}
|
|
|
}
|