|
|
using Furion;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
using Furion.DynamicApiController;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.Localization;
|
|
|
using Furion.RemoteRequest;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.EDI;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Helper;
|
|
|
using Myshipping.Core.Service;
|
|
|
using MySqlX.XDevAPI.Common;
|
|
|
using NetTaste;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using Npoi.Mapper;
|
|
|
using NPOI.HPSF;
|
|
|
using NPOI.HSSF.UserModel;
|
|
|
using NPOI.OpenXmlFormats;
|
|
|
using NPOI.OpenXmlFormats.Wordprocessing;
|
|
|
using NPOI.POIFS.Crypt.Dsig;
|
|
|
using NPOI.SS.Formula.Atp;
|
|
|
using NPOI.SS.Formula.Eval;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using NPOI.SS.UserModel;
|
|
|
using NPOI.Util;
|
|
|
using NPOI.XSSF.Model;
|
|
|
using Org.BouncyCastle.Asn1.Tsp;
|
|
|
using Org.BouncyCastle.Asn1.X500;
|
|
|
using Org.BouncyCastle.Asn1.X9;
|
|
|
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
|
|
using SqlSugar;
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.DirectoryServices.ActiveDirectory;
|
|
|
using System.Dynamic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net;
|
|
|
using System.Net.Http;
|
|
|
using System.Reflection.Metadata.Ecma335;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Security.Policy;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Xml.Linq;
|
|
|
using static Aliyun.OSS.Model.CreateSelectObjectMetaInputFormatModel;
|
|
|
using static Aliyun.OSS.Model.ListPartsResult;
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 任务管理
|
|
|
/// </summary>
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManage", Order = 10)]
|
|
|
public class TaskManageService : ITaskManageService, IDynamicApiController, ITransient
|
|
|
{
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskSIFeedBackInfo> _taskSIFeedBackInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskSIFeedBackContaInfo> _taskSIFeedBackContaInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskBillFeeDetailInfo> _taskBillFeeDetailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskFileInfo> _taskFileInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskEmailInfo> _taskEmailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskVGMFeedBackInfo> _taskVGMFeedBackInfoRepository;
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
|
|
|
private readonly SqlSugarRepository<TaskStatManageInfo> _taskStatManageInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskOriginalDownloadHisInfo> _taskOriginalDownloadHisInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskChargesHisInfo> _taskChargesHisInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskLARAPaperInfo> _taskLARAPaperInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskPerBillBaseInfo> _taskPerBillBaseInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskStoreMsgInfo> _taskStoreMsgInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskChangeShipHisInfo> _taskChangeShipHisInfoRepository;
|
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
|
|
|
private readonly SqlSugarRepository<BookingCtn> _bookingOrderContaRepository;
|
|
|
private readonly SqlSugarRepository<BookingCtnDetail> _bookingOrderContaCargoRepository;
|
|
|
private readonly SqlSugarRepository<BookingStatus> _bookingStatusRepository;
|
|
|
private readonly SqlSugarRepository<BookingOrderContact> _bookingOrderContactRepository;
|
|
|
|
|
|
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccountRepository;
|
|
|
private readonly SqlSugarRepository<TaskTruckInfo> _taskTruckInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskTruckCtn> _taskTruckCtnRepository;
|
|
|
|
|
|
private readonly IDjyWebsiteAccountConfigService _webAccountConfig;
|
|
|
private readonly ISysCacheService _cache;
|
|
|
private readonly ILogger<BookingOrderService> _logger;
|
|
|
|
|
|
private readonly INamedServiceProvider<IBookingOrderService> _namedBookingOrderServiceProvider;
|
|
|
|
|
|
const string CONST_WEB_ACCOUNT_TYPE = "CmaWeb";
|
|
|
const string CONST_BOOK_ORIGINAL_DOWN_URL_CODE = "bookOriginalDownUrl";
|
|
|
|
|
|
const string CONST_WEB_LARA_ACCOUNT_TYPE = "LaraWeb";
|
|
|
const string CONST_LARA_DOWN_URL_CODE = "LaraPaperPostUrl";
|
|
|
|
|
|
const string CONST_MAPPING_MODULE = "YunJia";
|
|
|
|
|
|
//LARA纸计算常量
|
|
|
const int LARA_PARER_DRAFT_VAR = 3;
|
|
|
|
|
|
public TaskManageService(SqlSugarRepository<TaskBaseInfo> taskBaseInfoRepository,
|
|
|
SqlSugarRepository<TaskSIFeedBackInfo> taskSIFeedBackInfoRepository,
|
|
|
SqlSugarRepository<TaskSIFeedBackContaInfo> taskSIFeedBackContaInfoRepository,
|
|
|
SqlSugarRepository<TaskBillFeeDetailInfo> taskBillFeeDetailInfoRepository,
|
|
|
SqlSugarRepository<TaskFileInfo> taskFileInfoRepository,
|
|
|
SqlSugarRepository<TaskEmailInfo> taskEmailInfoRepository,
|
|
|
SqlSugarRepository<TaskVGMFeedBackInfo> taskVGMFeedBackInfoRepository,
|
|
|
SqlSugarRepository<SysUser> sysUserRepository,
|
|
|
SqlSugarRepository<TaskStatManageInfo> taskStatManageInfoRepository,
|
|
|
SqlSugarRepository<TaskOriginalDownloadHisInfo> taskOriginalDownloadHisInfoRepository,
|
|
|
SqlSugarRepository<TaskChargesHisInfo> taskChargesHisInfoRepository,
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository,
|
|
|
SqlSugarRepository<TaskLARAPaperInfo> taskLARAPaperInfoRepository,
|
|
|
SqlSugarRepository<BookingCtn> bookingOrderContaRepository,
|
|
|
SqlSugarRepository<BookingCtnDetail> bookingOrderContaCargoRepository,
|
|
|
SqlSugarRepository<BookingStatus> bookingStatusRepository,
|
|
|
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccountRepository,
|
|
|
SqlSugarRepository<TaskPerBillBaseInfo> taskPerBillBaseInfoRepository,
|
|
|
SqlSugarRepository<TaskStoreMsgInfo> taskStoreMsgInfoRepository,
|
|
|
SqlSugarRepository<TaskChangeShipHisInfo> taskChangeShipHisInfoRepository,
|
|
|
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
|
|
|
SqlSugarRepository<TaskTruckInfo> taskTruckInfoRepository,
|
|
|
SqlSugarRepository<TaskTruckCtn> taskTruckCtnRepository,
|
|
|
INamedServiceProvider<IBookingOrderService> namedBookingOrderServiceProvider,
|
|
|
IDjyWebsiteAccountConfigService webAccountConfig,
|
|
|
ISysCacheService cache,
|
|
|
ILogger<BookingOrderService> logger)
|
|
|
{
|
|
|
_taskBaseInfoRepository = taskBaseInfoRepository;
|
|
|
_taskSIFeedBackInfoRepository = taskSIFeedBackInfoRepository;
|
|
|
_taskSIFeedBackContaInfoRepository = taskSIFeedBackContaInfoRepository;
|
|
|
_taskBillFeeDetailInfoRepository = taskBillFeeDetailInfoRepository;
|
|
|
_taskFileInfoRepository = taskFileInfoRepository;
|
|
|
_taskEmailInfoRepository = taskEmailInfoRepository;
|
|
|
_taskVGMFeedBackInfoRepository = taskVGMFeedBackInfoRepository;
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
_taskStatManageInfoRepository = taskStatManageInfoRepository;
|
|
|
_taskOriginalDownloadHisInfoRepository = taskOriginalDownloadHisInfoRepository;
|
|
|
_taskChargesHisInfoRepository = taskChargesHisInfoRepository;
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
_taskLARAPaperInfoRepository = taskLARAPaperInfoRepository;
|
|
|
_bookingOrderContaRepository = bookingOrderContaRepository;
|
|
|
_bookingOrderContaCargoRepository = bookingOrderContaCargoRepository;
|
|
|
_bookingStatusRepository = bookingStatusRepository;
|
|
|
_djyUserMailAccountRepository = djyUserMailAccountRepository;
|
|
|
_taskPerBillBaseInfoRepository = taskPerBillBaseInfoRepository;
|
|
|
_taskStoreMsgInfoRepository = taskStoreMsgInfoRepository;
|
|
|
_taskChangeShipHisInfoRepository = taskChangeShipHisInfoRepository;
|
|
|
_bookingOrderContactRepository = bookingOrderContactRepository;
|
|
|
_taskTruckInfoRepository = taskTruckInfoRepository;
|
|
|
_taskTruckCtnRepository = taskTruckCtnRepository;
|
|
|
|
|
|
_namedBookingOrderServiceProvider = namedBookingOrderServiceProvider;
|
|
|
|
|
|
_webAccountConfig = webAccountConfig;
|
|
|
_cache = cache;
|
|
|
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
#region 创建任务
|
|
|
/// <summary>
|
|
|
/// 创建任务
|
|
|
/// </summary>
|
|
|
/// <param name="info">任务详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[AllowAnonymous, HttpPost("/TaskManage/CreateTaskJob")]
|
|
|
public async Task<TaskManageOrderResultDto> CreateTaskJob(TaskManageOrderMessageInfo info)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
result = await InitTaskJob(info);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"请求任务异常,{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 新增任务
|
|
|
/// <summary>
|
|
|
/// 新增任务
|
|
|
/// </summary>
|
|
|
/// <param name="info">任务详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[SqlSugarUnitOfWork]
|
|
|
private async Task<TaskManageOrderResultDto> InitTaskJob(TaskManageOrderMessageInfo info)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().OrderByDescending(a=>a.CreatedTime)
|
|
|
.First(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}");
|
|
|
|
|
|
/*
|
|
|
只要任务最后一次处理任务的状态是已取消、已完成,就可以重入新的任务
|
|
|
*/
|
|
|
if(taskInfo != null && taskInfo.STATUS != TaskStatusEnum.Cancel.ToString() && taskInfo.STATUS != TaskStatusEnum.Complete.ToString())
|
|
|
throw Oops.Oh($"状态已存在,不能重复创建任务");
|
|
|
|
|
|
taskInfo = new TaskBaseInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
STATUS = TaskStatusEnum.Create.ToString(),
|
|
|
IsDeleted = false,
|
|
|
IS_EXCEPT = 0,
|
|
|
IS_COMPLETE = 0,
|
|
|
MBL_NO = info.Main.MBlNo,
|
|
|
TASK_BASE_TYPE = info.Main.TaskType.ToString(),
|
|
|
CARRIER_ID = info.Main.CarrierId?.Trim(),
|
|
|
IS_PUBLIC = string.IsNullOrWhiteSpace(info.Main.TaskUserId) ? 1 : 0,
|
|
|
BOOK_ORDER_NO = info.Main.BookingOrderNo,
|
|
|
OUT_BUSI_NO = $"{info.Head.SenderId}_{info.Head.GID}",
|
|
|
TASK_TITLE = info.Main.TaskTitle,
|
|
|
TASK_DESP = info.Main.TaskDesp,
|
|
|
TASK_SOURCE = info.Main.TaskSource.ToString(),
|
|
|
TASK_TYPE = info.Main.TaskType.ToString(),
|
|
|
};
|
|
|
|
|
|
UserTendDto userTendInfo = GetUserTendInfo(info.Main.RecvUserId);
|
|
|
|
|
|
taskInfo.CreatedUserId = userTendInfo.userId;
|
|
|
taskInfo.CreatedUserName = userTendInfo.userName;
|
|
|
taskInfo.TenantId = userTendInfo.tendId;
|
|
|
taskInfo.TenantName = userTendInfo.tenantName;
|
|
|
|
|
|
taskInfo.CreatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.CARRIER_ID)
|
|
|
&& taskInfo.CARRIER_ID == "MSC")
|
|
|
{
|
|
|
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
|
|
|
taskInfo.TASK_TYPE = TaskBusiTypeEnum.MSC_BC.ToString();
|
|
|
|
|
|
if (taskInfo.IS_EXCEPT == 1)
|
|
|
taskInfo.TASK_TYPE = TaskBusiTypeEnum.MSC_EXCEPT.ToString();
|
|
|
}
|
|
|
|
|
|
//新增
|
|
|
_taskBaseInfoRepository.Insert(taskInfo);
|
|
|
|
|
|
#region 附件
|
|
|
//附件
|
|
|
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
|
|
|
{
|
|
|
info.Main.FileList.ForEach(async file =>
|
|
|
{
|
|
|
var fileInfo = new TaskFileInfo();
|
|
|
|
|
|
fileInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
fileInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
fileInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
fileInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
fileInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
fileInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
fileInfo.TenantId = taskInfo.TenantId;
|
|
|
fileInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
fileInfo.FILE_PATH = file.FilePath;
|
|
|
fileInfo.FILE_NAME = file.FileName;
|
|
|
fileInfo.FILE_TYPE = file.FileType;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(fileInfo.FILE_NAME))
|
|
|
{
|
|
|
var fileModel = new FileInfo(file.FilePath);
|
|
|
|
|
|
fileInfo.FILE_NAME = fileModel.Name;
|
|
|
fileInfo.FILE_TYPE = fileModel.Extension?.Replace(".", "");
|
|
|
}
|
|
|
|
|
|
await _taskFileInfoRepository.InsertAsync(fileInfo);
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 邮件
|
|
|
//邮件
|
|
|
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
|
|
|
{
|
|
|
info.Main.EmailList.ForEach(async email =>
|
|
|
{
|
|
|
var emailInfo = new TaskEmailInfo();
|
|
|
|
|
|
emailInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
emailInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
emailInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
emailInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
emailInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
emailInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
emailInfo.TenantId = taskInfo.TenantId;
|
|
|
emailInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
emailInfo.MAIL_PATH = email.MailPath;
|
|
|
|
|
|
await _taskEmailInfoRepository.InsertAsync(emailInfo);
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region SI反馈入库
|
|
|
//SI反馈入库
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.SI_FEEDBACK)
|
|
|
{
|
|
|
if (info.Main.SIFeedBack == null)
|
|
|
throw Oops.Oh($"任务类型={info.Main.TaskType.ToString()} SIFeedBack信息必传");
|
|
|
|
|
|
TaskSIFeedBackInfo taskSIFeedBackInfo = info.Main.SIFeedBack.Adapt<TaskSIFeedBackInfo>();
|
|
|
|
|
|
taskSIFeedBackInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
taskSIFeedBackInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
taskSIFeedBackInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
taskSIFeedBackInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
taskSIFeedBackInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
taskSIFeedBackInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
taskSIFeedBackInfo.TenantId = taskInfo.TenantId;
|
|
|
taskSIFeedBackInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskSIFeedBackInfoRepository.InsertAsync(taskSIFeedBackInfo);
|
|
|
|
|
|
//SI反馈箱信息入库
|
|
|
if (info.Main.SIFeedBack.ContaList != null && info.Main.SIFeedBack.ContaList.Count > 0)
|
|
|
{
|
|
|
info.Main.SIFeedBack.ContaList.ForEach(async ctn =>
|
|
|
{
|
|
|
var contaInfo = ctn.Adapt<TaskSIFeedBackContaInfo>();
|
|
|
|
|
|
contaInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
contaInfo.P_PKID = taskSIFeedBackInfo.PK_ID;
|
|
|
|
|
|
contaInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
contaInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
contaInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
contaInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
contaInfo.TenantId = taskInfo.TenantId;
|
|
|
contaInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskSIFeedBackContaInfoRepository.InsertAsync(contaInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 费用明细
|
|
|
//费用明细
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.INVOICE_BILL_MAIL)
|
|
|
{
|
|
|
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
|
|
|
{
|
|
|
info.Main.FeeList.ForEach(async fee =>
|
|
|
{
|
|
|
var feeInfo = fee.Adapt<TaskBillFeeDetailInfo>();
|
|
|
|
|
|
feeInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
feeInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
feeInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
feeInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
feeInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
feeInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
feeInfo.TenantId = taskInfo.TenantId;
|
|
|
feeInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskBillFeeDetailInfoRepository.InsertAsync(feeInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 单票账单
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.PER_BILL)
|
|
|
{
|
|
|
TaskPerBillBaseInfo taskPerBillBaseInfo = info.Main.PerBillInfo.Adapt<TaskPerBillBaseInfo>();
|
|
|
//写入
|
|
|
await _taskPerBillBaseInfoRepository.InsertAsync(taskPerBillBaseInfo);
|
|
|
|
|
|
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
|
|
|
{
|
|
|
info.Main.FeeList.ForEach(async fee =>
|
|
|
{
|
|
|
var feeInfo = fee.Adapt<TaskBillFeeDetailInfo>();
|
|
|
|
|
|
feeInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
feeInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
feeInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
feeInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
feeInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
feeInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
feeInfo.TenantId = taskInfo.TenantId;
|
|
|
feeInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskBillFeeDetailInfoRepository.InsertAsync(feeInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region VGM反馈入库
|
|
|
//VGM反馈入库
|
|
|
if (info.Main.VGMFeedBackList != null && info.Main.VGMFeedBackList.Count > 0)
|
|
|
{
|
|
|
info.Main.VGMFeedBackList.ForEach(async vgm =>
|
|
|
{
|
|
|
var vgmInfo = vgm.Adapt<TaskVGMFeedBackInfo>();
|
|
|
|
|
|
vgmInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
vgmInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
vgmInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
vgmInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
vgmInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
vgmInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
vgmInfo.TenantId = taskInfo.TenantId;
|
|
|
vgmInfo.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskVGMFeedBackInfoRepository.InsertAsync(vgmInfo);
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 派车任务
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.TRUCK_DISPATCH)
|
|
|
{
|
|
|
//派车任务
|
|
|
if (info.Main.TruckInfo == null)
|
|
|
{
|
|
|
throw Oops.Oh($"派车任务主信息不能为空,请查看请求报文");
|
|
|
}
|
|
|
|
|
|
var truckInfo = info.Main.TruckInfo.Adapt<TaskTruckInfo>();
|
|
|
|
|
|
truckInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
truckInfo.TASK_ID = taskInfo.PK_ID;
|
|
|
truckInfo.BookingTruckId = info.Main.TruckInfo.Id;
|
|
|
truckInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
truckInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
truckInfo.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
truckInfo.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
truckInfo.TenantId = taskInfo.TenantId;
|
|
|
truckInfo.TenantName = taskInfo.TenantName;
|
|
|
truckInfo.Status = BookingTruckStatus.TEMP.ToString();
|
|
|
|
|
|
//异步写入
|
|
|
await _taskTruckInfoRepository.InsertAsync(truckInfo);
|
|
|
|
|
|
if(info.Main.TruckInfo.ContaList != null && info.Main.TruckInfo.ContaList.Count > 0)
|
|
|
{
|
|
|
var contaList = info.Main.TruckInfo.ContaList.Adapt<List<TaskTruckCtn>>();
|
|
|
|
|
|
contaList.ForEach(async x =>
|
|
|
{
|
|
|
x.P_ID = truckInfo.PK_ID;
|
|
|
x.PK_ID = IDGen.NextID().ToString();
|
|
|
|
|
|
x.CreatedTime = taskInfo.CreatedTime;
|
|
|
x.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
x.CreatedUserId = taskInfo.CreatedUserId;
|
|
|
x.CreatedUserName = taskInfo.CreatedUserName;
|
|
|
x.TenantId = taskInfo.TenantId;
|
|
|
x.TenantName = taskInfo.TenantName;
|
|
|
|
|
|
await _taskTruckCtnRepository.InsertAsync(x);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
if (info.Main.SerialMsgInfo != null)
|
|
|
{
|
|
|
var storeInfo = new TaskStoreMsgInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_PKID = taskInfo.PK_ID,
|
|
|
MSG_JSON = info.Main.SerialMsgInfo.SerialMsg,
|
|
|
MSG_TYPE = info.Main.SerialMsgInfo.SerialType,
|
|
|
CreatedTime = taskInfo.CreatedTime,
|
|
|
UpdatedTime = taskInfo.CreatedTime,
|
|
|
|
|
|
CreatedUserId = taskInfo.CreatedUserId,
|
|
|
CreatedUserName = taskInfo.CreatedUserName,
|
|
|
TenantId = taskInfo.TenantId,
|
|
|
TenantName = taskInfo.TenantName,
|
|
|
};
|
|
|
|
|
|
await _taskStoreMsgInfoRepository.InsertAsync(storeInfo);
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "新增任务成功";
|
|
|
|
|
|
var md = _taskBaseInfoRepository.AsQueryable().First(a => a.PK_ID == taskInfo.PK_ID);
|
|
|
//回写任务号
|
|
|
result.ext = md?.TASK_NO;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Oh($"{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询订舱表查询用户和租户信息
|
|
|
/// </summary>
|
|
|
/// <param name="userId"></param>
|
|
|
/// <returns></returns>
|
|
|
private UserTendDto GetUserTendInfo(string userId)
|
|
|
{
|
|
|
UserTendDto userTendDto = null;
|
|
|
|
|
|
//这里因为接口是不做授权验证的,所以这里直接写的动态sql提取了用户和租户信息
|
|
|
var userTendInfo = _sysUserRepository.EntityContext.Queryable<dynamic>("user").AS("sys_user")
|
|
|
.AddJoinInfo("sys_tenant", "ten", "user.TenantId=ten.Id")
|
|
|
.Where("user.Id=@id", new { id = long.Parse(userId) })
|
|
|
.Select("user.Id as UserId,user.Name as UserName,ten.Id as TendId,ten.Name as TendName").First();
|
|
|
|
|
|
if (userTendInfo == null || userTendInfo.TendId == null)
|
|
|
throw Oops.Oh("当前用户详情获取失败,请确认{0}赋值是否准确", nameof(TaskManageOrderMessageInfo.Main.TaskUserId));
|
|
|
|
|
|
userTendDto = new UserTendDto
|
|
|
{
|
|
|
userId = long.Parse(userTendInfo.UserId.ToString()),
|
|
|
userName = userTendInfo.UserName.ToString(),
|
|
|
tendId = long.Parse(userTendInfo.TendId.ToString()),
|
|
|
tenantName = userTendInfo.TendName.ToString()
|
|
|
};
|
|
|
|
|
|
return userTendDto;
|
|
|
}
|
|
|
|
|
|
#region 获取查询参数
|
|
|
/// <summary>
|
|
|
/// 获取查询参数
|
|
|
/// </summary>
|
|
|
/// <param name="ParaType">参数类型 STATUS-任务状态;TASK_TYPE-任务类型;SOURCE-任务来源 CATEGORY-分类</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
/// <example>TASK_TYPE</example>
|
|
|
[HttpGet("/TaskManage/GetParaInfo")]
|
|
|
public async Task<TaskManageOrderResultDto> GetParaInfo([QueryString] string ParaType)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
try
|
|
|
{
|
|
|
Dictionary<string, string> dict = new Dictionary<string, string>();
|
|
|
|
|
|
if (ParaType == "STATUS")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskStatusEnum));
|
|
|
}
|
|
|
else if (ParaType == "TASK_TYPE")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskBusiTypeEnum));
|
|
|
}
|
|
|
else if (ParaType == "SOURCE")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskSourceEnum));
|
|
|
}
|
|
|
else if (ParaType == "CATEGORY")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskStatLevelEnum));
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.rows = dict.Select(t => new { Code = t.Key, Name = t.Value }).ToList();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取登陆人相关的任务统计信息
|
|
|
/// <summary>
|
|
|
/// 获取登陆人相关的任务统计信息
|
|
|
/// </summary>
|
|
|
/// <param name="isReCalc">是否强制计算</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManage/GetCurrentTotalStat")]
|
|
|
public async Task<TaskUserStatResultInfo> GetCurrentTotalStat([FromQuery] bool isReCalc = false)
|
|
|
{
|
|
|
TaskUserStatResultInfo resultInfo = new TaskUserStatResultInfo
|
|
|
{
|
|
|
LevelTop = new List<TaskUserStatItem>(),
|
|
|
LevelNext = new List<TaskUserStatItemNext>(),
|
|
|
LevelTree = new List<TaskUserStatItemTree>()
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
1、首先判断当前登陆人是否有统计记录,如果没有触发统计生成统计记录。
|
|
|
2、如果isReCalc=true,表示强制重新统计数据,并重新更新统计数据。
|
|
|
3、按照统计类型(个人/公共)、任务状态、是否异常分组汇总,并写入统计表。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var userTendInfo = await _sysUserRepository.AsQueryable()
|
|
|
.LeftJoin<SysTenant>((usr, ten) => usr.TenantId == ten.Id)
|
|
|
.Where(usr => usr.Id == UserManager.UserId)
|
|
|
.Select((usr, ten) => new { User = usr, Tend = ten }).FirstAsync();
|
|
|
|
|
|
if (userTendInfo == null)
|
|
|
throw Oops.Oh($"当前用户关联租户信息获取失败");
|
|
|
|
|
|
//var statList = _taskStatManageInfoRepository.AsQueryable().Where(t => (t.USER_ID == userTendInfo.User.Id
|
|
|
//&& t.STAT_TYPE == TaskStatLevelEnum.PERSON.ToString()) || (t.COMP_ID == userTendInfo.Tend.Id && t.STAT_TYPE == TaskStatLevelEnum.PUBLIC.ToString())).ToList();
|
|
|
|
|
|
|
|
|
//任务列表分组统计
|
|
|
var groupList = _taskBaseInfoRepository.AsQueryable()
|
|
|
.Where(t => (t.CreatedUserId == UserManager.UserId && t.IS_PUBLIC == 0) || (t.TenantId == userTendInfo.Tend.Id && t.IS_PUBLIC == 1))
|
|
|
.GroupBy(p => new { p.TASK_TYPE, p.STATUS, p.IS_EXCEPT, p.IS_PUBLIC })
|
|
|
.Select(p => new
|
|
|
{
|
|
|
Total = SqlFunc.AggregateCount(p.PK_ID),
|
|
|
TaskType = p.TASK_TYPE,
|
|
|
Status = p.STATUS,
|
|
|
IsExcept = p.IS_EXCEPT,
|
|
|
IsPublic = p.IS_PUBLIC
|
|
|
}).ToList();
|
|
|
|
|
|
var exceptList = groupList
|
|
|
.Where(t => t.IsExcept == 1).ToList();
|
|
|
|
|
|
var personList = groupList
|
|
|
.Where(t => t.IsExcept == 0 && t.IsPublic == 0).ToList();
|
|
|
|
|
|
var publicList = groupList
|
|
|
.Where(t => t.IsExcept == 0 && t.IsPublic == 1).ToList();
|
|
|
|
|
|
#region 异常
|
|
|
if (exceptList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
Name = TaskStatLevelEnum.EXCPTION.GetDescription(),
|
|
|
Total = exceptList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.EXCPTION,
|
|
|
ActionKey = TaskStatLevelEnum.EXCPTION.ToString()
|
|
|
});
|
|
|
|
|
|
exceptList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
exceptList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 个人
|
|
|
if (personList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
Name = TaskStatLevelEnum.PERSON.GetDescription(),
|
|
|
Total = personList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.PERSON,
|
|
|
ActionKey = TaskStatLevelEnum.PERSON.ToString()
|
|
|
});
|
|
|
|
|
|
personList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
personList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 公共
|
|
|
if (publicList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
Name = TaskStatLevelEnum.PUBLIC.GetDescription(),
|
|
|
Total = publicList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.PUBLIC,
|
|
|
ActionKey = TaskStatLevelEnum.PUBLIC.ToString()
|
|
|
});
|
|
|
|
|
|
publicList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
publicList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取登录人相关的任务统计信息异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return resultInfo;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 任务台账查询
|
|
|
/// <summary>
|
|
|
/// 任务台账查询
|
|
|
/// </summary>
|
|
|
/// <param name="QuerySearch">任务台账查询请求</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/GetPage")]
|
|
|
public async Task<SqlSugarPagedList<TaskBaseInfoDto>> GetPageAsync(QueryTaskManageDto QuerySearch)
|
|
|
{
|
|
|
List<string> mblList = new List<string>();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.MBlNo))
|
|
|
{
|
|
|
if (Regex.IsMatch(QuerySearch.MBlNo, "(\\t|\\n\\r|\\n)"))
|
|
|
{
|
|
|
mblList = Regex.Replace(QuerySearch.MBlNo, "(\\t |\\n\\r |\\n)", "#").Split(new char[] { '#' }).Select(t => t?.Trim()).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
mblList.Add(QuerySearch.MBlNo.Trim());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
DateTime etdBegin = DateTime.MinValue;
|
|
|
DateTime etdEnd = DateTime.MinValue;
|
|
|
|
|
|
DateTime taskDateBegin = DateTime.MinValue;
|
|
|
DateTime taskDateEnd = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDBegin, out etdBegin))
|
|
|
throw Oops.Oh($"开船起始日期格式错误,{QuerySearch.ETDBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDEnd, out etdEnd))
|
|
|
throw Oops.Oh($"开船结束日期格式错误,{QuerySearch.ETDEnd}");
|
|
|
|
|
|
etdEnd = etdEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.TaskDateBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.TaskDateBegin, out taskDateBegin))
|
|
|
throw Oops.Oh($"任务起始日期格式错误,{QuerySearch.TaskDateBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.TaskDateEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.TaskDateEnd, out taskDateEnd))
|
|
|
throw Oops.Oh($"任务结束日期格式错误,{QuerySearch.TaskDateEnd}");
|
|
|
|
|
|
etdEnd = etdEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.SortField))
|
|
|
entityOrderCol = MapsterExtHelper.GetAdaptProperty<TaskBaseInfoDto, TaskBaseInfo>(QuerySearch.SortField);
|
|
|
|
|
|
var entities = await _taskBaseInfoRepository.AsQueryable()
|
|
|
.Where(t=> t.CreatedUserId == UserManager.UserId)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.MBlNo), t => mblList.Any(p => p.Contains(t.MBL_NO, StringComparison.OrdinalIgnoreCase)))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskRecvName), t => t.CreatedUserName.Contains(QuerySearch.TaskRecvName.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(etdBegin != DateTime.MinValue, t => t.ETD.HasValue && t.ETD.Value >= etdBegin)
|
|
|
.WhereIF(etdEnd != DateTime.MinValue, t => t.ETD.HasValue && t.ETD.Value < etdEnd)
|
|
|
.WhereIF(taskDateBegin != DateTime.MinValue, t => t.CreatedTime >= taskDateBegin)
|
|
|
.WhereIF(taskDateEnd != DateTime.MinValue, t => t.CreatedTime < taskDateEnd)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskType), t => t.TASK_TYPE.Equals(QuerySearch.TaskType, StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskSource), t => t.TASK_SOURCE.Equals(QuerySearch.TaskSource, StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.EXCPTION.ToString(), t => t.IS_EXCEPT == 1)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PUBLIC.ToString(), t => t.IS_PUBLIC == 1)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PERSON.ToString(), t => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Status), t => t.STATUS.Equals(QuerySearch.Status, StringComparison.OrdinalIgnoreCase))
|
|
|
.OrderBy(entityOrderCol + (QuerySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize);
|
|
|
|
|
|
|
|
|
return entities.Adapt<SqlSugarPagedList<TaskBaseInfoDto>>();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载正本提单(可批量)
|
|
|
/// <summary>
|
|
|
/// 下载正本提单(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/DownloadOriginalTask")]
|
|
|
public async Task<TaskManageOrderResultDto> DownloadOriginalTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 下载正本提单开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置
|
|
|
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_WEB_ACCOUNT_TYPE, UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
|
|
|
|
|
|
if (userWebAccountConfig == null)
|
|
|
throw Oops.Bah($"个人/公司网站【{CONST_WEB_ACCOUNT_TYPE}】获取失败,请维护个人/公司网站账户信息");
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerDownloadOriginalTask(batchNo, tsk, userWebAccountConfig);
|
|
|
});
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("下载正本提单异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 单票正本下载
|
|
|
/// <summary>
|
|
|
/// 单票正本下载
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="taskBaseInfo">任务详情</param>
|
|
|
/// <param name="webAccountConfig">网站账户配置</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerDownloadOriginalTask(string batchNo, TaskBaseInfo taskBaseInfo,
|
|
|
DjyWebsiteAccountConfig webAccountConfig)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、TaskOriginalDownloadHisInfo表中处理任务是succ/temp不允许重复下载。failure/timeout的记录可以再次发起下载。
|
|
|
2、从任务表提取RESULT_NOTE回执信息,里面包含了JSON数据 {"pageUrl":"http://www.cnc-ebusiness.com/ebusiness/bl/detail/AASM104300"}
|
|
|
3、异步请求正本下载的链接,有超时时间。
|
|
|
4、下载完成后写入记录
|
|
|
*/
|
|
|
|
|
|
//正本下载URL
|
|
|
string originalUrl = string.Empty;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var hisList = _taskOriginalDownloadHisInfoRepository
|
|
|
.Where(t => t.TASK_ID == taskBaseInfo.PK_ID).ToList();
|
|
|
|
|
|
if (hisList.Any(t => new string[] { "succ", "temp" }.Contains(t.STATUS)))
|
|
|
throw Oops.Bah("下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskBaseInfo.RESULT_NOTE))
|
|
|
throw Oops.Bah("下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
var resultObj = JSON.Deserialize<dynamic>(taskBaseInfo.RESULT_NOTE);
|
|
|
|
|
|
originalUrl = resultObj.pageUrl.ToString();
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(originalUrl))
|
|
|
throw Oops.Bah("解析下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
DateTime startDate = DateTime.Now;
|
|
|
|
|
|
var downloadUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.First(t => t.Code.Equals(CONST_BOOK_ORIGINAL_DOWN_URL_CODE, StringComparison.OrdinalIgnoreCase))?.Value;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(downloadUrl))
|
|
|
throw Oops.Bah($"正本下载URL不存在,请确认字典是否配置 code={CONST_BOOK_ORIGINAL_DOWN_URL_CODE}");
|
|
|
|
|
|
TaskOriginalDownloadHisInfo taskOriginalDownloadHisInfo = new TaskOriginalDownloadHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
REQUEST_URL = originalUrl,
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
STATUS = "temp",
|
|
|
IS_TIMEOUT = 0,
|
|
|
START_DATE = startDate,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME
|
|
|
};
|
|
|
|
|
|
//写入记录
|
|
|
_taskOriginalDownloadHisInfoRepository.Insert(taskOriginalDownloadHisInfo);
|
|
|
|
|
|
//请求远程链接
|
|
|
Dictionary<string, string> formDict = new Dictionary<string, string> {
|
|
|
{"bno", taskBaseInfo.MBL_NO },
|
|
|
{"page_url", downloadUrl },
|
|
|
{"web_user", webAccountConfig.Account },
|
|
|
{"web_pwd", webAccountConfig.Password },
|
|
|
{"web_pwd", "myshipping_task" },
|
|
|
{"web_pwd", "" }
|
|
|
};
|
|
|
|
|
|
//请求下载正本
|
|
|
var postResult = await InnerRemoteDownOriginal(batchNo, downloadUrl, formDict);
|
|
|
|
|
|
//重新获取下载历史
|
|
|
var downloadHisInfo = _taskOriginalDownloadHisInfoRepository.AsQueryable()
|
|
|
.First(t => t.PK_ID == taskOriginalDownloadHisInfo.PK_ID);
|
|
|
|
|
|
//更新任务状态
|
|
|
var taskModel = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskBaseInfo.PK_ID);
|
|
|
|
|
|
downloadHisInfo.END_DATE = (DateTime)postResult.ext;
|
|
|
downloadHisInfo.RESULT_NOTE = postResult.msg;
|
|
|
|
|
|
bool isDownSucc = false;
|
|
|
|
|
|
//下载返回成功后,更新记录并生成扣费记录
|
|
|
if (postResult.succ)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "succ";
|
|
|
downloadHisInfo.RESULT_URL = postResult.msg;
|
|
|
|
|
|
taskModel.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskModel.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
taskModel.COMPLETE_DATE = DateTime.Now;
|
|
|
taskModel.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskModel.IS_COMPLETE = 1;
|
|
|
|
|
|
isDownSucc = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (postResult.isTimeout)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "timeout";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "failure";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//更新下载历史
|
|
|
await _taskOriginalDownloadHisInfoRepository.AsUpdateable(downloadHisInfo).IgnoreColumns(it => new
|
|
|
{
|
|
|
it.TenantId,
|
|
|
it.CreatedUserId,
|
|
|
it.CreatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
//异步扣费,这里不管是否失败都生成扣费记录,只在状态上做标识。
|
|
|
var chargeResult = await InnerChargeFee(taskBaseInfo, isDownSucc);
|
|
|
|
|
|
_taskBaseInfoRepository.AsUpdateable(taskModel).UpdateColumns(it => new
|
|
|
{
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME
|
|
|
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 远程请求正本下载
|
|
|
/// <summary>
|
|
|
/// 远程请求正本下载
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <param name="dic">请求参数</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerRemoteDownOriginal(string batchNo, string url, Dictionary<string, string> dic)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} 请求报文开始", batchNo);
|
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
.SetBody(dic, "application/x-www-form-urlencoded")
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
.PostAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(res));
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
var downResult = JSON.Deserialize<dynamic>(userResult);
|
|
|
|
|
|
//返回详情
|
|
|
result.msg = downResult.message.ToString();
|
|
|
|
|
|
//返回代码
|
|
|
if (downResult.status.ToString() == "1")
|
|
|
{
|
|
|
result.succ = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
result.ext = eDate;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
//如果有异常直接抛出错误
|
|
|
throw Oops.Bah(ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 扣费
|
|
|
/// <summary>
|
|
|
/// 扣费
|
|
|
/// </summary>
|
|
|
/// <param name="taskBaseInfo">任务信息</param>
|
|
|
/// <param name="isCharge">是否执行扣费 true-执行扣费 false-不执行扣费(主要是符合扣费条件但是由于超时没有得到准确回执)</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerChargeFee(TaskBaseInfo taskBaseInfo, bool isCharge = true)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = false };
|
|
|
try
|
|
|
{
|
|
|
decimal balance = 0;
|
|
|
decimal price = 0;
|
|
|
decimal total = 0;
|
|
|
|
|
|
TaskChargesHisInfo model = new TaskChargesHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
BEFORE_BALANCE = balance,
|
|
|
PRICE = price,
|
|
|
BUSI_TYPE = "21",
|
|
|
BUSI_TYPE_NAME = String.Empty,
|
|
|
SEND_TYPE = "1001",
|
|
|
SEND_TYPE_NAME = String.Empty,
|
|
|
REMARK = "正本下载",
|
|
|
QTY = 1,
|
|
|
TOTAL_AMOUNT = total,
|
|
|
};
|
|
|
|
|
|
if (!isCharge)
|
|
|
{
|
|
|
model.STATUS = TaskChargeStatusEnum.UNKNOW_RESULT.ToString();
|
|
|
model.STATUS_NAME = TaskChargeStatusEnum.UNKNOW_RESULT.GetDescription();
|
|
|
}
|
|
|
|
|
|
//写入记录
|
|
|
await _taskChargesHisInfoRepository.InsertAsync(model);
|
|
|
|
|
|
result.succ = false;
|
|
|
result.msg = "扣费失败";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 完成任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 完成任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/CompleteTask")]
|
|
|
public async Task<TaskManageOrderResultDto> CompleteTask([FromBody] string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 完成任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.COMPLETE_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
private async Task<TaskManageOrderResultDto> InnerManualTask(string batchNo, TaskBaseInfo taskBaseInfo, TaskOperTypeEnum taskOperTypeEnum)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var model = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskBaseInfo.PK_ID);
|
|
|
|
|
|
if (taskOperTypeEnum == TaskOperTypeEnum.COMPLETE_TASK)
|
|
|
{
|
|
|
|
|
|
if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.CANCELLATION.ToString())
|
|
|
{
|
|
|
//收到订舱已被取消邮件后生成的任务,如果点击完成,(订舱状态变为【退舱】,注意这里还需要确认)
|
|
|
}
|
|
|
|
|
|
model.COMPLETE_DATE = DateTime.Now;
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
model.IS_COMPLETE = 1;
|
|
|
model.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
model.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
|
|
|
_taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new
|
|
|
{
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.IS_COMPLETE,
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
else if (taskOperTypeEnum == TaskOperTypeEnum.CANCEL_TASK)
|
|
|
{
|
|
|
if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.CHANGE_SHIP.ToString())
|
|
|
{
|
|
|
model.STATUS = TaskStatusEnum.Cancel.ToString();
|
|
|
model.STATUS_NAME = TaskStatusEnum.Cancel.GetDescription();
|
|
|
|
|
|
_taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new
|
|
|
{
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.IS_COMPLETE,
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
else if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())
|
|
|
{
|
|
|
/*
|
|
|
1.如果原换船通知已经接受,需要把原船名航次恢复并通知客户取消换船。
|
|
|
2.如果原换船通知未作处理,点击接受或者结束任务时提示:本票货存在未处理换船通知,请先结束原换船任务然后结束本任务。
|
|
|
3.如果原换船任务为结束任务,在取消换船任务点接受时,提示未做换船,请点击结束任务。
|
|
|
*/
|
|
|
|
|
|
//查询同票主单的是否有未处理的换船通知
|
|
|
//_taskBaseInfoRepository.AsQueryable().Where(t=>t.MBL_NO.Equals(taskBaseInfo.MBL_NO) && )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"异常,{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
#region 取消任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 取消任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/CancelTask")]
|
|
|
public async Task<TaskManageOrderResultDto> CancelTask([FromBody] string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 取消任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.CANCEL_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 挂起任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 挂起任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/PendingTask")]
|
|
|
public async Task<TaskManageOrderResultDto> PendingTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 挂起任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.PENDING_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 提单纸页数计算
|
|
|
/// <summary>
|
|
|
/// 提单纸页数计算
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperCalc")]
|
|
|
public async Task<List<LaraPaperCalcInfo>> LaraPaperCalc(string[] PKIds)
|
|
|
{
|
|
|
List<LaraPaperCalcInfo> list = new List<LaraPaperCalcInfo>();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 提单纸页数计算开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//根据任务主键获取所有主单号列表
|
|
|
var mblnoList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID) && !string.IsNullOrWhiteSpace(t.MBL_NO))
|
|
|
.Select(t => t.MBL_NO).Distinct().ToList();
|
|
|
|
|
|
if (mblnoList.Count > 0)
|
|
|
{
|
|
|
//根据主单号获取任务类型是DRAFT的任务,取时间最新的
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) =>
|
|
|
tsk.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString() && mblnoList.Contains(tsk.MBL_NO))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
|
|
|
list = mblnoList.Select((mbl, idx) =>
|
|
|
{
|
|
|
var calcInfo = new LaraPaperCalcInfo();
|
|
|
|
|
|
calcInfo.MBLNo = mbl;
|
|
|
calcInfo.Indx = idx + 1;
|
|
|
|
|
|
var files = calcList.FirstOrDefault(t => t.tsk.MBL_NO.Equals(mbl, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (files != null)
|
|
|
{
|
|
|
calcInfo.DraftNum = files.clist.Select(t => t.FILE_NAME.GetPageNum()).Sum();
|
|
|
}
|
|
|
|
|
|
calcInfo.PaperNum = calcInfo.DraftNum * 3;
|
|
|
|
|
|
return calcInfo;
|
|
|
}).ToList();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("提单纸页数计算异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 请求提单纸登记
|
|
|
/// <summary>
|
|
|
/// 请求提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="laraPaperList">提单纸登记请求参数列表</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperRegistPost")]
|
|
|
public async Task<TaskManageOrderResultDto> LaraPaperRegistPost(List<LaraPaperRegistPostDto> laraPaperList)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} num={num} LARA提单纸登记开始", batchNo, laraPaperList.Count);
|
|
|
|
|
|
/*
|
|
|
1、读取LARA网站的配置账户。
|
|
|
2、读取字典的URL。
|
|
|
3、组织请求参数。
|
|
|
4、写入TASK_LARA_PAPER。
|
|
|
5、远程请求。
|
|
|
6、更新状态
|
|
|
*/
|
|
|
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskArg = laraPaperList.Select(t => t.TaskId).Distinct().ToArray();
|
|
|
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => taskArg.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成", batchNo);
|
|
|
|
|
|
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置
|
|
|
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_WEB_LARA_ACCOUNT_TYPE, UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
|
|
|
|
|
|
if (userWebAccountConfig == null)
|
|
|
throw Oops.Bah($"个人/公司网站【{CONST_WEB_LARA_ACCOUNT_TYPE}】获取失败,请维护个人/公司网站账户信息");
|
|
|
|
|
|
var downloadUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.First(t => t.Code.Equals(CONST_LARA_DOWN_URL_CODE, StringComparison.OrdinalIgnoreCase))?.Value;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(downloadUrl))
|
|
|
throw Oops.Bah($"LARA纸下载URL不存在,请确认字典是否配置 code={CONST_LARA_DOWN_URL_CODE}");
|
|
|
|
|
|
JObject jobjPost = new JObject();
|
|
|
jobjPost.Add("customer_user", "myshipping");
|
|
|
jobjPost.Add("customer_pwd", "");
|
|
|
JArray jarr = new JArray();
|
|
|
jobjPost.Add("lara_list", jarr);
|
|
|
|
|
|
laraPaperList.ForEach(async lara =>
|
|
|
{
|
|
|
TaskLARAPaperInfo taskLARAPaperInfo = new TaskLARAPaperInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = lara.TaskId,
|
|
|
BOOKING_ORDER_NO = "",
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
STATUS = "temp",
|
|
|
IS_TIMEOUT = 0,
|
|
|
START_DATE = DateTime.Now,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME,
|
|
|
PAGE_NUMBERS = lara.PageNumbers,
|
|
|
PAGE_SUM = lara.PageSum,
|
|
|
ISSUE_TYPE = lara.ISSUETYPE,
|
|
|
MBL_NO = lara.MBLNO,
|
|
|
NUMBER_FROM = lara.NumberFrom,
|
|
|
NUMBER_TO = lara.NumberTo,
|
|
|
DRAFT_NUM = lara.DraftNum,
|
|
|
};
|
|
|
|
|
|
//写入记录
|
|
|
await _taskLARAPaperInfoRepository.InsertAsync(taskLARAPaperInfo);
|
|
|
|
|
|
JObject jobjItem = new JObject();
|
|
|
jobjItem.Add("customer_user", "myshipping");
|
|
|
jobjItem.Add("customer_pwd", "");
|
|
|
jobjItem.Add("web_user", userWebAccountConfig.Account);
|
|
|
jobjItem.Add("web_pwd", userWebAccountConfig.Password);
|
|
|
jobjItem.Add("bno", lara.MBLNO);
|
|
|
jobjItem.Add("num_from", lara.NumberFrom);
|
|
|
jobjItem.Add("num_to", lara.NumberTo);
|
|
|
jobjItem.Add("numbers", lara.PageNumbers);
|
|
|
jobjItem.Add("vessel_code", "");
|
|
|
jobjItem.Add("voyage_code", "");
|
|
|
jobjItem.Add("bl_status", "All");
|
|
|
jobjItem.Add("bl_type", "Original Bill");
|
|
|
jobjItem.Add("issue_code", "ALL");
|
|
|
jarr.Add(jobjItem);
|
|
|
|
|
|
});
|
|
|
//await InnerDownloadOriginalTask(batchNo, taskInfo, userWebAccountConfig);
|
|
|
|
|
|
var postResult = await InnerRemoteDownLaraPaper(batchNo, downloadUrl, JSON.Serialize(jobjPost));
|
|
|
|
|
|
if (postResult.succ)
|
|
|
{
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = postResult.msg;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("请求提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 远程请求请求提单纸登记
|
|
|
/// <summary>
|
|
|
/// 远程请求请求提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <param name="jsonMsg">请求参数</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerRemoteDownLaraPaper(string batchNo, string url, string jsonMsg)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} 请求报文开始", batchNo);
|
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
.SetBody(jsonMsg, "application/json")
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
.PostAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(res));
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
var downResult = JSON.Deserialize<dynamic>(userResult);
|
|
|
|
|
|
//返回详情
|
|
|
result.msg = downResult.message.ToString();
|
|
|
|
|
|
//返回代码
|
|
|
if (downResult.status.ToString() == "1")
|
|
|
{
|
|
|
result.succ = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
result.ext = eDate;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
//如果有异常直接抛出错误
|
|
|
throw Oops.Bah(ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region LARA提单纸登记
|
|
|
/// <summary>
|
|
|
/// LARA提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperRegist")]
|
|
|
public async Task<LaraPaperRegistDto> LaraPaperRegist([FromQuery]string[] PKIds)
|
|
|
{
|
|
|
LaraPaperRegistDto result = new LaraPaperRegistDto();
|
|
|
|
|
|
List<LaraPaperRegistDetailDto> list = new List<LaraPaperRegistDetailDto>();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} LARA提单纸登记开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
/*
|
|
|
1、通过任务主键记录关联所有相同订舱主键相同并且任务类型是(DRAFT)的记录。
|
|
|
2、关联任务正本下载运行表(结束时间)
|
|
|
|
|
|
问题:提单纸页数计算是通过主单号来最新记录提取文件页数,为什么LARA提单纸登记没有用这个模式。(没理解)
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
//
|
|
|
var List = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskBaseInfo>((tsk, tsk2) => tsk.BOOK_ORDER_NO == tsk2.BOOK_ORDER_NO)
|
|
|
.Where((tsk, tsk2) => PKIds.Contains(tsk.PK_ID) && tsk2.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString())
|
|
|
.Select((tsk, tsk2) => new { tsk = tsk, tsk2 = tsk2 }).ToList();
|
|
|
|
|
|
var list2 = List.GroupBy(t => t.tsk.PK_ID).Select(t =>
|
|
|
{
|
|
|
var curList = t.ToList();
|
|
|
|
|
|
if (curList.Count > 0)
|
|
|
{
|
|
|
return new { tsk = curList.FirstOrDefault().tsk, tsk2 = curList.OrderByDescending(a => a.tsk2.CreatedTime).FirstOrDefault().tsk2 };
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}).Where(t => t != null).ToList();
|
|
|
|
|
|
if (list2.Count > 0)
|
|
|
{
|
|
|
var taskPKIdList = list2.Select(t => t.tsk2.PK_ID).Distinct().ToArray();
|
|
|
|
|
|
var originalDownloadHisInfo = _taskOriginalDownloadHisInfoRepository.AsQueryable()
|
|
|
.Where(t => taskPKIdList.Contains(t.TASK_ID))
|
|
|
.OrderByDescending(t => t.END_DATE)
|
|
|
.First();
|
|
|
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) =>
|
|
|
tsk.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString() && taskPKIdList.Contains(tsk.PK_ID))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
var bookingNoList = list2.Select(t => !string.IsNullOrWhiteSpace(t.tsk.BOOK_ORDER_NO) ?long.Parse(t.tsk.BOOK_ORDER_NO):0)
|
|
|
.Where(t=>t > 0).Distinct().ToList();
|
|
|
|
|
|
var orderList = _bookingOrderRepository.AsQueryable().Where(t => bookingNoList.Contains(t.Id)).ToList();
|
|
|
|
|
|
list2.ForEach(t =>
|
|
|
{
|
|
|
LaraPaperRegistDetailDto laraInfo = new LaraPaperRegistDetailDto();
|
|
|
|
|
|
laraInfo.OrderNo = t.tsk.BOOK_ORDER_NO;
|
|
|
laraInfo.TaskId = t.tsk.PK_ID;
|
|
|
laraInfo.MBLNo = t.tsk.MBL_NO;
|
|
|
|
|
|
var files = calcList.FirstOrDefault(a => a.tsk.PK_ID.Equals(t.tsk2.PK_ID));
|
|
|
|
|
|
if (files != null)
|
|
|
{
|
|
|
laraInfo.DraftNum = files.clist.Select(t => t.FILE_NAME.GetPageNum()).Sum();
|
|
|
}
|
|
|
|
|
|
laraInfo.OriginalDownTime = originalDownloadHisInfo?.END_DATE;
|
|
|
|
|
|
var orderInfo = orderList.FirstOrDefault(a => a.Id == long.Parse(t.tsk.BOOK_ORDER_NO));
|
|
|
|
|
|
laraInfo.IssueType = orderInfo?.ISSUETYPE;
|
|
|
//laraInfo.IssueTypeName = t.tsk2.issu;
|
|
|
|
|
|
list.Add(laraInfo);
|
|
|
});
|
|
|
|
|
|
result.DetailList = list;
|
|
|
}
|
|
|
|
|
|
var laraPaperInfo = _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.Where(t => t.CreatedUserId == UserManager.UserId)
|
|
|
.OrderByDescending(t => t.NUMBER_TO).First();
|
|
|
|
|
|
result.NumberTo = laraPaperInfo != null ? laraPaperInfo.NUMBER_TO : "1".PadLeft(9, '0'); ;
|
|
|
|
|
|
result.CalcList = InnerCalcLaraPageNumbers(new CalcLaraPageNumbersDto
|
|
|
{
|
|
|
numberTo = result.NumberTo,
|
|
|
paperList = result.DetailList.Select((t, idx) =>
|
|
|
{
|
|
|
return new LaraPaperRegistPostDto
|
|
|
{
|
|
|
DraftNum = t.DraftNum,
|
|
|
ISSUETYPE = t.IssueType,
|
|
|
MBLNO = t.MBLNo,
|
|
|
TaskId = t.TaskId,
|
|
|
ORDNO = t.OrderNo,
|
|
|
SortNo = idx + 1,
|
|
|
};
|
|
|
}).ToList()
|
|
|
},true);
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("LARA提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载任务附件
|
|
|
/// <summary>
|
|
|
/// 下载任务附件
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId"></param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
[HttpGet("/TaskManage/DownloadTaskAttach")]
|
|
|
public async Task<IActionResult> DownloadTaskAttach([FromQuery] string taskPKId)
|
|
|
{
|
|
|
FileStreamResult result = null;
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskPKId).OrderByDescending(t=>t.CreatedTime).ToList();
|
|
|
|
|
|
var fileInfo = fileList.FirstOrDefault();
|
|
|
if (fileInfo.FILE_PATH.StartsWith("http://"))
|
|
|
{
|
|
|
var fileStream = await InnerGetDownloadFile(fileInfo.FILE_PATH, taskPKId, batchNo);
|
|
|
|
|
|
result = new FileStreamResult(fileStream, "application/octet-stream") { FileDownloadName = fileInfo.FILE_NAME };
|
|
|
}
|
|
|
else if (System.IO.File.Exists(fileInfo.FILE_PATH))
|
|
|
{
|
|
|
result = new FileStreamResult(new FileStream(fileInfo.FILE_PATH, FileMode.Open), "application/octet-stream") { FileDownloadName = fileInfo.FILE_NAME };
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 异步下载文件
|
|
|
/// <summary>
|
|
|
/// 异步下载文件
|
|
|
/// </summary>
|
|
|
/// <param name="fileUrl">文件请求URL</param>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
private async Task<Stream> InnerGetDownloadFile(string fileUrl,string taskPKId,string batchNo)
|
|
|
{
|
|
|
Stream stream = null;
|
|
|
try
|
|
|
{
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
stream = await fileUrl.GetAsStreamAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} url={url} 请求完成,耗时:{timeDiff}ms.", batchNo, fileUrl, timeDiff);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} url={url} 下载文件异常, 结果{msg}", batchNo, fileUrl, ex.Message);
|
|
|
|
|
|
throw Oops.Bah(nameof(InnerGetDownloadFile)+"下载文件异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return stream;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 正本附件批量打印
|
|
|
/// <summary>
|
|
|
/// 正本附件批量打印
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
[HttpPost("/TaskManage/PrintBatch")]
|
|
|
public async Task<IActionResult> PrintBatch(string[] PKIds)
|
|
|
{
|
|
|
FileStreamResult result = null;
|
|
|
/*
|
|
|
1、通过任务主键获取所有的文件列表。只合并PDF文件,其他的文件不处理。
|
|
|
2、创建临时文件存放目录。
|
|
|
3、如果是http://开头的文档,需要使用下载文件,并变更为本地文件
|
|
|
4、PDF合成所有文件。
|
|
|
5、写入下载记录表。
|
|
|
6、返回文件流。
|
|
|
*/
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) => PKIds.Contains(tsk.PK_ID) && file.FILE_TYPE.Equals(".pdf"))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
var pdfList = calcList.SelectMany(t => t.clist).Select((t, idx) => new
|
|
|
{
|
|
|
Idx = idx,
|
|
|
file = t
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
if (pdfList.Count == 0)
|
|
|
throw Oops.Oh($"没有可以合并的PDF文件");
|
|
|
|
|
|
string filePath = string.Empty;
|
|
|
string tempFileName = IDGen.NextID().ToString();
|
|
|
|
|
|
var opt = App.GetOptions<TempFileOptions>().Path;
|
|
|
|
|
|
filePath = $"{Path.Combine(App.WebHostEnvironment.WebRootPath, opt)}\\TempPDFMerge\\";//服务器路径
|
|
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
|
{
|
|
|
filePath = filePath.Replace("\\", "/");
|
|
|
}
|
|
|
|
|
|
//预先创建目录
|
|
|
if (!Directory.Exists(filePath))
|
|
|
{
|
|
|
Directory.CreateDirectory(filePath);
|
|
|
}
|
|
|
|
|
|
var mergePdfPath = Path.Combine(filePath, $"{tempFileName}.pdf");
|
|
|
|
|
|
/*
|
|
|
Document document = null;
|
|
|
PdfCopy copy = null;
|
|
|
|
|
|
pdfList.ForEach(t => {
|
|
|
if(t.Idx == 0)
|
|
|
{
|
|
|
if(t.file.FILE_PATH.IndexOf("http://") >=0)
|
|
|
{
|
|
|
//var dw = InnerRemoteDownFile(t.file.FILE_PATH).GetAwaiter().GetResult();
|
|
|
|
|
|
WebClient wc = new WebClient();
|
|
|
wc.DownloadFile(t.file.FILE_PATH, Path.Combine(filePath, $"{tempFileName}abc.pdf"));
|
|
|
|
|
|
//document = new Document(new PdfReader(dw).GetPageSize(1));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
document = new Document(new PdfReader(t.file.FILE_PATH).GetPageSize(1));
|
|
|
}
|
|
|
|
|
|
copy = new PdfCopy(document, new FileStream(mergePdfPath, FileMode.Create));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
PdfReader reader = null;
|
|
|
|
|
|
if (t.file.FILE_PATH.IndexOf("http://") >= 0)
|
|
|
{
|
|
|
var dw = InnerRemoteDownFile(t.file.FILE_PATH).GetAwaiter().GetResult();
|
|
|
|
|
|
reader = new PdfReader(dw);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
reader = new PdfReader(t.file.FILE_PATH);
|
|
|
}
|
|
|
|
|
|
int n = reader.NumberOfPages;
|
|
|
for (int j = 1; j <= n; j++)
|
|
|
{
|
|
|
document.NewPage();
|
|
|
PdfImportedPage page = copy.GetImportedPage(reader, j);
|
|
|
copy.AddPage(page);
|
|
|
}
|
|
|
reader.Close();
|
|
|
}
|
|
|
});
|
|
|
|
|
|
document.Close();
|
|
|
*/
|
|
|
|
|
|
result = new FileStreamResult(new FileStream(mergePdfPath, FileMode.Open), "application/octet-stream") { FileDownloadName = $"{tempFileName}.pdf" };
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("LARA提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载文件
|
|
|
private async Task<Stream> InnerRemoteDownFile(string filePath)
|
|
|
{
|
|
|
using (HttpClient client = new HttpClient())
|
|
|
{
|
|
|
HttpResponseMessage response = await client.GetAsync(filePath);
|
|
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
{
|
|
|
System.Net.Http.HttpContent content = response.Content;
|
|
|
var contentStream = await content.ReadAsStreamAsync(); // get the actual content stream
|
|
|
return contentStream;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new FileNotFoundException($"{filePath} 文件下载失败");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 接收换船
|
|
|
/// <summary>
|
|
|
/// 接收换船
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/AcceptChangeShip")]
|
|
|
public async Task<TaskManageOrderResultDto> AcceptChangeShip([FromQuery]string taskPKId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 获取任务完成", batchNo, taskPKId);
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.CHANGE_SHIP.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.CHANGE_SHIP.GetDescription()},不能接收换船");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.STATUS != TaskStatusEnum.Create.ToString())
|
|
|
Oops.Oh($"任务状态不是{0},不能【接收换船】", TaskStatusEnum.Create.GetDescription());
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
{
|
|
|
orderInfo = _bookingOrderRepository.AsQueryable().First(t => t.MBLNO == taskInfo.MBL_NO);
|
|
|
|
|
|
_logger.LogInformation("批次={no} 订舱主键{id}获取任务失败,通过主单号{mblno}提取完成", batchNo, taskInfo.BOOK_ORDER_NO, taskInfo.MBL_NO);
|
|
|
}
|
|
|
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取用户邮箱配置完成", batchNo);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.RESULT_NOTE))
|
|
|
Oops.Oh($"获取换船任务详情失败");
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取换船任务详情,{note}", batchNo, taskInfo.RESULT_NOTE);
|
|
|
|
|
|
var jsonObj = JSON.Deserialize<dynamic>(taskInfo.RESULT_NOTE);
|
|
|
|
|
|
var taskChangeShipModel = new TaskChangeShipHisInfo {
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_PKID = taskInfo.PK_ID,
|
|
|
BOOK_ORDER_NO = orderInfo.Id.ToString(),
|
|
|
MBL_NO = orderInfo.MBLNO,
|
|
|
VESSEL_TO = jsonObj.vessel.ToString(),
|
|
|
VOYNO_TO = jsonObj.voyno.ToString(),
|
|
|
SHIP_AGENCY_TO = jsonObj.shipagency != null ? jsonObj.shipagency : "",
|
|
|
VESSEL_SRC = orderInfo.VESSEL,
|
|
|
VOYNO_SRC = orderInfo.VOYNO,
|
|
|
SHIP_AGENCY_SRC = orderInfo.SHIPAGENCY,
|
|
|
CreatedTime = DateTime.Now,
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name
|
|
|
};
|
|
|
|
|
|
//写入换船历史表
|
|
|
await _taskChangeShipHisInfoRepository.InsertAsync(taskChangeShipModel);
|
|
|
|
|
|
_logger.LogInformation("批次={no} 写入换船历史表完成{id}", batchNo, taskChangeShipModel.PK_ID);
|
|
|
|
|
|
//更新任务状态
|
|
|
orderInfo = _bookingOrderRepository.AsQueryable().First(t => t.Id == orderInfo.Id);
|
|
|
|
|
|
orderInfo.VESSEL = taskChangeShipModel.VESSEL_TO;
|
|
|
orderInfo.VOYNO = taskChangeShipModel.VOYNO_TO;
|
|
|
orderInfo.SHIPAGENCY = taskChangeShipModel.SHIP_AGENCY_TO;
|
|
|
orderInfo.CreatedTime = DateTime.Now;
|
|
|
orderInfo.CreatedUserId = UserManager.UserId;
|
|
|
orderInfo.CreatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新订舱详情
|
|
|
await _bookingOrderRepository.AsUpdateable(orderInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.VESSEL,
|
|
|
it.VOYNO
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 更新订舱完成", batchNo);
|
|
|
|
|
|
taskInfo.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskInfo.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
|
|
|
taskInfo.COMPLETE_DATE = DateTime.Now;
|
|
|
taskInfo.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskInfo.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
|
|
|
taskInfo.UpdatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
taskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新任务表
|
|
|
await _taskBaseInfoRepository.AsUpdateable(taskInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME,
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 更新任务完成", batchNo);
|
|
|
|
|
|
//提取订舱相关联系的邮箱信息
|
|
|
var bookContactEmailList = _bookingOrderContactRepository.AsQueryable().Where(t => t.BookingId == orderInfo.Id && !string.IsNullOrWhiteSpace(t.Email))
|
|
|
.Select(t => t.Email).Distinct().ToList();
|
|
|
|
|
|
if(bookContactEmailList.Count > 0)
|
|
|
{
|
|
|
string sendTo = string.Join(";", bookContactEmailList.ToArray());
|
|
|
|
|
|
string emailSubject = $"换船通知-{orderInfo.MBLNO}";
|
|
|
string emailBody = $"提单号为{orderInfo.MBLNO}的订舱已换船<br/>";
|
|
|
|
|
|
var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, sendTo);
|
|
|
|
|
|
_logger.LogInformation("批次={no} 发送邮件完成 {rlt}", batchNo,JSON.Serialize(sendResult));
|
|
|
|
|
|
//接受之后重新发送放舱
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "操作成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("接收换船异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 取消换船
|
|
|
/// <summary>
|
|
|
/// 取消换船
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/AcceptCancelChangeShip")]
|
|
|
public async Task<TaskManageOrderResultDto> AcceptCancelChangeShip([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 获取任务完成", batchNo, taskPKId);
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.ABORT_CHANGE_SHIP.GetDescription()},不能取消换船");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.STATUS != TaskStatusEnum.Create.ToString())
|
|
|
Oops.Oh($"任务状态不是{0},不能【取消换船】", TaskStatusEnum.Create.GetDescription());
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
_logger.LogInformation("批次={no} 订舱主键{id}获取订舱完成", batchNo, taskInfo.BOOK_ORDER_NO);
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.RESULT_NOTE))
|
|
|
Oops.Oh($"获取换船任务详情失败");
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取换船任务详情,{note}", batchNo, taskInfo.RESULT_NOTE);
|
|
|
|
|
|
var jsonObj = JSON.Deserialize<dynamic>(taskInfo.RESULT_NOTE);
|
|
|
|
|
|
//获取任务历史
|
|
|
var lastChangShipTask = await _taskBaseInfoRepository.AsQueryable().Where(t=>t.BOOK_ORDER_NO == taskInfo.BOOK_ORDER_NO && t.TASK_TYPE == TaskBusiTypeEnum.CHANGE_SHIP.ToString())
|
|
|
.OrderByDescending(t=>t.CreatedTime).FirstAsync();
|
|
|
|
|
|
if(lastChangShipTask != null)
|
|
|
{
|
|
|
if (lastChangShipTask.STATUS == TaskStatusEnum.Create.ToString()) //原换船通知未作处理
|
|
|
{
|
|
|
throw Oops.Bah("本票货存在未处理换船通知,请先结束原换船任务然后结束本任务。");
|
|
|
}
|
|
|
|
|
|
if (lastChangShipTask.STATUS == TaskStatusEnum.Cancel.ToString()) //原换船任务为结束任务
|
|
|
{
|
|
|
throw Oops.Bah("未做换船,请点击结束任务。");
|
|
|
}
|
|
|
|
|
|
if (lastChangShipTask.STATUS == TaskStatusEnum.Complete.ToString()) //原换船通知已经接受
|
|
|
{
|
|
|
//查询换船历史,恢复换船
|
|
|
var lastChangeShip = await _taskChangeShipHisInfoRepository.AsQueryable().Where(t => t.BOOK_ORDER_NO == orderInfo.Id.ToString())
|
|
|
.OrderByDescending(t => t.CreatedTime).FirstAsync();
|
|
|
|
|
|
if (lastChangeShip == null)
|
|
|
throw Oops.Bah("查询换船历史失败");
|
|
|
|
|
|
//更新任务状态
|
|
|
orderInfo = _bookingOrderRepository.AsQueryable().First(t => t.Id == orderInfo.Id);
|
|
|
|
|
|
orderInfo.VESSEL = lastChangeShip.VESSEL_SRC;
|
|
|
orderInfo.VOYNO = lastChangeShip.VOYNO_SRC;
|
|
|
orderInfo.SHIPAGENCY = lastChangeShip.SHIP_AGENCY_SRC;
|
|
|
|
|
|
_logger.LogInformation($"{orderInfo.MBLNO}接受取消换船,从{orderInfo.VESSEL}/{orderInfo.VOYNO} 到 {jsonObj.vessel.ToString()}/{jsonObj.voyno.ToString()}");
|
|
|
|
|
|
orderInfo.CreatedTime = DateTime.Now;
|
|
|
orderInfo.CreatedUserId = UserManager.UserId;
|
|
|
orderInfo.CreatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新订舱详情
|
|
|
await _bookingOrderRepository.AsUpdateable(orderInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.VESSEL,
|
|
|
it.VOYNO
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 更新订舱完成", batchNo);
|
|
|
|
|
|
taskInfo.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskInfo.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
|
|
|
taskInfo.COMPLETE_DATE = DateTime.Now;
|
|
|
taskInfo.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskInfo.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
|
|
|
taskInfo.UpdatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
taskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新任务表
|
|
|
await _taskBaseInfoRepository.AsUpdateable(taskInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME,
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 更新任务完成", batchNo);
|
|
|
|
|
|
//提取订舱相关联系的邮箱信息
|
|
|
var bookContactEmailList = _bookingOrderContactRepository.AsQueryable().Where(t => t.BookingId == orderInfo.Id && !string.IsNullOrWhiteSpace(t.Email))
|
|
|
.Select(t => t.Email).Distinct().ToList();
|
|
|
|
|
|
if (bookContactEmailList.Count > 0)
|
|
|
{
|
|
|
string sendTo = string.Join(";", bookContactEmailList.ToArray());
|
|
|
|
|
|
string emailSubject = $"取消换船通知-{orderInfo.MBLNO}";
|
|
|
string emailBody = $"取消换船通知-{orderInfo.MBLNO}\", $\"提单号为{orderInfo.MBLNO}的订舱已取消换船<br/>";
|
|
|
|
|
|
var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, sendTo);
|
|
|
|
|
|
_logger.LogInformation("批次={no} 发送邮件完成 {rlt}", batchNo, JSON.Serialize(sendResult));
|
|
|
|
|
|
//接受之后重新发送放舱
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "操作成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("取消换船异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 转发电放邮件
|
|
|
/// <summary>
|
|
|
/// 转发电放邮件
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="toMail">指定邮件地址</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/SendTelexEmail")]
|
|
|
public async Task<TaskManageOrderResultDto> SendTelexEmail([FromQuery] string taskPKId, [FromQuery] string toMail)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.TELEX_NOTICE.ToString() || taskInfo.TASK_TYPE != TaskBusiTypeEnum.SEAWAYBILL_DOWN.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.TELEX_NOTICE.GetDescription()}、{TaskBusiTypeEnum.SEAWAYBILL_DOWN.GetDescription()},不能转发邮件");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
string emailSubject = string.Empty;
|
|
|
string emailBody = string.Empty;
|
|
|
|
|
|
var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, toMail);
|
|
|
|
|
|
if (!sendResult.Key)
|
|
|
{
|
|
|
Oops.Oh(sendResult.Value);
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送下货纸
|
|
|
/// <summary>
|
|
|
/// 发送下货纸
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="fileRole">文件功能 (9原始)</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/SendShippingOrder")]
|
|
|
public async Task<TaskManageOrderResultDto> SendShippingOrder([FromQuery] string taskPKId, [FromQuery] string fileRole = "9")
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
/*
|
|
|
1、查询任务关联的订舱信息。
|
|
|
2、触发下货纸发送。
|
|
|
3、发送成功更新任务状态为成功。
|
|
|
4、查看用户公司是否配置了反馈地址,如果有配置则触发反馈推送,否则显示反馈失败提示。
|
|
|
5、触发扣费
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if(taskInfo.TASK_TYPE != TaskBusiTypeEnum.SHIPPING_ORDER.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SHIPPING_ORDER.GetDescription()},不能发送下货纸");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
//推送下货纸业务
|
|
|
var rtn = await XiahuozhiHelpler.Send(orderInfo.Id, fileRole);
|
|
|
|
|
|
if (!rtn.Key)
|
|
|
{
|
|
|
throw Oops.Bah($"发送失败:{rtn.Value}");
|
|
|
}
|
|
|
|
|
|
//订舱状态写入
|
|
|
await SaveBookingStatus(orderInfo.Id, "sta_xhz", "下货纸");
|
|
|
|
|
|
taskInfo.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskInfo.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
|
|
|
taskInfo.COMPLETE_DATE = DateTime.Now;
|
|
|
taskInfo.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskInfo.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
|
|
|
taskInfo.UpdatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
taskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新任务表
|
|
|
await _taskBaseInfoRepository.AsUpdateable(taskInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME,
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
await InnerChargeFeeShippingOrder(taskInfo);
|
|
|
|
|
|
//反馈用户(这里预留,主要考虑是否通过用户配置确定是否需要推送回执)
|
|
|
await FeedbackXiaHuoZhi("");
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 更新订舱的状态
|
|
|
/// <summary>
|
|
|
/// 更新订舱的状态
|
|
|
/// </summary>
|
|
|
/// <param name="bookingId">订舱主键</param>
|
|
|
/// <param name="code">状态代码</param>
|
|
|
/// <param name="name">状态名称</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task SaveBookingStatus(long bookingId, string code, string name)
|
|
|
{
|
|
|
var bookSta = _bookingStatusRepository.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 _bookingStatusRepository.InsertAsync(bookSta);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bookSta.StaTime = DateTime.Now;
|
|
|
await _bookingStatusRepository.UpdateAsync(bookSta);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 扣费
|
|
|
/// <summary>
|
|
|
/// 扣费
|
|
|
/// </summary>
|
|
|
/// <param name="taskBaseInfo">任务信息</param>
|
|
|
/// <param name="isCharge">是否执行扣费 true-执行扣费 false-不执行扣费(主要是符合扣费条件但是由于超时没有得到准确回执)</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerChargeFeeShippingOrder(TaskBaseInfo taskBaseInfo, bool isCharge = true)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = false };
|
|
|
try
|
|
|
{
|
|
|
decimal balance = 0;
|
|
|
decimal price = 0;
|
|
|
decimal total = 0;
|
|
|
|
|
|
TaskChargesHisInfo model = new TaskChargesHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
BEFORE_BALANCE = balance,
|
|
|
PRICE = price,
|
|
|
BUSI_TYPE = "21",
|
|
|
BUSI_TYPE_NAME = String.Empty,
|
|
|
SEND_TYPE = "1001",
|
|
|
SEND_TYPE_NAME = String.Empty,
|
|
|
REMARK = "下货纸",
|
|
|
QTY = 1,
|
|
|
TOTAL_AMOUNT = total,
|
|
|
};
|
|
|
|
|
|
if (!isCharge)
|
|
|
{
|
|
|
model.STATUS = TaskChargeStatusEnum.UNKNOW_RESULT.ToString();
|
|
|
model.STATUS_NAME = TaskChargeStatusEnum.UNKNOW_RESULT.GetDescription();
|
|
|
}
|
|
|
|
|
|
//写入记录
|
|
|
await _taskChargesHisInfoRepository.InsertAsync(model);
|
|
|
|
|
|
result.succ = false;
|
|
|
result.msg = "扣费失败";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取订舱详情
|
|
|
/// <summary>
|
|
|
/// 获取订舱详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetBookingOrderInfo")]
|
|
|
public async Task<TaskBookingOrderDto> GetBookingOrderInfo([FromQuery]string taskPKId)
|
|
|
{
|
|
|
TaskBookingOrderDto model = new TaskBookingOrderDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if(orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
|
|
|
var contaList = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == orderInfo.Id).ToListAsync();
|
|
|
|
|
|
//获取集装箱的主键
|
|
|
var ctnArg = contaList.Select(t => t.Id).ToArray();
|
|
|
|
|
|
//查询集装箱所有的货物信息
|
|
|
var cargoList = await _bookingOrderContaCargoRepository.AsQueryable()
|
|
|
.Where(x => ctnArg.Contains(x.CTNID.Value)).ToListAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 提取货物明细完成 数量={total}", batchNo, cargoList.Count);
|
|
|
|
|
|
if (cargoList.Count > 0)
|
|
|
{
|
|
|
model.ContaList = contaList.GroupJoin(cargoList, l => l.Id, r => r.CTNID, (l, r) => {
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var info = l.Adapt<TaskBookingOrderContaDto>();
|
|
|
info.CargoList = currList.Adapt<List<TaskBookingOrderCargoDto>>();
|
|
|
|
|
|
return info;
|
|
|
}
|
|
|
|
|
|
return l.Adapt<TaskBookingOrderContaDto>();
|
|
|
|
|
|
}).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
model.ContaList = contaList.Adapt<List<TaskBookingOrderContaDto>>();
|
|
|
}
|
|
|
|
|
|
//任务
|
|
|
model.TaskBaseInfo = taskInfo.Adapt<TaskBaseInfoDto>();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取订舱详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下货纸反馈
|
|
|
/// <summary>
|
|
|
/// 下货纸反馈
|
|
|
/// </summary>
|
|
|
/// <param name="bsno"></param>
|
|
|
/// <returns></returns>
|
|
|
private async Task FeedbackXiaHuoZhi(string bsno)
|
|
|
{
|
|
|
/*
|
|
|
var para = commonData.ParamValues.AsNoTracking().FirstOrDefault(x => x.CompId == compid && x.ParaCode == "XHZ_FEEDBACK_URL");
|
|
|
if (para == null || string.IsNullOrEmpty(para.ItemCode))
|
|
|
{
|
|
|
msg = "下货纸反馈地址未配置";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var feedbask = new BackgroundTaskCommon();
|
|
|
feedbask.GID = Guid.NewGuid().ToString();
|
|
|
feedbask.Status = BackgroundTaskCommon.StatusCreate;
|
|
|
feedbask.Type = BackgroundTaskCommon.TypeHttpFeedback;
|
|
|
feedbask.CreateTime = DateTime.Now;
|
|
|
feedbask.ParamData = JsonConvert.SerializeObject(new
|
|
|
{
|
|
|
url = para.ItemCode,
|
|
|
method = "POST",
|
|
|
json = JsonConvert.SerializeObject(new
|
|
|
{
|
|
|
bsno,
|
|
|
status
|
|
|
})
|
|
|
});
|
|
|
commonData.BackgroundTaskCommon.Add(feedbask);
|
|
|
|
|
|
msg = "成功";
|
|
|
return true;
|
|
|
*/
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取航次账单详情
|
|
|
/// <summary>
|
|
|
/// 获取航次账单详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetInvoiceBillInfo")]
|
|
|
public async Task<TaskInvoiceBillBaseInfo> GetInvoiceBillInfo([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskInvoiceBillBaseInfo model = new TaskInvoiceBillBaseInfo();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if(taskInfo.TASK_TYPE != TaskBusiTypeEnum.INVOICE_BILL_MAIL.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.INVOICE_BILL_MAIL.GetDescription()}");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//获取文件
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.TaskFile = fileList.Adapt<List<TaskManageOrderFileInfo>>();
|
|
|
|
|
|
var feeList = _taskBillFeeDetailInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.FeeList = feeList.Where(t => t.IS_TOTAL == 0).Select(t=>t.Adapt<TaskInvoiceBillFeeDto>()).ToList();
|
|
|
|
|
|
var totalUSD = feeList.FirstOrDefault(t => t.IS_TOTAL == 1 && t.FEE_NAME == "TotalUSD" && t.CURRENCY == "USD");
|
|
|
|
|
|
model.TotalAmountUSD = totalUSD != null ? totalUSD.TOTAL_AMOUNT : 0;
|
|
|
|
|
|
var totalCNY = feeList.FirstOrDefault(t => t.IS_TOTAL == 1 && t.FEE_NAME == "TotalCNY" && t.CURRENCY == "CNY");
|
|
|
|
|
|
model.TotalAmountCNY = totalCNY != null ? totalCNY.TOTAL_AMOUNT : 0;
|
|
|
|
|
|
model.InvoiceBillSendList = new List<TaskInvoiceBillFileHis>();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取获取航次账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取单票账单详情
|
|
|
/// <summary>
|
|
|
/// 获取单票账单详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetTaskPerBillInfo")]
|
|
|
public async Task<TaskPerBillResultInfo> GetTaskPerBillInfo([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskPerBillResultInfo model = new TaskPerBillResultInfo();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.PER_BILL.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.PER_BILL.GetDescription()}");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
var perBillInfo = _taskPerBillBaseInfoRepository.AsQueryable().First(t => t.TASK_PKID == taskInfo.PK_ID);
|
|
|
|
|
|
if (perBillInfo == null)
|
|
|
Oops.Oh($"单票账单不存在");
|
|
|
|
|
|
model.TaskPerBillBaseInfoDto = perBillInfo.Adapt<TaskPerBillBaseInfoDto>();
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//获取文件
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.TaskFile = fileList.Adapt<List<TaskManageOrderFileInfo>>();
|
|
|
|
|
|
var feeList = _taskBillFeeDetailInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.FeeList = feeList.Where(t => t.IS_TOTAL == 0).Select(t => t.Adapt<TaskPerBillFeeDto>()).ToList();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取获取单票账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取提单纸登记记录
|
|
|
/// <summary>
|
|
|
/// 获取提单纸登记记录
|
|
|
/// </summary>
|
|
|
/// <param name="querySearch">查询条件</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/GetLaraPaperRecordPage")]
|
|
|
public async Task<SqlSugarPagedList<LaraPaperRecordDto>> GetLaraPaperRecordPageAsync(QueryTaskManageBaseDto querySearch)
|
|
|
{
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
|
|
|
if (!string.IsNullOrWhiteSpace(querySearch.SortField))
|
|
|
entityOrderCol = MapsterExtHelper.GetAdaptProperty<LaraPaperRecordDto, TaskLARAPaperInfo>(querySearch.SortField);
|
|
|
|
|
|
var entities = await _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.OrderBy(entityOrderCol + (querySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(querySearch.PageNo, pageSize: querySearch.PageSize);
|
|
|
|
|
|
|
|
|
return entities.Adapt<SqlSugarPagedList<LaraPaperRecordDto>>();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 导出LARA提单纸登记记录
|
|
|
/// <summary>
|
|
|
/// 导出LARA提单纸登记记录
|
|
|
/// </summary>
|
|
|
/// <param name="sortField">排序字段</param>
|
|
|
/// <param name="pageNo">当前页码</param>
|
|
|
/// <param name="pageSize">页码容量</param>
|
|
|
/// <param name="descSort">排序方法,默认降序</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/LaraPaperRecordExport")]
|
|
|
public async Task<IActionResult> LaraPaperRecordExport([FromQuery] string sortField,[FromQuery] int pageNo = 1, [FromQuery] int pageSize = 30, [FromQuery] bool descSort = true)
|
|
|
{
|
|
|
QueryTaskManageBaseDto querySearch = new QueryTaskManageBaseDto
|
|
|
{
|
|
|
SortField = sortField,
|
|
|
PageNo = pageNo,
|
|
|
PageSize = pageSize,
|
|
|
descSort = descSort
|
|
|
};
|
|
|
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
var entities = await _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.OrderBy(entityOrderCol + (querySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(querySearch.PageNo, pageSize: querySearch.PageSize);
|
|
|
|
|
|
if(entities.Items.Count() == 0)
|
|
|
{
|
|
|
throw Oops.Oh($"没有可以导出的数据");
|
|
|
}
|
|
|
|
|
|
var list = entities.Items.Adapt<List<LaraPaperRecordDto>>();
|
|
|
|
|
|
//导出Excel文件流
|
|
|
var ms = ExportXlsLaraPaperRecord(list);
|
|
|
|
|
|
return new FileStreamResult(ms, "application/vnd.ms-excel") { FileDownloadName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}_LaraPaperRecord.xls" };
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 导出提单纸登记记录生成Excel
|
|
|
/// <summary>
|
|
|
/// 导出提单纸登记记录生成Excel
|
|
|
/// </summary>
|
|
|
/// <param name="list">LARA提单纸登记记录列表</param>
|
|
|
/// <returns>返回Excel文件流</returns>
|
|
|
private MemoryStream ExportXlsLaraPaperRecord(List<LaraPaperRecordDto> list)
|
|
|
{
|
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
IWorkbook workbook = new HSSFWorkbook();
|
|
|
ISheet sheet = workbook.CreateSheet();
|
|
|
IRow headerRow = sheet.CreateRow(0);
|
|
|
var headers = new string[] { "打印日期", "提单号", "Paper Number From", "Paper Number To", "Sum", "签单方式", "LARA登记时间", "LARA登记人" };
|
|
|
for (int i = 0; i < headers.Length; i++)
|
|
|
{
|
|
|
string head = headers[i];
|
|
|
var headCell = headerRow.CreateCell(i);
|
|
|
headCell.SetCellValue(head);
|
|
|
}
|
|
|
|
|
|
int rowIndex = 1;
|
|
|
foreach (var item in list)
|
|
|
{
|
|
|
IRow dataRow = sheet.CreateRow(rowIndex);
|
|
|
var cell0 = dataRow.CreateCell(0);
|
|
|
cell0.SetCellValue(item.OriginalDownTime);
|
|
|
|
|
|
var cell1 = dataRow.CreateCell(1);
|
|
|
cell1.SetCellValue(item.MBLNo);
|
|
|
|
|
|
var cell2 = dataRow.CreateCell(2);
|
|
|
cell2.SetCellValue(item.NumberFrom);
|
|
|
|
|
|
var cell3 = dataRow.CreateCell(3);
|
|
|
cell3.SetCellValue(item.NumberTo);
|
|
|
|
|
|
var cell4 = dataRow.CreateCell(4);
|
|
|
cell4.SetCellValue(item.PageSum);
|
|
|
|
|
|
var cell5 = dataRow.CreateCell(5);
|
|
|
cell5.SetCellValue(item.IssueTypeName);
|
|
|
|
|
|
var cell6 = dataRow.CreateCell(6);
|
|
|
cell6.SetCellValue(item.CreatedTime);
|
|
|
|
|
|
var cell7 = dataRow.CreateCell(7);
|
|
|
cell7.SetCellValue(item.CreatedUserName);
|
|
|
|
|
|
rowIndex++;
|
|
|
}
|
|
|
|
|
|
workbook.Write(ms, true);
|
|
|
ms.Flush();
|
|
|
ms.Position = 0;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("导出提单纸登记记录生成Excel异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return ms;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 保存SI信息
|
|
|
/// <summary>
|
|
|
/// 保存SI信息
|
|
|
/// </summary>
|
|
|
/// <param name="model">订舱信息</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/SaveBookingSI")]
|
|
|
public async Task<TaskManageOrderResultDto> SaveBookingSI(TaskBookingOrderDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、比较原始数据和修改数据内容,记录差异。
|
|
|
2、更新订舱主信息和集装箱信息。
|
|
|
3、写入本地历史记录表。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.TaskBaseInfo.PKId))
|
|
|
throw Oops.Oh($"任务主键TaskBaseInfo.PKId不能为空");
|
|
|
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == model.TaskBaseInfo.PKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
//取订舱详情(包含集装箱)
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.LeftJoin(_bookingOrderRepository.EntityContext.Queryable<BookingCtn>(),(bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(taskInfo.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
List<BookingCtn> orderCtnList = new List<BookingCtn>();
|
|
|
|
|
|
//这里是左连接查询,解决集装箱为空的情况
|
|
|
if(bookOrderList.Any(t=>t.ctn.Id > 0))
|
|
|
orderCtnList = bookOrderList.Select(t => t.ctn).ToList();
|
|
|
|
|
|
var mdBookingOrder = model.Adapt<BookingOrder>();
|
|
|
|
|
|
mdBookingOrder.Id = orderInfo.Id;
|
|
|
mdBookingOrder.UpdatedTime = DateTime.Now;
|
|
|
mdBookingOrder.UpdatedUserId = UserManager.UserId;
|
|
|
mdBookingOrder.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//比对主订舱信息
|
|
|
var orderDiff = InnerCompare(orderInfo, mdBookingOrder);
|
|
|
|
|
|
//比对箱信息
|
|
|
var contaList = model.ContaList.Select(x => x.Adapt<BookingCtn>()).ToList();
|
|
|
|
|
|
/**/
|
|
|
//这里参考原有的更新逻辑,只更新了SI回执有的字段信息,其他字段不更新,如果后期有调整可以自行增加更新字段
|
|
|
await _bookingOrderRepository.AsUpdateable(mdBookingOrder).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.SHIPPER,
|
|
|
it.CONSIGNEE,
|
|
|
it.NOTIFYPARTY,
|
|
|
it.MARKS,
|
|
|
it.DESCRIPTION,
|
|
|
it.BLFRT,
|
|
|
it.SERVICE,
|
|
|
it.ISSUETYPE,
|
|
|
it.PORTLOADID,
|
|
|
it.PORTLOAD,
|
|
|
it.PORTDISCHARGEID,
|
|
|
it.PORTDISCHARGE,
|
|
|
it.TRANSPORTID,
|
|
|
it.TRANSPORT,
|
|
|
it.DESTINATIONID,
|
|
|
it.DESTINATION,
|
|
|
it.PKGS,
|
|
|
it.KINDPKGS,
|
|
|
it.KGS,
|
|
|
it.CBM,
|
|
|
it.THIRDPAYADDR,
|
|
|
it.SIREMARK
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
var ctnlist = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == mdBookingOrder.Id).ToListAsync();
|
|
|
|
|
|
var si2orderCtnList = contaList.GroupJoin(ctnlist, l => l.CNTRNO?.Trim(), r => r.CNTRNO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
if(currInfo == null)
|
|
|
{
|
|
|
l.BILLID = orderInfo.Id;
|
|
|
l.CreatedTime = DateTime.Now;
|
|
|
l.CreatedUserId = UserManager.UserId;
|
|
|
l.CreatedUserName = UserManager.Name;
|
|
|
|
|
|
l.UpdatedTime = l.CreatedTime;
|
|
|
l.UpdatedUserId = UserManager.UserId;
|
|
|
l.UpdatedUserName = UserManager.Name;
|
|
|
return new { OperType = "insert", obj = l };
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
currInfo.Id = l.Id;
|
|
|
currInfo.BILLID = l.BILLID;
|
|
|
currInfo.UpdatedTime = DateTime.Now;
|
|
|
currInfo.UpdatedUserId = UserManager.UserId;
|
|
|
currInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
return new { OperType = "update", obj = currInfo };
|
|
|
}
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
var delList = ctnlist.GroupJoin(contaList, l => l.CNTRNO?.Trim(), r => r.CNTRNO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
if (currInfo == null)
|
|
|
{
|
|
|
l.UpdatedTime = DateTime.Now;
|
|
|
l.UpdatedUserId = UserManager.UserId;
|
|
|
l.UpdatedUserName = UserManager.Name;
|
|
|
return new { OperType = "delete", obj = l };
|
|
|
}
|
|
|
|
|
|
return new { OperType = string.Empty, obj = l };
|
|
|
}).Where(t=>t.OperType != string.Empty).ToList();
|
|
|
|
|
|
|
|
|
if (delList.Count > 0)
|
|
|
si2orderCtnList.AddRange(delList);
|
|
|
|
|
|
|
|
|
if (si2orderCtnList.Count > 0)
|
|
|
{
|
|
|
si2orderCtnList.ForEach(async ctn =>
|
|
|
{
|
|
|
if (ctn.OperType == "insert")
|
|
|
{
|
|
|
//插入
|
|
|
await _bookingOrderContaRepository.InsertAsync(ctn.obj);
|
|
|
}
|
|
|
else if (ctn.OperType == "update")
|
|
|
{
|
|
|
//更新
|
|
|
await _bookingOrderContaRepository.AsUpdateable(ctn.obj).UpdateColumns(it => new
|
|
|
{
|
|
|
it.CTNALL,
|
|
|
it.SEALNO,
|
|
|
it.PKGS,
|
|
|
it.KGS,
|
|
|
it.CBM,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
else if (ctn.OperType == "delete")
|
|
|
{
|
|
|
await _bookingOrderContaRepository.DeleteAsync(x => x.Id == ctn.obj.Id);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "保存SI信息成功";
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("保存SI信息异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取SI反馈信息
|
|
|
/// <summary>
|
|
|
/// 获取SI反馈信息
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetSIFeedBackInfo")]
|
|
|
public async Task<TaskSIFeedBackResultDto> GetSIFeedBackInfo(string taskPKId)
|
|
|
{
|
|
|
TaskSIFeedBackResultDto model = new TaskSIFeedBackResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.InnerJoin<BookingCtn>((bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(taskInfo.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
var siFeedBackList = _taskSIFeedBackInfoRepository.EntityContext.Queryable<TaskSIFeedBackInfo>()
|
|
|
.InnerJoin<TaskSIFeedBackContaInfo>((si, ctn) => si.PK_ID == ctn.P_PKID)
|
|
|
.Where((si, ctn) => si.TASK_PKID == model.TaskId && si.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((si, ctn) => new { si = si, ctn = ctn }).ToList();
|
|
|
|
|
|
if (siFeedBackList.Count == 0)
|
|
|
throw Oops.Oh($"SI反馈信息不存在");
|
|
|
|
|
|
var siFeedBackInfo = siFeedBackList.FirstOrDefault().si;
|
|
|
|
|
|
var resultInfo = siFeedBackInfo.Adapt<TaskSIFeedBackResultBusiDto>();
|
|
|
|
|
|
resultInfo.ContaList = siFeedBackList.Select(t => t.ctn.Adapt<TaskSIFeedBackResultContaDto>()).ToList();
|
|
|
|
|
|
model.BusiInfo = resultInfo;
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//进行数据比对确认差异字段KEY
|
|
|
var mainDiff = await InnerCompareMainInfoDiff(orderInfo, siFeedBackInfo);
|
|
|
|
|
|
model.SICompareOrderKeyList = mainDiff;
|
|
|
|
|
|
var contaDiff = await InnerCompareContaInfoDiff(bookOrderList.Select(t=>t.ctn).ToList(),
|
|
|
siFeedBackList.Select(t=>t.ctn).ToList());
|
|
|
|
|
|
model.SICompareOrderContaKeyList = contaDiff;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取获取单票账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
private List<TaskCompareResultDto> InnerCompare(object srcModel,object targetModel)
|
|
|
{
|
|
|
List<TaskCompareResultDto> list = new List<TaskCompareResultDto>();
|
|
|
|
|
|
if(srcModel is BookingOrder)
|
|
|
{
|
|
|
var srcBK = (BookingOrder)srcModel;
|
|
|
var targetBK = (BookingOrder)targetModel;
|
|
|
|
|
|
var bookProps = typeof(BookingOrder).GetProperties();
|
|
|
|
|
|
list = bookProps.Select(prop =>
|
|
|
{
|
|
|
var bk1Val = prop.GetValue(srcBK);
|
|
|
var bk2Val = prop.GetValue(targetBK);
|
|
|
|
|
|
if (prop.PropertyType == typeof(string))
|
|
|
{
|
|
|
string st1 = (bk1Val as string).AdjustString();
|
|
|
string st2 = (bk2Val as string).AdjustString();
|
|
|
|
|
|
if (st1 != st2)
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = false, ValType = prop.PropertyType };
|
|
|
}
|
|
|
else if (prop.PropertyType == typeof(int?))
|
|
|
{
|
|
|
var dt1 = bk1Val as int?;
|
|
|
var dt2 = bk2Val as int?;
|
|
|
|
|
|
if (dt1 != dt2)
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
else if (prop.PropertyType == typeof(decimal?))
|
|
|
{
|
|
|
var dt1 = bk1Val as decimal?;
|
|
|
var dt2 = bk2Val as decimal?;
|
|
|
|
|
|
if (dt1 != dt2)
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
if (bk1Val != bk2Val)
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = false, ValType = prop.PropertyType };
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
#region 比较主信息
|
|
|
/// <summary>
|
|
|
/// 比较主信息
|
|
|
/// </summary>
|
|
|
/// <param name="bookingOrder">订舱详情</param>
|
|
|
/// <param name="taskSIFeedBackInfo">SI反馈详情</param>
|
|
|
/// <returns>返回差异</returns>
|
|
|
private async Task<List<string>> InnerCompareMainInfoDiff(BookingOrder bookingOrder, TaskSIFeedBackInfo taskSIFeedBackInfo)
|
|
|
{
|
|
|
List<string> resultList = new List<string>();
|
|
|
|
|
|
//需要比对的字段
|
|
|
var compareField = new string[] { "SHIPPER", "CONSIGNEE", "NOTIFYPARTY", "MARKS", "DESCRIPTION", "BLFRT", "SERVICE", "ISSUETYPE", "PORTLOAD", "PORTDISCHARGE",
|
|
|
"TRANSPORT", "DESTINATION", "PKGS", "KGS", "CBM", "KINDPKGS", "THIRDPAYADDR" };
|
|
|
|
|
|
var bookProps = typeof(BookingOrder).GetProperties();
|
|
|
var feedProps = typeof(TaskSIFeedBackInfo).GetProperties();
|
|
|
|
|
|
resultList = bookProps.GroupJoin(feedProps, l => l.Name.ToUpper(),
|
|
|
r => r.Name.ToUpper(), (l, r) =>
|
|
|
{
|
|
|
if (compareField.Any(x => x.Equals(l.Name, StringComparison.OrdinalIgnoreCase)))
|
|
|
{
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var si = r.FirstOrDefault();
|
|
|
|
|
|
var bkVal = l.GetValue(bookingOrder);
|
|
|
var siVal = si.GetValue(taskSIFeedBackInfo);
|
|
|
|
|
|
if (l.PropertyType == typeof(string))
|
|
|
{
|
|
|
string st1 = (bkVal as string).AdjustString();
|
|
|
string st2 = (siVal as string).AdjustString();
|
|
|
|
|
|
if (!st1.Equals(st2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
else if (l.PropertyType == typeof(int?))
|
|
|
{
|
|
|
var dt1 = bkVal as int?;
|
|
|
var dt2 = siVal as int?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
else if (l.PropertyType == typeof(decimal?))
|
|
|
{
|
|
|
var dt1 = bkVal as decimal?;
|
|
|
var dt2 = siVal as decimal?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
}).Where(t => !string.IsNullOrWhiteSpace(t)).ToList();
|
|
|
|
|
|
return resultList;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 比较箱信息
|
|
|
/// <summary>
|
|
|
/// 比较箱信息
|
|
|
/// </summary>
|
|
|
/// <param name="bookContaList">订舱箱信息</param>
|
|
|
/// <param name="siContaList">SI反馈箱信息</param>
|
|
|
/// <returns>返回差异</returns>
|
|
|
private async Task<List<string>> InnerCompareContaInfoDiff(List<BookingCtn> bookContaList,List<TaskSIFeedBackContaInfo> siContaList)
|
|
|
{
|
|
|
List<string> resultList = new List<string>();
|
|
|
|
|
|
var bookProps = typeof(BookingCtn).GetProperties();
|
|
|
var feedProps = typeof(TaskSIFeedBackContaInfo).GetProperties();
|
|
|
|
|
|
resultList = siContaList.GroupJoin(bookContaList, l => l.CONTA_NO, r => r.CNTRNO, (l, r) =>
|
|
|
{
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var bkCtn = currList.FirstOrDefault();
|
|
|
|
|
|
if (!l.KGS.Equals(bkCtn.KGS)
|
|
|
|| !l.PKGS.Equals(bkCtn.PKGS)
|
|
|
|| !l.SEAL_NO.Equals(bkCtn.SEALNO)
|
|
|
|| !l.CONTA_TYPE.Equals(bkCtn.CTNALL)
|
|
|
|| !l.CBM.Equals(bkCtn.CBM))
|
|
|
{
|
|
|
return l.CONTA_NO;
|
|
|
}
|
|
|
|
|
|
return String.Empty;
|
|
|
}
|
|
|
|
|
|
return l.CONTA_NO;
|
|
|
}).Where(t => !string.IsNullOrWhiteSpace(t)).ToList();
|
|
|
|
|
|
return resultList;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取VGM比较结果
|
|
|
/// <summary>
|
|
|
/// 获取VGM比较结果
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetVGMCompareResult")]
|
|
|
public async Task<TaskVgmCompareResultDto> GetVGMCompareResult(string taskPKId)
|
|
|
{
|
|
|
TaskVgmCompareResultDto model = new TaskVgmCompareResultDto();
|
|
|
|
|
|
List<TaskVgmCompareDto> list = new List<TaskVgmCompareDto>();
|
|
|
List<TaskVgmCompareDto> list2 = new List<TaskVgmCompareDto>();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.VGM_COMPARE.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.VGM_COMPARE.GetDescription()}");
|
|
|
|
|
|
var vgmList = _taskVGMFeedBackInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID)
|
|
|
.ToList();
|
|
|
|
|
|
if(vgmList.Count == 0)
|
|
|
throw Oops.Oh($"VGM反馈信息不存在");
|
|
|
|
|
|
var contaList = _bookingOrderContaRepository.AsQueryable().Where(t => t.BILLID == long.Parse(taskInfo.BOOK_ORDER_NO)).ToList();
|
|
|
|
|
|
list = contaList.GroupJoin(vgmList, l => l.CNTRNO?.Trim(), r => r.CONTA_NO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
TaskVgmCompareDto md = l.Adapt<TaskVgmCompareDto>();
|
|
|
|
|
|
md.compareDiffList = new List<string>();
|
|
|
|
|
|
if (currInfo != null)
|
|
|
{
|
|
|
if(l.SEALNO != currInfo.SEAL_NO)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.SealNo));
|
|
|
}
|
|
|
if (l.CTNCODE != currInfo.CONTA_TYPE)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaType));
|
|
|
}
|
|
|
if (l.CTNALL != currInfo.CONTA_TYPE_NAME)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaTypeName));
|
|
|
}
|
|
|
if (l.KGS != currInfo.KGS)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.KGS));
|
|
|
}
|
|
|
if (l.TAREWEIGHT != currInfo.TAREWEIGHT)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.TareWeight));
|
|
|
}
|
|
|
if (l.WEIGHKGS != currInfo.WEIGHKGS)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighKGs));
|
|
|
}
|
|
|
if (l.WEIGHTYPE != currInfo.WEIGHTYPE)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighType));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
md.compareDiffList = new List<string> { nameof(TaskVgmCompareDto.ContaNo),
|
|
|
nameof(TaskVgmCompareDto.SealNo),
|
|
|
nameof(TaskVgmCompareDto.ContaType),
|
|
|
nameof(TaskVgmCompareDto.ContaTypeName),
|
|
|
nameof(TaskVgmCompareDto.KGS),
|
|
|
nameof(TaskVgmCompareDto.TareWeight),
|
|
|
nameof(TaskVgmCompareDto.WeighKGs),
|
|
|
nameof(TaskVgmCompareDto.WeighType),
|
|
|
};
|
|
|
}
|
|
|
|
|
|
return md;
|
|
|
}).ToList();
|
|
|
|
|
|
model.bookOrderCompareList = list;
|
|
|
|
|
|
list2 = vgmList.GroupJoin(contaList, l => l.CONTA_NO?.Trim(), r => r.CNTRNO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
TaskVgmCompareDto md = l.Adapt<TaskVgmCompareDto>();
|
|
|
|
|
|
md.compareDiffList = new List<string>();
|
|
|
|
|
|
if (currInfo != null)
|
|
|
{
|
|
|
if (l.SEAL_NO != currInfo.SEALNO)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.SealNo));
|
|
|
}
|
|
|
if (l.CONTA_TYPE != currInfo.CTNCODE)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaType));
|
|
|
}
|
|
|
if (l.CONTA_TYPE_NAME != currInfo.CTNALL)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaTypeName));
|
|
|
}
|
|
|
if (l.KGS != currInfo.KGS)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.KGS));
|
|
|
}
|
|
|
if (l.TAREWEIGHT != currInfo.TAREWEIGHT)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.TareWeight));
|
|
|
}
|
|
|
if (l.WEIGHKGS != currInfo.WEIGHKGS)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighKGs));
|
|
|
}
|
|
|
if (l.WEIGHTYPE != currInfo.WEIGHTYPE)
|
|
|
{
|
|
|
md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighType));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
md.compareDiffList = new List<string> { nameof(TaskVgmCompareDto.ContaNo),
|
|
|
nameof(TaskVgmCompareDto.SealNo),
|
|
|
nameof(TaskVgmCompareDto.ContaType),
|
|
|
nameof(TaskVgmCompareDto.ContaTypeName),
|
|
|
nameof(TaskVgmCompareDto.KGS),
|
|
|
nameof(TaskVgmCompareDto.TareWeight),
|
|
|
nameof(TaskVgmCompareDto.WeighKGs),
|
|
|
nameof(TaskVgmCompareDto.WeighType),
|
|
|
};
|
|
|
}
|
|
|
|
|
|
return md;
|
|
|
}).ToList();
|
|
|
|
|
|
model.vgmCompareList = list2;
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取VGM比较结果异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 更新订舱(VGM比较更新)
|
|
|
/// <summary>
|
|
|
/// 更新订舱(VGM比较更新)
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/SaveBookingVGM")]
|
|
|
public async Task<TaskManageOrderResultDto> SaveBookingVGM(string taskPKId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.VGM_COMPARE.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.VGM_COMPARE.GetDescription()}");
|
|
|
|
|
|
//取订舱详情(包含集装箱)
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.LeftJoin(_bookingOrderRepository.EntityContext.Queryable<BookingCtn>(), (bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(taskInfo.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
List<BookingCtn> orderCtnList = new List<BookingCtn>();
|
|
|
|
|
|
//这里是左连接查询,解决集装箱为空的情况
|
|
|
if (bookOrderList.Any(t => t.ctn.Id > 0))
|
|
|
orderCtnList = bookOrderList.Select(t => t.ctn).ToList();
|
|
|
|
|
|
var contaList = _taskVGMFeedBackInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
var si2orderCtnList = contaList.GroupJoin(orderCtnList, l => l.CONTA_NO?.Trim(), r => r.CNTRNO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
var contaInfo = l.Adapt<BookingCtn>();
|
|
|
|
|
|
if (currInfo == null)
|
|
|
{
|
|
|
contaInfo.BILLID = orderInfo.Id;
|
|
|
contaInfo.CreatedTime = DateTime.Now;
|
|
|
contaInfo.CreatedUserId = UserManager.UserId;
|
|
|
contaInfo.CreatedUserName = UserManager.Name;
|
|
|
|
|
|
contaInfo.UpdatedTime = contaInfo.CreatedTime;
|
|
|
contaInfo.UpdatedUserId = UserManager.UserId;
|
|
|
contaInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
return new { OperType = "insert", obj = contaInfo };
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
currInfo.Id = contaInfo.Id;
|
|
|
currInfo.BILLID = contaInfo.BILLID;
|
|
|
currInfo.UpdatedTime = DateTime.Now;
|
|
|
currInfo.UpdatedUserId = UserManager.UserId;
|
|
|
currInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
return new { OperType = "update", obj = currInfo };
|
|
|
}
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
var delList = orderCtnList.GroupJoin(contaList, l => l.CNTRNO?.Trim(), r => r.CONTA_NO?.Trim(), (l, r) => {
|
|
|
var currInfo = r.FirstOrDefault();
|
|
|
|
|
|
if (currInfo == null)
|
|
|
{
|
|
|
l.UpdatedTime = DateTime.Now;
|
|
|
l.UpdatedUserId = UserManager.UserId;
|
|
|
l.UpdatedUserName = UserManager.Name;
|
|
|
return new { OperType = "delete", obj = l };
|
|
|
}
|
|
|
|
|
|
return new { OperType = string.Empty, obj = l };
|
|
|
}).Where(t => t.OperType != string.Empty).ToList();
|
|
|
|
|
|
|
|
|
if (delList.Count > 0)
|
|
|
si2orderCtnList.AddRange(delList);
|
|
|
|
|
|
|
|
|
if (si2orderCtnList.Count > 0)
|
|
|
{
|
|
|
si2orderCtnList.ForEach(async ctn =>
|
|
|
{
|
|
|
if (ctn.OperType == "insert")
|
|
|
{
|
|
|
//插入
|
|
|
await _bookingOrderContaRepository.InsertAsync(ctn.obj);
|
|
|
}
|
|
|
else if (ctn.OperType == "update")
|
|
|
{
|
|
|
//更新
|
|
|
await _bookingOrderContaRepository.AsUpdateable(ctn.obj).UpdateColumns(it => new
|
|
|
{
|
|
|
it.CTNALL,
|
|
|
it.SEALNO,
|
|
|
it.PKGS,
|
|
|
it.KGS,
|
|
|
it.CBM,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
else if (ctn.OperType == "delete")
|
|
|
{
|
|
|
await _bookingOrderContaRepository.DeleteAsync(x => x.Id == ctn.obj.Id);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "更新订舱成功";
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("更新订舱(VGM比较更新)异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取换船详情
|
|
|
/// <summary>
|
|
|
/// 获取换船详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetChangeShipInfo")]
|
|
|
public async Task<TaskChangeShipResultDto> GetChangeShipInfo(string taskPKId)
|
|
|
{
|
|
|
TaskChangeShipResultDto model = new TaskChangeShipResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.CHANGE_SHIP.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.CHANGE_SHIP.GetDescription()}");
|
|
|
|
|
|
BookingOrder bookingOrder = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t=>t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
//这里参考源程序,如果任务没有对应订舱数据则通过主单号匹配一条订舱数据
|
|
|
if(bookingOrder == null)
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.MBLNO == taskInfo.MBL_NO && !t.ParentId.HasValue);
|
|
|
|
|
|
if (bookingOrder == null)
|
|
|
throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.RESULT_NOTE))
|
|
|
throw Oops.Oh($"任务反馈详情不存在");
|
|
|
|
|
|
var rtl = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(taskInfo.RESULT_NOTE);
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
model.TaskStatus = taskInfo.STATUS;
|
|
|
model.TaskStatusName = taskInfo.STATUS_NAME;
|
|
|
|
|
|
model.Vessel = rtl.vessel.ToString();
|
|
|
model.Voyno = rtl.voyno.ToString();
|
|
|
model.ShipAgency = rtl.shipagency == null? rtl.shipagency.ToString():"";
|
|
|
model.MailUrl = rtl.mail_url.ToString();
|
|
|
|
|
|
model.OriginalVessel = bookingOrder.VESSEL;
|
|
|
model.OriginalVoyno = bookingOrder.VOYNO;
|
|
|
model.MBlNo = bookingOrder.MBLNO;
|
|
|
|
|
|
//获得未处理的任务数量
|
|
|
model.TotalTask = await _taskBaseInfoRepository.AsQueryable().Where(t => t.CreatedTime < taskInfo.CreatedTime && t.STATUS == TaskStatusEnum.Create.ToString()
|
|
|
&& (t.TASK_TYPE == TaskBusiTypeEnum.CHANGE_SHIP.ToString() || t.TASK_TYPE == TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())).CountAsync();
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取换船详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取取消换船详情
|
|
|
/// <summary>
|
|
|
/// 获取取消换船详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetAbortChangeShipInfo")]
|
|
|
public async Task<TaskChangeShipResultDto> GetAbortChangeShipInfo(string taskPKId)
|
|
|
{
|
|
|
TaskChangeShipResultDto model = new TaskChangeShipResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.ABORT_CHANGE_SHIP.GetDescription()}");
|
|
|
|
|
|
BookingOrder bookingOrder = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
//这里参考源程序,如果任务没有对应订舱数据则通过主单号匹配一条订舱数据
|
|
|
if (bookingOrder == null)
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.MBLNO == taskInfo.MBL_NO && !t.ParentId.HasValue);
|
|
|
|
|
|
if (bookingOrder == null)
|
|
|
throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.RESULT_NOTE))
|
|
|
throw Oops.Oh($"任务反馈详情不存在");
|
|
|
|
|
|
var rtl = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(taskInfo.RESULT_NOTE);
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
model.TaskStatus = taskInfo.STATUS;
|
|
|
model.TaskStatusName = taskInfo.STATUS_NAME;
|
|
|
|
|
|
model.Vessel = rtl.vessel.ToString();
|
|
|
model.Voyno = rtl.voyno.ToString();
|
|
|
model.ShipAgency = rtl.shipagency == null ? rtl.shipagency.ToString() : "";
|
|
|
model.MailUrl = rtl.mail_url.ToString();
|
|
|
|
|
|
model.OriginalVessel = bookingOrder.VESSEL;
|
|
|
model.OriginalVoyno = bookingOrder.VOYNO;
|
|
|
model.MBlNo = bookingOrder.MBLNO;
|
|
|
|
|
|
//获得未处理的任务数量
|
|
|
model.TotalTask = await _taskBaseInfoRepository.AsQueryable().Where(t => t.CreatedTime < taskInfo.CreatedTime && t.STATUS == TaskStatusEnum.Create.ToString()
|
|
|
&& (t.TASK_TYPE == TaskBusiTypeEnum.CHANGE_SHIP.ToString() || t.TASK_TYPE == TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())).CountAsync();
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("获取取消换船详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 手工批量重新比对BC
|
|
|
/// <summary>
|
|
|
/// 手工批量重新比对BC
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/ManualReCompareBC")]
|
|
|
public async Task<TaskManageOrderResultDto> ManualReCompareBC(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 手工批量重新比对BC开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
var list = new List<TaskManageOrderResultDto>();
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
var rlt = await InnerSingleManualReCompareBC(tsk);
|
|
|
|
|
|
list.Add(rlt);
|
|
|
});
|
|
|
|
|
|
|
|
|
if (list.Any(t => !t.succ))
|
|
|
{
|
|
|
result.msg = "失败";
|
|
|
result.succ = false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.msg = "成功";
|
|
|
result.succ = true;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("手工批量重新比对BC异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 手工单票重新比对BC
|
|
|
/// <summary>
|
|
|
/// 手工单票重新比对BC
|
|
|
/// </summary>
|
|
|
/// <param name="model">任务详情</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerSingleManualReCompareBC(TaskBaseInfo model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、通过任务的报文表获取BC的报文。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var storeInfo = await _taskStoreMsgInfoRepository.AsQueryable()
|
|
|
.Where(t => t.TASK_PKID == model.PK_ID && t.MSG_TYPE == TaskStoreMsgTypeEnum.BC_MSG.ToString()).FirstAsync();
|
|
|
|
|
|
if(storeInfo == null)
|
|
|
throw Oops.Oh("MBL_NO={0},获取{1}报文失败", model.MBL_NO,TaskStoreMsgTypeEnum.BC_MSG.GetDescription());
|
|
|
|
|
|
var rtl = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(storeInfo.MSG_JSON);
|
|
|
|
|
|
string msg = string.Empty;
|
|
|
//2023-02-02 测试过程中发现JSON数据格式有了变化,这里增加兼容
|
|
|
if(rtl.mesage != null)
|
|
|
{
|
|
|
msg = JSON.Serialize(rtl.mesage);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msg = storeInfo.MSG_JSON;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(msg))
|
|
|
throw Oops.Oh("MBL_NO={0},解析{1}报文详情异常", model.MBL_NO, TaskStoreMsgTypeEnum.BC_MSG.GetDescription());
|
|
|
|
|
|
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.InnerJoin<BookingCtn>((bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(model.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
//获取订舱详情与BC进行比对
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
List<BookingCtn> ctnList = new List<BookingCtn>();
|
|
|
|
|
|
if (bookOrderList.Any(t => t.ctn != null))
|
|
|
ctnList = bookOrderList.Select(t => t.ctn).ToList();
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
throw Oops.Oh("MBL_NO={0},获取订舱详情失败", model.MBL_NO);
|
|
|
|
|
|
TaskBCStoreResultInfo bcStoreInfo = JSON.Deserialize<TaskBCStoreResultInfo>(msg);
|
|
|
|
|
|
//BC比较
|
|
|
var compareResult = InnerCompareBC(bcStoreInfo,orderInfo, ctnList);
|
|
|
|
|
|
if(!compareResult.succ)
|
|
|
{
|
|
|
//更新任务的反馈结果
|
|
|
model.RESULT_NOTE = compareResult.msg;
|
|
|
model.UpdatedTime = DateTime.Now;
|
|
|
model.UpdatedUserId = UserManager.UserId;
|
|
|
model.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.RESULT_NOTE,
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//置任务状态为完成
|
|
|
model.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
model.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
model.COMPLETE_DATE = DateTime.Now;
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
model.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
|
|
|
model.UpdatedTime = DateTime.Now;
|
|
|
model.UpdatedUserId = UserManager.UserId;
|
|
|
model.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME,
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
//更新订舱的ETD(记个日志)
|
|
|
if (!string.IsNullOrWhiteSpace(bcStoreInfo.ETD))
|
|
|
{
|
|
|
DateTime etd = DateTime.MinValue;
|
|
|
|
|
|
if(DateTime.TryParse(bcStoreInfo.ETD,out etd))
|
|
|
{
|
|
|
orderInfo.ETD = etd;
|
|
|
orderInfo.UpdatedTime = DateTime.Now;
|
|
|
orderInfo.UpdatedUserId = UserManager.UserId;
|
|
|
orderInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _bookingOrderRepository.AsUpdateable(orderInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName,
|
|
|
it.ETD
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
}
|
|
|
//【预留】异步推送后台任务(订舱自动放舱-BookingFangCang)
|
|
|
//【预留】异步推送后台任务(下货纸-Xiahuozhi)
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "处理成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"手工重新比对BC异常,{ex.Message}";
|
|
|
|
|
|
//throw Oops.Bah("手工重新比对BC异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 单票比对BC
|
|
|
/// <summary>
|
|
|
/// 单票比对BC
|
|
|
/// </summary>
|
|
|
/// <param name="bcStoreInfo">BC回执详情</param>
|
|
|
/// <param name="orderInfo">订舱详情</param>
|
|
|
/// <param name="ctnList">订舱集装箱列表</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
private TaskManageOrderResultDto InnerCompareBC(TaskBCStoreResultInfo bcStoreInfo,BookingOrder orderInfo,List<BookingCtn> ctnList)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = true};
|
|
|
|
|
|
try
|
|
|
{
|
|
|
List<Tuple<bool, string>> rltTupleList = new List<Tuple<bool, string>>();
|
|
|
|
|
|
/*
|
|
|
迁移过来的注释
|
|
|
2021-9-28,需求再变,BC需要再次比对约号
|
|
|
2021-7-19 需求修改:BC不需要再对比约号
|
|
|
*/
|
|
|
|
|
|
//约号
|
|
|
if (!string.IsNullOrWhiteSpace(orderInfo.CONTRACTNO))
|
|
|
{
|
|
|
if ((string.IsNullOrWhiteSpace(bcStoreInfo.BJH) || !Regex.IsMatch(orderInfo.CONTRACTNO, $"\\b{bcStoreInfo.BJH.Trim()}\\b"))
|
|
|
&& (string.IsNullOrWhiteSpace(bcStoreInfo.FWHT) || !Regex.IsMatch(orderInfo.CONTRACTNO, $"\\b{bcStoreInfo.FWHT.Trim()}\\b")))
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "约号不一致"));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(bcStoreInfo.BJH) || !string.IsNullOrWhiteSpace(bcStoreInfo.FWHT))
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "约号不一致"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 集装箱
|
|
|
//集装箱
|
|
|
if (bcStoreInfo.CntrTotal != orderInfo.CNTRTOTAL)
|
|
|
{
|
|
|
//集装箱型
|
|
|
var ediCtnList = _cache.GetAllMappingCtn().GetAwaiter().GetResult()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
|
|
|
&& !string.IsNullOrWhiteSpace(t.CarrierCode) && t.CarrierCode.Equals(orderInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
var storeCtnList = bcStoreInfo.CntrTotal.Split(new char[] { ';' }).Select(t =>
|
|
|
{
|
|
|
var currArg = t.Split(new char[] { 'x' });
|
|
|
|
|
|
return new { Code = currArg[1]?.Trim(), Num = int.Parse(currArg[0]?.Trim()) };
|
|
|
}).GroupBy(t => t.Code)
|
|
|
.Select(t =>
|
|
|
{
|
|
|
return new { Code = t.Key, Num = t.Sum(x => x.Num) };
|
|
|
}).ToList();
|
|
|
|
|
|
var orderCtnListctnList = ctnList.Select(t =>
|
|
|
{
|
|
|
var mapCtn = ediCtnList.FirstOrDefault(x => x.Code.Equals(t.CTNCODE));
|
|
|
|
|
|
if (mapCtn != null && !string.IsNullOrWhiteSpace(mapCtn.MapCode))
|
|
|
return new { Code = mapCtn.MapCode, Num = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 };
|
|
|
|
|
|
return new { Code = t.CTNCODE, Num = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 };
|
|
|
}).GroupBy(t => t.Code)
|
|
|
.Select(t =>
|
|
|
{
|
|
|
return new { Code = t.Key, Num = t.Sum(x => x.Num) };
|
|
|
}).ToList();
|
|
|
|
|
|
if (storeCtnList.Count != orderCtnListctnList.Count)
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "箱型箱量不一致"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var totalList = storeCtnList.GroupJoin(orderCtnListctnList, l => l.Code, r => r.Code, (l, r) =>
|
|
|
{
|
|
|
var rModel = r.FirstOrDefault();
|
|
|
|
|
|
if (rModel == null)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (l.Num != rModel.Num)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}).ToList();
|
|
|
|
|
|
if (totalList.Any(t => !t))
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "箱型箱量不一致"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
//船名
|
|
|
if (bcStoreInfo.Vessel != orderInfo.VESSEL?.Trim())
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "船名不一致"));
|
|
|
}
|
|
|
|
|
|
//航次
|
|
|
if (bcStoreInfo.Voyno?.Replace("1MA", "") != orderInfo.VOYNO?.Trim()
|
|
|
&& bcStoreInfo.Voyno2 != orderInfo.VOYNO?.Trim() && bcStoreInfo.Voyno3 != orderInfo.VOYNO?.Trim())
|
|
|
{
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "航次不一致"));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
//2021-10-12,增加最小、最大、运输温度,湿度,通风 的比较
|
|
|
//2021-11-23,备注中含有NOR,不比较温度湿度等信息
|
|
|
|
|
|
2023-02-02 这里补充了一下EDIREMARK的判断,用正则匹配NOR信息。NOR(冻代干集装箱)
|
|
|
*/
|
|
|
if (orderInfo.CARGOID == "R" && (string.IsNullOrWhiteSpace(orderInfo.SOREMARK) || !Regex.IsMatch(orderInfo.SOREMARK, "\\bNOR\\b")))
|
|
|
{
|
|
|
//最低温度
|
|
|
var compareReult = CompareTemperatureNum(orderInfo.TEMPMIN, bcStoreInfo.TempMin, "temp");
|
|
|
|
|
|
if (!compareReult.Item1)
|
|
|
rltTupleList.Add(compareReult);
|
|
|
|
|
|
//最高温度
|
|
|
compareReult = CompareTemperatureNum(orderInfo.TEMPMAX, bcStoreInfo.TempMax, "temp", "最高温度");
|
|
|
|
|
|
if (!compareReult.Item1)
|
|
|
rltTupleList.Add(compareReult);
|
|
|
|
|
|
//运输温度
|
|
|
compareReult = CompareTemperatureNum(orderInfo.TEMPSET, bcStoreInfo.TempTransport, "temp", "运输温度");
|
|
|
|
|
|
if (!compareReult.Item1)
|
|
|
rltTupleList.Add(compareReult);
|
|
|
|
|
|
//湿度
|
|
|
compareReult = CompareTemperatureNum(orderInfo.HUMIDITY, bcStoreInfo.Humidity, "humidity", "湿度");
|
|
|
|
|
|
if (!compareReult.Item1)
|
|
|
rltTupleList.Add(compareReult);
|
|
|
|
|
|
//通风
|
|
|
compareReult = CompareTemperatureNum(orderInfo.REEFERF, bcStoreInfo.VentilationCubicMeter, "vent", "通风");
|
|
|
|
|
|
if (!compareReult.Item1)
|
|
|
rltTupleList.Add(compareReult);
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 2021-12-3,捷丰要求加卸货港和目的地校验,规则:
|
|
|
* A:大简云里卸货港字段‘,’之前的字符和BC里卸货港‘,’之前的字段。
|
|
|
* 1.一致,自动发送下货纸
|
|
|
* 2.不一致,生成待处理下货纸任务。
|
|
|
* B:bc如果有最终交货地 那么要和系统目的港对比;最终交货地空白 就不用对比这个地方
|
|
|
*/
|
|
|
string orderPortDischarge = orderInfo.PORTDISCHARGE.Split(new char[] { ',' }).FirstOrDefault()?.Trim();
|
|
|
string storePortDischarge = bcStoreInfo.PortDischargeEName.Split(new char[] { ',' }).FirstOrDefault()?.Trim();
|
|
|
|
|
|
if (orderPortDischarge != storePortDischarge)
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "卸货港不一致"));
|
|
|
|
|
|
string orderDest = orderInfo.DESTINATION.Split(new char[] { ',' }).FirstOrDefault()?.Trim();
|
|
|
string storeDest = bcStoreInfo.ZZJHD.Split(new char[] { ',' }).FirstOrDefault()?.Trim();
|
|
|
|
|
|
if (orderDest != storeDest)
|
|
|
rltTupleList.Add(new Tuple<bool, string>(false, "目的地不一致"));
|
|
|
|
|
|
if (rltTupleList.Any(t => !t.Item1))
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = string.Join(";", rltTupleList.Select(t => t.Item2).ToArray());
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("{0}单票比对BC异常,{1}",nameof(InnerCompareBC), ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 对比温度
|
|
|
/// <summary>
|
|
|
/// 对比温度
|
|
|
/// </summary>
|
|
|
/// <param name="orderTemperature">订舱数值</param>
|
|
|
/// <param name="storeTemperature">回执数值</param>
|
|
|
/// <param name="operType">操作类型 temp-温度 humidity-湿度 vent-通风</param>
|
|
|
/// <param name="showName">显示名称</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
private Tuple<bool, string> CompareTemperatureNum(string orderTemperature,string storeTemperature,string operType = "temp",string showName = "最低温度")
|
|
|
{
|
|
|
decimal orderTemp = int.MaxValue;
|
|
|
decimal storeTemp = int.MaxValue;
|
|
|
|
|
|
decimal.TryParse(orderTemperature, out orderTemp);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(storeTemperature))
|
|
|
{
|
|
|
if (operType == "temp")
|
|
|
{
|
|
|
decimal.TryParse(Regex.Match(storeTemperature, "(\\-?([0-9]?|[0-9]+)\\.?[0-9]+)(?=C)").Value, out storeTemp);
|
|
|
}
|
|
|
else if (operType == "humidity")
|
|
|
{
|
|
|
decimal.TryParse(Regex.Match(storeTemperature, "\\[0-9]+").Value, out storeTemp);
|
|
|
}
|
|
|
else if (operType == "vent")
|
|
|
{
|
|
|
decimal.TryParse(storeTemperature, out storeTemp);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (storeTemp != int.MaxValue && orderTemp != int.MaxValue)
|
|
|
{
|
|
|
if (storeTemp != orderTemp)
|
|
|
return new Tuple<bool, string>(false, $"{showName}不一致");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (storeTemp != int.MaxValue || orderTemp != int.MaxValue)
|
|
|
return new Tuple<bool, string>(false, $"{showName}不一致");
|
|
|
}
|
|
|
|
|
|
return new Tuple<bool, string>(true, "");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载截单EDI
|
|
|
/// <summary>
|
|
|
/// 下载截单EDI
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="orderNo">订单号</param>
|
|
|
/// <param name="useForwarderCode">是否使用货代代码</param>
|
|
|
/// <param name="forwarderCode">货代代码</param>
|
|
|
/// <param name="forwarderName">货代称呼</param>
|
|
|
/// <param name="fileRole">文件功能 (9原始,1 更新,5 退舱 )</param>
|
|
|
/// <param name="sendType">发送类型 E-截单</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/DownloadClosingEDI")]
|
|
|
public async Task<IActionResult> DownloadClosingEDI([FromQuery] string taskPKId, [FromQuery] string orderNo, [FromQuery] bool useForwarderCode,
|
|
|
[FromQuery] string forwarderCode, [FromQuery] string forwarderName, [FromQuery] string fileRole, [FromQuery] string sendType)
|
|
|
{
|
|
|
if (sendType?.ToUpper() != "E")
|
|
|
throw Oops.Oh($"sendType只接收E-截单");
|
|
|
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
BookingOrder bookingOrder = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (bookingOrder == null)
|
|
|
throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}");
|
|
|
|
|
|
var model = new BookingOrClosingEDIOrderDto
|
|
|
{
|
|
|
Id = bookingOrder.Id,
|
|
|
orderNo = orderNo,
|
|
|
useForwarderCode = useForwarderCode,
|
|
|
forwarderCode = forwarderCode,
|
|
|
forwarderName = forwarderName,
|
|
|
fileRole = fileRole,
|
|
|
send = false,
|
|
|
sendType = sendType
|
|
|
};
|
|
|
|
|
|
var bookingOrderService = _namedBookingOrderServiceProvider.GetService<ITransient>(nameof(BookingOrderService));
|
|
|
|
|
|
var filePath = await bookingOrderService.InnerBookingOrClosingEDI(model);
|
|
|
|
|
|
var fileInfo = new FileInfo(filePath);
|
|
|
|
|
|
var result = new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileInfo.Name };
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送截单EDI
|
|
|
/// <summary>
|
|
|
/// 发送截单EDI
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="orderNo">订单号</param>
|
|
|
/// <param name="useForwarderCode">是否使用货代代码</param>
|
|
|
/// <param name="forwarderCode">货代代码</param>
|
|
|
/// <param name="forwarderName">货代称呼</param>
|
|
|
/// <param name="fileRole">文件功能 (9原始,1 更新,5 退舱 )</param>
|
|
|
/// <param name="sendType">发送类型 E-截单</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/SendClosingEDI")]
|
|
|
public async Task<string> SendClosingEDI([FromQuery] string taskPKId, [FromQuery] string orderNo, [FromQuery] bool useForwarderCode,
|
|
|
[FromQuery] string forwarderCode, [FromQuery] string forwarderName, [FromQuery] string fileRole, [FromQuery] string sendType)
|
|
|
{
|
|
|
if (sendType?.ToUpper() != "E")
|
|
|
throw Oops.Oh($"sendType只接收E-截单");
|
|
|
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
BookingOrder bookingOrder = null;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (bookingOrder == null)
|
|
|
throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}");
|
|
|
|
|
|
var model = new BookingOrClosingEDIOrderDto
|
|
|
{
|
|
|
Id = bookingOrder.Id,
|
|
|
orderNo = orderNo,
|
|
|
useForwarderCode = useForwarderCode,
|
|
|
forwarderCode = forwarderCode,
|
|
|
forwarderName = forwarderName,
|
|
|
fileRole = fileRole,
|
|
|
send = true,
|
|
|
sendType = sendType
|
|
|
};
|
|
|
|
|
|
var bookingOrderService = _namedBookingOrderServiceProvider.GetService<ITransient>(nameof(BookingOrderService));
|
|
|
|
|
|
return await bookingOrderService.InnerBookingOrClosingEDI(model);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 计算LARA纸计算页数
|
|
|
/// <summary>
|
|
|
/// 计算LARA纸计算页数
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求LARA纸详情</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/CalcLaraPageNumbers")]
|
|
|
public async Task<List<LaraPaperRegistPostDto>> CalcLaraPageNumbers(CalcLaraPageNumbersDto model)
|
|
|
{
|
|
|
List<LaraPaperRegistPostDto> list = new List<LaraPaperRegistPostDto>();
|
|
|
|
|
|
/*
|
|
|
LARA计算方法
|
|
|
|
|
|
1、判断是否为首次加载,model.moveType为空时表示首次加载,触发InitCalcLaraPageNumbers方法。
|
|
|
2、如果 model.moveType有值时,判断是调整行位置,根据指定的行位置重新计算编号。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if(string.IsNullOrWhiteSpace(model.moveType))
|
|
|
{
|
|
|
list = InnerCalcLaraPageNumbers(model,true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
list = InnerCalcLaraPageNumbers(model);
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("计算LARA纸计算页数异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 计算LARA纸
|
|
|
/// <summary>
|
|
|
/// 计算LARA纸
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求LARA纸详情</param>
|
|
|
/// <param name="isInit">是否初始化 true-初始化</param>
|
|
|
/// <returns></returns>
|
|
|
private List<LaraPaperRegistPostDto> InnerCalcLaraPageNumbers(CalcLaraPageNumbersDto model,bool isInit = false)
|
|
|
{
|
|
|
List<LaraPaperRegistPostDto> list = new List<LaraPaperRegistPostDto>();
|
|
|
|
|
|
//如果判断不是首次加载,需要将移动的行从列表移动到指定位置后,重新计算。
|
|
|
if(!isInit)
|
|
|
{
|
|
|
model.paperList = model.paperList.Select(t =>
|
|
|
{
|
|
|
if (t.SortNo == model.origIndex.Value)
|
|
|
{
|
|
|
//up
|
|
|
if(model.currIndex < model.origIndex)
|
|
|
{
|
|
|
t.SortNo = (decimal)model.currIndex.Value - 0.1m;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
t.SortNo = (decimal)model.currIndex.Value + 0.1m;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return t;
|
|
|
}).OrderBy(t => t.SortNo)
|
|
|
.Select((t, idx) =>
|
|
|
{
|
|
|
t.SortNo = (decimal)idx + 1;
|
|
|
return t;
|
|
|
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
var mNumberTo = model.numberTo.TrimStart('0') == "" ? 0 : int.Parse(model.numberTo.TrimStart('0'));
|
|
|
|
|
|
if (mNumberTo > 0)
|
|
|
{
|
|
|
int lastNumberTo = 0;
|
|
|
int lastNumberFrom = 0;
|
|
|
|
|
|
model.paperList.OrderBy(t => t.SortNo).ToList().ForEach(t =>
|
|
|
{
|
|
|
LaraPaperRegistPostDto info = new LaraPaperRegistPostDto();
|
|
|
|
|
|
info.SortNo = t.SortNo;
|
|
|
info.DraftNum = t.DraftNum;
|
|
|
info.TaskId = t.TaskId;
|
|
|
info.ORDNO = t.ORDNO;
|
|
|
info.MBLNO = t.MBLNO;
|
|
|
info.ISSUETYPE = t.ISSUETYPE;
|
|
|
|
|
|
if (t.SortNo == 1)
|
|
|
{
|
|
|
lastNumberFrom = mNumberTo + 1;
|
|
|
info.NumberFrom = (lastNumberFrom).ToString().PadLeft(9, '0');
|
|
|
|
|
|
var currNumberTo = (t.DraftNum * LARA_PARER_DRAFT_VAR) + mNumberTo;
|
|
|
|
|
|
info.NumberTo = currNumberTo.ToString().PadLeft(9, '0');
|
|
|
info.PageSum = currNumberTo - lastNumberFrom + 1;
|
|
|
|
|
|
lastNumberTo = currNumberTo;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
lastNumberFrom = lastNumberTo + 1;
|
|
|
info.NumberFrom = (lastNumberFrom).ToString().PadLeft(9, '0');
|
|
|
|
|
|
var currNumberTo = (t.DraftNum * LARA_PARER_DRAFT_VAR) + lastNumberTo;
|
|
|
|
|
|
info.NumberTo = currNumberTo.ToString().PadLeft(9, '0');
|
|
|
info.PageSum = currNumberTo - lastNumberFrom + 1;
|
|
|
|
|
|
lastNumberTo = currNumberTo;
|
|
|
}
|
|
|
|
|
|
|
|
|
list.Add(info);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 撤销任务
|
|
|
/// </summary>
|
|
|
/// <param name="info">任务详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public async Task<TaskManageOrderResultDto> CancelTaskJob(TaskManageOrderMessageInfo info)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、通过Head.GID检索任务表。
|
|
|
2、任务不存在提示检索失败。
|
|
|
3、任务存在判断当前状态已完成、已取消、已挂起不能撤销。
|
|
|
4、派车任务业务状态是SEND_DISPATCH不能撤销。
|
|
|
5、更新任务状态、更新派车任务状态。
|
|
|
6、返回结果
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable()
|
|
|
.First(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}");
|
|
|
|
|
|
if(taskInfo == null)
|
|
|
throw Oops.Oh($"任务不存在");
|
|
|
|
|
|
if(new string[] { TaskStatusEnum.Complete.ToString(), TaskStatusEnum.Pending.ToString(),TaskStatusEnum.Pending.ToString() }
|
|
|
.Contains(taskInfo.STATUS))
|
|
|
throw Oops.Oh($"任务状态是已完成/已挂起/已取消的不能撤销");
|
|
|
|
|
|
var truckInfo = _taskTruckInfoRepository.AsQueryable().First(a => a.TASK_ID == taskInfo.PK_ID);
|
|
|
|
|
|
if (truckInfo == null)
|
|
|
throw Oops.Oh($"派车任务不存在");
|
|
|
|
|
|
if(truckInfo.Status == BookingTruckStatus.SEND_DISPATCH.ToString())
|
|
|
throw Oops.Oh($"派车任务状态是已派车不能撤销");
|
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
truckInfo.Status = BookingTruckStatus.CANCELED.ToString();
|
|
|
|
|
|
UserTendDto userTendInfo = GetUserTendInfo(info.Main.TaskUserId);
|
|
|
|
|
|
truckInfo.UpdatedUserId = userTendInfo.userId;
|
|
|
truckInfo.UpdatedUserName = userTendInfo.userName;
|
|
|
truckInfo.UpdatedTime = nowDate;
|
|
|
|
|
|
//更新派车任务
|
|
|
await _taskTruckInfoRepository.AsUpdateable(truckInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedUserId,
|
|
|
it.Status,
|
|
|
it.UpdatedUserName,
|
|
|
it.UpdatedTime
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
taskInfo.UpdatedUserId = userTendInfo.userId;
|
|
|
taskInfo.UpdatedUserName = userTendInfo.userName;
|
|
|
taskInfo.UpdatedTime = nowDate;
|
|
|
taskInfo.STATUS = TaskStatusEnum.Cancel.ToString();
|
|
|
|
|
|
//更新任务
|
|
|
await _taskBaseInfoRepository.AsUpdateable(taskInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.UpdatedUserId,
|
|
|
it.STATUS,
|
|
|
it.UpdatedUserName,
|
|
|
it.UpdatedTime
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "撤销成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError("撤销任务异常,原因:{error}", ex.Message);
|
|
|
|
|
|
throw Oops.Oh($"{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 样本业务提取帮助类
|
|
|
/// <summary>
|
|
|
/// 样本业务提取帮助类
|
|
|
/// </summary>
|
|
|
public static class DraftPaperExtension
|
|
|
{
|
|
|
public static int GetPageNum(this string Name)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(Name))
|
|
|
return 0;
|
|
|
|
|
|
string s = Regex.Replace(Name.Substring(Name.LastIndexOf('-') + 1), "\\.[a-zA-Z]+", "");
|
|
|
|
|
|
return int.Parse(s);
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah("文件名{0} 取页数异常,{1}", Name, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 整理文本数据
|
|
|
public static class CompareObjExtension
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 整理文本数据
|
|
|
/// </summary>
|
|
|
/// <param name="str">文本</param>
|
|
|
/// <returns></returns>
|
|
|
public static string AdjustString(this string str)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(str))
|
|
|
return str;
|
|
|
|
|
|
var rtn = str.Replace("\r\n", "\n").Trim();
|
|
|
if (rtn.EndsWith("\n"))
|
|
|
{
|
|
|
rtn = rtn.Substring(0, rtn.Length - 1);
|
|
|
}
|
|
|
|
|
|
return rtn;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 文本转换成日期
|
|
|
/// </summary>
|
|
|
/// <param name="str">文本</param>
|
|
|
/// <param name="MemberName">字段名称</param>
|
|
|
/// <returns>返回日期</returns>
|
|
|
public static Nullable<DateTime> GetDateTime(this string str,string MemberName)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(str))
|
|
|
return null;
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!DateTime.TryParse(str, out currDate))
|
|
|
throw Oops.Oh("字段{0}={1}转换日期失败,请检查日期格式", MemberName, str);
|
|
|
|
|
|
return currDate;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
}
|