You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1730 lines
70 KiB
C#

2 years ago
using Furion;
using Furion.DistributedIDGenerator;
2 years ago
using Furion.DynamicApiController;
2 years ago
using Furion.FriendlyException;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using HtmlAgilityPack;
2 years ago
using Mapster;
using Microsoft.AspNetCore.Http;
2 years ago
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
2 years ago
using Myshipping.Application.ConfigOption;
2 years ago
using Myshipping.Application.Entity;
2 years ago
using Myshipping.Application.Enum;
using Myshipping.Application.Service.BookingSlot.Dto;
2 years ago
using Myshipping.Core;
11 months ago
using Myshipping.Core.Entity;
2 years ago
using Myshipping.Core.Service;
using Newtonsoft.Json;
using Npoi.Mapper;
2 years ago
using NPOI.SS.Formula.Functions;
using RabbitMQ.Client;
using SqlSugar;
using StackExchange.Profiling.Internal;
2 years ago
using System;
using System.Collections.Generic;
2 years ago
using System.IO;
2 years ago
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Principal;
2 years ago
using System.Text;
using System.Threading.Tasks;
2 years ago
using System.Web;
using System.Xml;
using Yitter.IdGenerator;
2 years ago
namespace Myshipping.Application
{
/// <summary>
/// BC任务
/// </summary>
[ApiDescriptionSettings("Application", Name = "TaskManageBC", Order = 10)]
2 years ago
public class TaskManageBCService: ITaskManageBCService, IDynamicApiController
{
private readonly ISysCacheService _cache;
private readonly ILogger<TaskManageBCService> _logger;
private readonly SqlSugarRepository<TaskBCInfo> _taskBCInfoRepository;
private readonly SqlSugarRepository<TaskBCCTNInfo> _taskBCCTNInfoRepository;
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
private readonly SqlSugarRepository<TaskFileInfo> _taskFileRepository;
2 years ago
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly SqlSugarRepository<BookingCtn> _bookingCtnRepository;
11 months ago
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
private readonly SqlSugarRepository<BookingFile> _bookingFileRepository;
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
11 months ago
private readonly IServiceWorkFlowBaseService _serviceWorkFlowBaseService;
private readonly IBookingOrderService _bookingOrderService;
private readonly IBookingSlotService _bookingSlotService;
11 months ago
private readonly IBookingValueAddedService _bookingValueAddedService;
11 months ago
private readonly IDjyCustomerService _djyCustomerService;
11 months ago
const string CONST_BC_FILE_CODE = "bc";
const string CONST_BC_FILE_NAME = "Booking Confirmation";
const string CONST_BC_NOTICE_FILE_CODE = "bc_notice";
const string CONST_BC_NOTICE_FILE_NAME = "Booking Confirmation Notice";
2 years ago
public TaskManageBCService(SqlSugarRepository<TaskBCInfo> taskBCInfoRepository,
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
SqlSugarRepository<TaskBCCTNInfo> taskBCCTNInfoRepository,
2 years ago
SqlSugarRepository<TaskFileInfo> taskFileRepository,
SqlSugarRepository<BookingOrder> bookingOrderRepository,
11 months ago
SqlSugarRepository<BookingCtn> bookingCtnRepository,
SqlSugarRepository<SysUser> sysUserRepository,
SqlSugarRepository<BookingFile> bookingFileRepository,
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
IServiceWorkFlowBaseService serviceWorkFlowBaseService,
IBookingOrderService bookingOrderService, ILogger<TaskManageBCService> logger,
11 months ago
IDjyCustomerService djyCustomerService,
IBookingSlotService bookingSlotService, ISysCacheService cache, IBookingValueAddedService bookingValueAddedService)
2 years ago
{
_taskBaseRepository = taskBaseRepository;
_taskBCInfoRepository = taskBCInfoRepository;
_taskBCCTNInfoRepository = taskBCCTNInfoRepository;
_taskFileRepository = taskFileRepository;
2 years ago
_bookingOrderRepository = bookingOrderRepository;
_bookingCtnRepository = bookingCtnRepository;
11 months ago
_sysUserRepository = sysUserRepository;
_serviceWorkFlowBaseService = serviceWorkFlowBaseService;
_bookingOrderService = bookingOrderService;
_bookingSlotService = bookingSlotService;
_cache = cache;
_bookingValueAddedService = bookingValueAddedService;
_bookingFileRepository = bookingFileRepository;
11 months ago
_djyCustomerService = djyCustomerService;
_djyUserMailAccount = djyUserMailAccount;
_logger = logger;
11 months ago
}
2 years ago
#region 获取BC详情
/// <summary>
/// 获取BC详情
/// </summary>
/// <param name="pkId">BC主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/GetInfo")]
public async Task<TaskManageOrderResultDto> GetInfo(string pkId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == pkId);
if (bcOrder == null)
throw Oops.Oh($"BC主键{pkId}无法获取业务信息");
var BCCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == pkId).ToList();
TaskBCShowBaseDto model = bcOrder.Adapt<TaskBCShowBaseDto>();
if (BCCtnList.Count > 0)
model.CtnList = BCCtnList.Adapt<List<TaskBCCTNInfoDto>>();
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList();
if (fileList.Count > 0)
model.FileList = fileList.Adapt<List<TaskFileDto>>();
2 years ago
result.succ = true;
result.ext = model;
2 years ago
//如果当前BC有对应记录则读取订舱详情
if (bcOrder.BOOKING_ORDER_ID.HasValue)
{
var bkOrder = await _bookingOrderRepository.AsQueryable().
FirstAsync(a => a.Id == bcOrder.BOOKING_ORDER_ID.Value);
if (bkOrder != null)
{
var showBKOrder = bkOrder.Adapt<BookingOrderOutput>();
var ctnList = await _bookingCtnRepository.AsQueryable().
Where(a => a.BILLID == bkOrder.Id).ToListAsync();
2 years ago
if (ctnList.Count > 0)
showBKOrder.ctnInputs = ctnList.Adapt<List<BookingCtnDto>>();
result.ext2 = showBKOrder;
}
}
2 years ago
}
catch (Exception ex)
{
result.succ = false;
2 years ago
result.msg = $"获取BC详情异常原因{ex.Message}";
2 years ago
}
return result;
}
#endregion
#region 通过任务主键获取BC详情
/// <summary>
/// 通过任务主键获取BC详情
/// </summary>
/// <param name="taskPkId">BC任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/GetInfoByTaskId")]
public async Task<TaskManageOrderResultDto> GetInfoByTaskId(string taskPkId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
if (taskBase == null)
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
if (bcOrder == null)
throw Oops.Oh($"任务主键{taskPkId}无法获取BC业务信息");
var bcCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == bcOrder.PK_ID).ToList();
TaskBCShowBaseDto model = bcOrder.Adapt<TaskBCShowBaseDto>();
if (bcCtnList.Count > 0)
model.CtnList = bcCtnList.Adapt<List<TaskBCCTNInfoDto>>();
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList();
if (fileList.Count > 0)
model.FileList = fileList.Adapt<List<TaskFileDto>>();
11 months ago
model.taskStatus = taskBase.STATUS;
11 months ago
//生成关键信息
#region 生成关键信息
model.Keywords = new List<TaskBCShowBaseKeywordDto>();
if(bcOrder.CARRIAGE_TYPE == "DIRECT_SHIP")
{
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#FFFF80",Icon= "icon-yunshu1" });
}
else if (bcOrder.CARRIAGE_TYPE == "TRANSFER_SHIP")
{
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#CAF982", Icon = "icon-shuaxin" });
}
if (bcOrder.BOOKING_SLOT_TYPE == "CONTRACT_ORDER")
{
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#81D3F8", Icon = "icon-touzijilu" });
}
else if (bcOrder.BOOKING_SLOT_TYPE == "SPOT_ORDER")
{
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#FACD91", Icon = "icon-beizhu1" });
}
#endregion
2 years ago
2 years ago
result.succ = true;
result.ext = model;
2 years ago
//如果当前BC有对应记录则读取订舱详情
if (bcOrder.BOOKING_ORDER_ID.HasValue)
{
var bkOrder = await _bookingOrderRepository.AsQueryable().
FirstAsync(a => a.Id == bcOrder.BOOKING_ORDER_ID.Value);
if(bkOrder != null)
{
var showBKOrder = bkOrder.Adapt<BookingOrderOutput>();
var ctnList = await _bookingCtnRepository.AsQueryable().
Where(a => a.BILLID == bkOrder.Id).ToListAsync();
2 years ago
if (ctnList.Count > 0)
showBKOrder.ctnInputs = ctnList.Adapt<List<BookingCtnDto>>();
result.ext2 = showBKOrder;
}
}
2 years ago
}
catch (Exception ex)
{
result.succ = false;
2 years ago
result.msg = $"获取BC详情异常原因{ex.Message}";
2 years ago
}
return result;
}
#endregion
2 years ago
11 months ago
#region 获取待处理的BC任务
2 years ago
/// <summary>
/// 获取待处理的BC任务来自邮件解析需要对应订舱系统会根据用户的订舱台账预配
/// </summary>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/GetToDoBCList")]
2 years ago
public async Task<TaskManageOrderResultDto> GetToDoBCList()
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
/*
1
2
*/
try
{
Dictionary<string, List<BookingOrder>> toDoListDict = new Dictionary<string, List<BookingOrder>>();
2 years ago
//获取所有待处理的BC任务
var taskList = await _taskBCInfoRepository.AsQueryable().InnerJoin<TaskBaseInfo>((a,b)=>a.TASK_ID == b.PK_ID)
2 years ago
.Where((a, b)=> !a.BOOKING_ORDER_ID.HasValue && b.STATUS == TaskStatusEnum.Create.ToString())
.Select((a,b)=>new { BC = a,TSK = b }).ToListAsync();
if (taskList.Count > 0)
{
taskList.ForEach(async tsk =>
{
var curList = await _bookingOrderRepository.AsQueryable()
.Where(a => a.VESSEL.Contains(tsk.BC.VESSEL) && a.VOYNO.Contains(tsk.BC.VOYNO) || a.MBLNO.Contains(tsk.BC.MBL_NO)
).ToListAsync();
if (curList.Count > 0)
{
toDoListDict.Add(tsk.BC.PK_ID, curList);
}
else
{
toDoListDict.Add(tsk.BC.PK_ID, new List<BookingOrder>());
}
});
}
//这里最后清洗一下对应的订舱数据,只保留一条符合的数据
if (toDoListDict.Count > 0)
{
List<Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>> tupList = new List<Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>>();
int num = 1;
int odNum = 1;
foreach (var kvp in toDoListDict)
{
var bcInfo = taskList.FirstOrDefault(a => a.BC.PK_ID == kvp.Key).BC.Adapt<TaskBCInfoDto>();
bcInfo.Indx = num;
if (kvp.Value.Count > 0)
{
var bookingOrder = kvp.Value.Select(a =>
{
if (a.MBLNO.Equals(bcInfo.MBLNo, StringComparison.OrdinalIgnoreCase))
{
return new { Sort = 90, OBJ = a };
}
else if (a.VESSEL.Equals(bcInfo.Vessel, StringComparison.OrdinalIgnoreCase)
&& a.VOYNO.Equals(bcInfo.VoyNo, StringComparison.OrdinalIgnoreCase))
{
return new { Sort = 80, OBJ = a };
}
return new { Sort = 1, OBJ = a };
}).OrderByDescending(a => a.Sort).FirstOrDefault().OBJ.Adapt<BookingOrderBCTaskDto>();
bookingOrder.Indx = odNum;
bookingOrder.BCIndx = num;
bcInfo.BKOrderIndx = odNum;
odNum++;
tupList.Add(new Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>(
bcInfo,
bookingOrder
));
}
else
{
tupList.Add(new Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>(
bcInfo,
null
));
}
num++;
}
result.ext = tupList.Select(a=>a.Item1).ToList();
result.ext2 = tupList.Select(a => a.Item2).ToList();
2 years ago
}
result.succ = true;
2 years ago
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"获取派车详情异常,原因:{ex.Message}";
}
return result;
}
11 months ago
#endregion
2 years ago
11 months ago
#region 任务ID下载附件
2 years ago
/// <summary>
/// 任务ID下载附件
/// </summary>
/// <param name="taskPKId">BC任务主键</param>
11 months ago
/// <param name="fileCategory">附件分类代码</param>
2 years ago
/// <returns>返回数据流</returns>
[HttpGet("/TaskManageBC/DownloadFile")]
11 months ago
public async Task<IActionResult> DownloadFile([FromQuery] string taskPKId, [FromQuery] string fileCategory = "BC")
2 years ago
{
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
if (bcTaskInfo == null)
{
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
}
11 months ago
TaskFileCategoryEnum fileCategoryEnum = TaskFileCategoryEnum.NONE;
System.Enum.TryParse(fileCategory, out fileCategoryEnum);
if (fileCategoryEnum == TaskFileCategoryEnum.NONE)
{
throw Oops.Oh($"附件分类代码错误,请提供正确的分类代码");
}
string name = fileCategoryEnum.ToString();
var fileInfo = await _taskFileRepository.AsQueryable().FirstAsync(u => u.TASK_PKID == taskPKId && u.FILE_CATEGORY == name);
2 years ago
if (fileInfo == null)
{
throw Oops.Oh($"任务主键{taskPKId}没有可下载的附件");
}
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH);
if (!File.Exists(fileFullPath))
{
throw Oops.Oh($"任务主键{taskPKId} 附件下载请求失败,请确认文件是否存在");
}
var fileName = HttpUtility.UrlEncode(fileInfo.FILE_NAME, Encoding.GetEncoding("UTF-8"));
var result = new FileStreamResult(new FileStream(fileFullPath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
return result;
}
11 months ago
#endregion
11 months ago
#region 检索订舱信息
/// <summary>
/// 检索订舱信息
/// </summary>
/// <param name="query">检索条件</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageBC/QueryBookingOrderList")]
public async Task<TaskManageOrderResultDto> QueryBookingOrderList([FromBody] BookingOrderBCQuery query)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
bool isAvailable = false;
var queryWhere = _bookingOrderRepository.AsQueryable();
#region 查询条件
if (query.beginETD.HasValue || query.endETD.HasValue)
{
/*
7
*/
DateTime beginDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
DateTime endDate = beginDate;
if (query.beginETD.HasValue)
beginDate = query.beginETD.Value;
if (query.endETD.HasValue)
endDate = query.endETD.Value;
if (endDate > beginDate.AddDays(7))
throw Oops.Oh($"船期的日期范围不能超过7天");
endDate = endDate.AddDays(1);
queryWhere = queryWhere.Where(a => a.ETD >= beginDate && a.ETD < endDate);
isAvailable = true;
}
if (query.beginCreated.HasValue || query.endCreated.HasValue)
{
/*
7
*/
DateTime beginDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
DateTime endDate = beginDate;
if (query.beginCreated.HasValue)
beginDate = query.beginCreated.Value;
if (query.endCreated.HasValue)
endDate = query.endCreated.Value;
if (endDate > beginDate.AddDays(7))
throw Oops.Oh($"制单的日期范围不能超过7天");
endDate = endDate.AddDays(1);
queryWhere = queryWhere.Where(a => a.CreatedTime >= beginDate && a.CreatedTime < endDate);
isAvailable = true;
}
if (!string.IsNullOrWhiteSpace(query.mblNo))
{
queryWhere = queryWhere.Where(a => a.MBLNO.Contains(query.mblNo));
isAvailable = true;
}
if (!string.IsNullOrWhiteSpace(query.custNo))
{
queryWhere = queryWhere.Where(a => a.CUSTNO.Contains(query.custNo));
isAvailable = true;
}
if (!string.IsNullOrWhiteSpace(query.vessel))
{
queryWhere = queryWhere.Where(a => a.VESSEL.Contains(query.vessel));
isAvailable = true;
}
if (!string.IsNullOrWhiteSpace(query.voyno))
{
queryWhere = queryWhere.Where(a => a.VOYNO.Contains(query.voyno));
isAvailable = true;
}
#endregion
if (!isAvailable)
throw Oops.Oh($"查询条件不能为空");
var list = await queryWhere.OrderBy(a => a.CreatedTime)
.Take(query.topNum).ToListAsync();
var bkList = list.Adapt<List<BookingOrderBCTaskDto>>();
result.succ = true;
result.ext = bkList;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"查询失败,原因:{ex.Message}";
}
return result;
}
11 months ago
#endregion
11 months ago
#region 转移任务(将任务指定给其他人)
/// <summary>
/// 转移任务(将任务指定给其他人)
/// </summary>
/// <param name="taskPKId">BC任务主键</param>
/// <param name="userId">用户ID</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/TransferTask")]
public async Task<TaskManageOrderResultDto> TransferTask([FromQuery] string taskPKId, [FromQuery] long userId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
11 months ago
/*
1
*/
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
if (bcTaskInfo == null)
{
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
}
if(userId < 0)
throw Oops.Oh($"指定用户ID不能为空");
var targetUserId = _sysUserRepository.AsQueryable().First(u => u.Id == userId);
if (targetUserId == null)
throw Oops.Oh($"指定用户不存在");
if (bcTaskInfo.IS_PUBLIC == 1)
{
bcTaskInfo.IS_PUBLIC = 0;
bcTaskInfo.CreatedUserId = targetUserId.Id;
bcTaskInfo.CreatedUserName = targetUserId.Name;
11 months ago
11 months ago
bcTaskInfo.UpdatedTime = DateTime.Now;
bcTaskInfo.UpdatedUserId = targetUserId.Id;
bcTaskInfo.UpdatedUserName = targetUserId.Name;
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
{
it.TenantId,
it.CreatedTime,
it.IsDeleted,
it.TASK_NO,
it.TASK_TYPE,
it.TASK_SOURCE
}).ExecuteCommandAsync();
}
else
{
bcTaskInfo.CreatedUserId = targetUserId.Id;
bcTaskInfo.CreatedUserName = targetUserId.Name;
bcTaskInfo.UpdatedTime = DateTime.Now;
bcTaskInfo.UpdatedUserId = targetUserId.Id;
bcTaskInfo.UpdatedUserName = targetUserId.Name;
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
{
it.TenantId,
it.CreatedTime,
it.IsDeleted,
it.TASK_NO,
it.TASK_TYPE,
it.TASK_SOURCE
}).ExecuteCommandAsync();
}
result.succ = true;
result.msg = "成功";
11 months ago
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"转移任务失败,原因:{ex.Message}";
}
return result;
}
#endregion
#region 生成订舱或舱位
/// <summary>
/// 生成订舱或舱位
/// </summary>
/// <param name="model">生成订舱或者舱位请求</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageBC/CreateBookingAndSlot")]
public async Task<TaskManageOrderResultDto> CreateBookingAndSlot([FromBody] BookingOrSlotGenerateDto model)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
11 months ago
/*
1GEN_BOOKING_SLOT-
1
2
3
4BC
2GEN_BOOKING-
1
4BC
3GEN_SLOT-
1
4BC
3GEN_SLOT-
1
3
4BC
11 months ago
*/
if (string.IsNullOrWhiteSpace(model.BCTaskId))
11 months ago
throw Oops.Oh($"BC任务主键不能为空");
//生成方式GEN_BOOKING_SLOT-生成舱位和订舱;GEN_BOOKING-只生成订舱GEN_SLOT-只生成舱位GEN_EXIST_BOOKING-匹配指定的订舱)
if (string.IsNullOrWhiteSpace(model.GenerateMethod))
throw Oops.Oh($"生成方式不能为空,需要指定一种生成方式");
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == model.BCTaskId);
if (bcTaskInfo == null)
{
throw Oops.Oh($"任务主键{model.BCTaskId}无法获取业务信息");
}
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == bcTaskInfo.PK_ID);
if (bcOrder == null)
throw Oops.Oh($"任务主键{model.BCTaskId}无法获取BC业务信息");
var bcCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == bcOrder.PK_ID).ToList();
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcTaskInfo.PK_ID).ToList();
if (bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value > 0)
11 months ago
{
throw Oops.Oh($"当前BC任务已生成订舱或舱位不能重复生成");
}
if (model.GenerateMethod == "GEN_BOOKING_SLOT")
{
11 months ago
#region 推送舱位、推送订舱
//推送舱位
11 months ago
long bookingSlotId = 0;
if(bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0)
{
bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
}
else
{
bookingSlotId = await GenerateBookingSlot(bcOrder, bcCtnList, fileList);
}
11 months ago
if (bookingSlotId > 0)
11 months ago
{
//推送订舱
var bookingOrderId = await GenerateBookingOrder(bcOrder, bcCtnList, fileList, model);
11 months ago
if (bookingOrderId > 0)
11 months ago
{
11 months ago
//更新库存
11 months ago
//_bookingSlotService.
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
if (bcEntity != null)
11 months ago
{
if (bookingOrderId > 0)
bcEntity.BOOKING_ORDER_ID = bookingOrderId;
11 months ago
if (bookingSlotId > 0)
bcEntity.BOOKING_SLOT_ID = bookingSlotId;
11 months ago
bcEntity.UpdatedTime = DateTime.Now;
bcEntity.UpdatedUserId = UserManager.UserId;
bcEntity.UpdatedUserName = UserManager.Name;
11 months ago
_taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
11 months ago
{
it.BOOKING_ORDER_ID,
it.BOOKING_SLOT_ID,
11 months ago
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
11 months ago
}).ExecuteCommand();
11 months ago
var currBCOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcEntity.PK_ID);
if (currBCOrder != null)
await GenerateSendEmail(currBCOrder);
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
if (taskEntity != null && taskEntity.IS_PUBLIC == 1)
{
taskEntity.IS_PUBLIC = 0;
taskEntity.CreatedUserId = UserManager.UserId;
taskEntity.CreatedUserName = UserManager.Name;
taskEntity.UpdatedTime = DateTime.Now;
taskEntity.UpdatedUserId = UserManager.UserId;
taskEntity.UpdatedUserName = UserManager.Name;
_taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
{
it.IS_PUBLIC,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.CreatedUserId,
it.CreatedUserName
}).ExecuteCommand();
}
11 months ago
}
}
}
else
{
throw Oops.Oh($"生成舱位失败,舱位已存在");
}
11 months ago
#endregion
}
else if (model.GenerateMethod == "GEN_BOOKING")
{
#region 推送订舱
//推送订舱
var bookingOrderId = GenerateBookingOrder(bcOrder, bcCtnList, fileList, model).GetAwaiter().GetResult();
11 months ago
if (bookingOrderId > 0)
{
//异步推送邮件
await GenerateSendEmail(bcOrder);
11 months ago
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcTaskInfo.PK_ID);
if (bcEntity != null)
{
if (bookingOrderId > 0)
bcEntity.BOOKING_ORDER_ID = bookingOrderId;
bcEntity.UpdatedTime = DateTime.Now;
bcEntity.UpdatedUserId = UserManager.UserId;
bcEntity.UpdatedUserName = UserManager.Name;
_taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
{
it.BOOKING_ORDER_ID,
it.BOOKING_SLOT_ID,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommand();
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
if (taskEntity != null && taskEntity.IS_PUBLIC == 1)
{
taskEntity.IS_PUBLIC = 0;
taskEntity.CreatedUserId = UserManager.UserId;
taskEntity.CreatedUserName = UserManager.Name;
taskEntity.UpdatedTime = DateTime.Now;
taskEntity.UpdatedUserId = UserManager.UserId;
taskEntity.UpdatedUserName = UserManager.Name;
_taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
{
it.IS_PUBLIC,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.CreatedUserId,
it.CreatedUserName
}).ExecuteCommand();
}
}
}
#endregion
}
else if (model.GenerateMethod == "GEN_BOOKING_SLOT")
{
#region 推送舱位
//推送舱位
var bookingSlotId = GenerateBookingSlot(bcOrder, bcCtnList, fileList).GetAwaiter().GetResult();
if (bookingSlotId > 0)
{
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcTaskInfo.PK_ID);
if (bcEntity != null)
{
if (bookingSlotId > 0)
bcEntity.BOOKING_SLOT_ID = bookingSlotId;
bcEntity.UpdatedTime = DateTime.Now;
bcEntity.UpdatedUserId = UserManager.UserId;
bcEntity.UpdatedUserName = UserManager.Name;
_taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
{
it.BOOKING_ORDER_ID,
it.BOOKING_SLOT_ID,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommand();
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
if (taskEntity != null && taskEntity.IS_PUBLIC == 1)
{
taskEntity.IS_PUBLIC = 0;
taskEntity.CreatedUserId = UserManager.UserId;
taskEntity.CreatedUserName = UserManager.Name;
taskEntity.UpdatedTime = DateTime.Now;
taskEntity.UpdatedUserId = UserManager.UserId;
taskEntity.UpdatedUserName = UserManager.Name;
_taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
{
it.IS_PUBLIC,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName,
it.CreatedUserId,
it.CreatedUserName
}).ExecuteCommand();
}
}
}
#endregion
}
11 months ago
11 months ago
result.succ = true;
result.msg = "成功";
11 months ago
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"生成订舱或舱位失败,原因:{ex.Message}";
}
return result;
}
#endregion
#region 生成舱位
/// <summary>
/// 生成舱位
/// </summary>
/// <param name="taskBCInfo">BC任务详情</param>
/// <param name="taskBCCtnList">BC任务集装箱列表</param>
/// <param name="taskFileList">BC任务附件列表</param>
/// <returns>返回舱位ID</returns>
private async Task<long> GenerateBookingSlot(TaskBCInfo taskBCInfo, List<TaskBCCTNInfo> taskBCCtnList, List<TaskFileInfo> taskFileList)
{
long id = 0;
try
{
var carrierInfo = _cache.GetAllCodeCarrier().GetAwaiter().GetResult()
.Where(t => t.Code.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|| t.EnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|| t.CnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
BookingSlotBaseApiDto slotModel = new BookingSlotBaseApiDto
{
DataObj = new BookingSlotBaseApiSaveDto
{
CARRIERID = taskBCInfo.CARRIERID,
CARRIER = carrierInfo.CnName?.Trim(),
11 months ago
SLOT_BOOKING_NO = taskBCInfo.MBL_NO,
BOOKING_PARTY = taskBCInfo.BOOKING_PARTY,
BOOKING_SLOT_TYPE = taskBCInfo.BOOKING_SLOT_TYPE,
BOOKING_SLOT_TYPE_NAME = taskBCInfo.BOOKING_SLOT_TYPE_NAME,
VESSEL = taskBCInfo.VESSEL,
VOYNO = taskBCInfo.VOYNO,
VGM_SUBMISSION_CUT_DATE = taskBCInfo.VGM_CUTOFF_TIME,
WEEK_AT = taskBCInfo.WEEK_AT,
CARRIAGE_TYPE = taskBCInfo.CARRIAGE_TYPE,
CARRIAGE_TYPE_NAME = taskBCInfo.CARRIAGE_TYPE_NAME,
CONTRACT_NO = taskBCInfo.CONTRACTNO,
CTN_STAT = taskBCInfo.CTN_STAT,
CY_CUT_DATE = taskBCInfo.CY_CUTOFF_TIME,
DETENSION_FREE_DAYS = taskBCInfo.DETENSION_FREE_DAYS,
ETD = taskBCInfo.ETD,
ETA = taskBCInfo.ETA,
LANECODE = taskBCInfo.LANECODE,
LANENAME = taskBCInfo.LANENAME,
MANIFEST_CUT_DATE = taskBCInfo.MANIFEST_CUT_DATE,
MDGF_CUT_DATE = taskBCInfo.MDGF_CUT_DATE,
PLACEDELIVERY = taskBCInfo.PLACEDELIVERY,
PLACERECEIPT = taskBCInfo.PLACERECEIPT,
PORTDISCHARGE = taskBCInfo.PORTDISCHARGE,
PORTLOAD = taskBCInfo.PORTLOAD,
SI_CUT_DATE = taskBCInfo.SI_CUT_DATE,
TRANSFER_PORT_1 = taskBCInfo.TRANSFER_PORT_1,
TRANSFER_PORT_2 = taskBCInfo.TRANSFER_PORT_2,
CtnList = new List<BookingSlotCtnSaveInput>()
},
OpType = "add"
};
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
if (taskBCCtnList.Count > 0)
{
taskBCCtnList.ForEach(t =>
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput
{
CTNCODE = ctnCode?.Code,
CTNALL = t.CTNALL,
CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1
};
slotModel.DataObj.CtnList.Add(ctn);
});
}
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
DynameFileInfo dynameFile = null;
DynameFileInfo dynameNoticeFile = null;
if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString()))
{
var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString());
var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH);
11 months ago
dynameFile = new DynameFileInfo
11 months ago
{
FileBytes = File.ReadAllBytes(fileFullPath),
FileName = Path.GetFileName(fileFullPath)
};
}
if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC_NOTICE.ToString()))
{
var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString());
var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH);
dynameNoticeFile = new DynameFileInfo
{
FileBytes = File.ReadAllBytes(fileFullPath),
FileName = Path.GetFileName(fileFullPath)
};
}
11 months ago
id = await _bookingSlotService.InnerApiReceive(slotModel, dynameFile, dynameNoticeFile);
11 months ago
}
catch (Exception ex)
{
_logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成舱位异常,原因:{ex.Message}");
}
return id;
}
#endregion
#region 生成订舱
/// <summary>
/// 生成订舱
/// </summary>
/// <param name="taskBCInfo">BC任务详情</param>
/// <param name="taskBCCtnList">BC任务集装箱列表</param>
/// <param name="taskFileList">BC任务附件列表</param>
/// <param name="generateModel">订舱请求详情</param>
/// <returns>返回订舱ID</returns>
private async Task<long> GenerateBookingOrder(TaskBCInfo taskBCInfo, List<TaskBCCTNInfo> taskBCCtnList, List<TaskFileInfo> taskFileList,
BookingOrSlotGenerateDto generateModel)
{
long id = 0;
try
{
/*
1
2
3
*/
var carrierInfo = _cache.GetAllCodeCarrier().GetAwaiter().GetResult()
.Where(t => t.Code.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|| t.EnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|| t.CnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
SaveBookingOrderInput bkModel = new SaveBookingOrderInput
{
CUSTOMERID = generateModel.CustomerId,
CUSTOMERNAME = generateModel.CustomerName,
CARRIERID = carrierInfo.Code?.Trim(),
CARRIER = carrierInfo.CnName?.Trim(),
MBLNO = taskBCInfo.MBL_NO.ToUpper().Trim(),
CONTRACTNO = !string.IsNullOrWhiteSpace(taskBCInfo.CONTRACTNO) ? taskBCInfo.CONTRACTNO : "",
VESSEL = taskBCInfo.VESSEL.ToUpper().Trim(),
VOYNO = taskBCInfo.VOYNO.ToUpper().Trim(),
VOYNOINNER = taskBCInfo.VOYNO.ToUpper().Trim(),
ETD = taskBCInfo.ETD,
ETA = taskBCInfo.ETA,
SALEID = generateModel.SaleId.ToString(),
SALE = generateModel.SaleName,
OPID = generateModel.OpId.ToString(),
OP = generateModel.OpName,
DOCID = generateModel.DocId.ToString(),
DOC = generateModel.DocName,
ROUTEID = generateModel.RouteID.ToString(),
ROUTE = generateModel.Route,
CZRemark = generateModel.CZRemark,
ShenQingXiangShi = generateModel.ShenQingXiangShi,
LineManageID = generateModel.LineManageID.ToString(),
LineName = generateModel.LineManage,
CLOSEVGMDATE = taskBCInfo.VGM_CUTOFF_TIME,
CLOSINGDATE = taskBCInfo.CY_CUTOFF_TIME,
CLOSEDOCDATE = taskBCInfo.CUT_SINGLE_TIME,
ctnInputs = new List<BookingCtnDto>()
};
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
if (taskBCCtnList.Count > 0)
{
taskBCCtnList.ForEach(t =>
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
BookingCtnDto ctn = new BookingCtnDto
{
CTNCODE = ctnCode?.Code,
CTNALL = t.CTNALL,
CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1
};
bkModel.ctnInputs.Add(ctn);
});
}
var bkRlt = await _bookingOrderService.Save(bkModel);
id = bkRlt.Id;
11 months ago
string batchNo = IDGen.NextID().ToString();
11 months ago
if (id > 0)
{
if (generateModel.ProjectList != null && generateModel.ProjectList.Count > 0)
{
ModifyServiceProjectDto projectDto = new ModifyServiceProjectDto
{
BookingId = id,
ProjectCodes = generateModel.ProjectList.Distinct().ToArray(),
};
//写入服务项目
var prjRlt = await _bookingValueAddedService.SaveServiceProject(projectDto);
11 months ago
_logger.LogInformation($"推送订舱的服务项目完成 id={id} rlt={JSON.Serialize(prjRlt)}");
}
11 months ago
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
taskFileList.ForEach(file =>
{
11 months ago
if (file.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString())
{
var fileFullPath = Path.Combine(dirAbs, file.FILE_PATH);
if (File.Exists(fileFullPath))
{
//如果确认文件读取成功
var bookFilePath = FileAttachHelper.MoveFile(id.ToString(), fileFullPath, batchNo).GetAwaiter().GetResult();
//将格式单附件写入订舱的附件
SaveEDIFile(id, bookFilePath, new System.IO.FileInfo(bookFilePath).Name, taskBCInfo.TenantId.Value,
CONST_BC_FILE_CODE, CONST_BC_FILE_NAME).GetAwaiter();
}
}
else if (file.FILE_CATEGORY == TaskFileCategoryEnum.BC_NOTICE.ToString())
{
var fileFullPath = Path.Combine(dirAbs, file.FILE_PATH);
11 months ago
if (File.Exists(fileFullPath))
{
//如果确认文件读取成功
var bookFilePath = FileAttachHelper.MoveFile(id.ToString(), fileFullPath, batchNo, false, "bcnoticefile").GetAwaiter().GetResult();
//将格式单附件写入订舱的附件
SaveEDIFile(id, bookFilePath, new System.IO.FileInfo(bookFilePath).Name, taskBCInfo.TenantId.Value,
CONST_BC_NOTICE_FILE_CODE, CONST_BC_NOTICE_FILE_NAME).GetAwaiter();
}
}
});
}
_logger.LogInformation($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱成功 id={id}");
}
catch(Exception ex)
{
_logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱异常,原因:{ex.Message}");
}
return id;
}
#endregion
11 months ago
#region 取消任务
/// <summary>
/// 取消任务
/// </summary>
/// <param name="taskPKId">BC任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/CancelTask")]
public async Task<TaskManageOrderResultDto> CancelTask([FromQuery] string taskPKId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
11 months ago
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
if (bcTaskInfo == null)
{
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
}
bcTaskInfo.IsDeleted = true;
bcTaskInfo.UpdatedTime = DateTime.Now;
bcTaskInfo.UpdatedUserId = UserManager.UserId;
bcTaskInfo.UpdatedUserName = UserManager.Name;
11 months ago
11 months ago
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
{
it.TenantId,
it.CreatedTime,
it.CreatedUserId,
it.CreatedUserName,
it.IsDeleted,
it.TASK_NO,
it.TASK_TYPE,
it.TASK_SOURCE
}).ExecuteCommandAsync();
result.succ = true;
result.msg = "成功";
11 months ago
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"取消任务失败,原因:{ex.Message}";
}
return result;
}
#endregion
11 months ago
11 months ago
#region 获取服务项目列表
11 months ago
/// <summary>
/// 获取服务项目列表
/// </summary>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/GetProjectList")]
public async Task<List<ServiceProjectBaseDto>> GetProjectList()
{
List<ServiceProjectBaseDto> list = new List<ServiceProjectBaseDto>();
return await _serviceWorkFlowBaseService.GetEnableProjectList(UserManager.TENANT_ID.ToString());
}
11 months ago
#endregion
#region 异步写入附件表
/// <summary>
/// 异步写入附件表
/// </summary>
/// <param name="boookId">订舱ID</param>
/// <param name="FilePath">文件路径</param>
/// <param name="fileName">文件名</param>
/// <param name="tenantId">租户ID</param>
/// <param name="fileTypeCode">附件类型代码</param>
/// <param name="fileTypeName">附件类型名称</param>
/// <param name="moudle">附件模块代码</param>
/// <returns></returns>
[NonAction]
private async Task SaveEDIFile(long boookId, string FilePath, string fileName, long tenantId,
string fileTypeCode = "bc", string fileTypeName = "Booking Confirmation",string moudle = "BookingSlot")
{
/*
*/
//EDI文件
var bookFile = new BookingFile
{
Id = YitIdHelper.NextId(),
FileName = fileName,
FilePath = FilePath,
TypeCode = fileTypeCode,
TypeName = fileTypeName,
BookingId = boookId,
TenantId = tenantId,
Moudle = moudle
};
await _bookingFileRepository.InsertAsync(bookFile);
}
#endregion
11 months ago
#region 生成并推送邮件
/// <summary>
/// 生成并推送邮件
/// </summary>
/// <param name="taskBCInfo">BC任务详情</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> GenerateSendEmail(TaskBCInfo taskBCInfo)
11 months ago
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
1BCNotice
2OP
3BCNotice
4
5
*/
//读取订舱数据
var bookingOrderEntity = _bookingOrderRepository.AsQueryable()
.First(a => a.Id == taskBCInfo.BOOKING_ORDER_ID);
11 months ago
if (bookingOrderEntity == null)
11 months ago
{
throw Oops.Oh($"订舱详情获取失败,请确认订舱是否存在或已删除");
}
_logger.LogInformation($"获取订舱详情完成bookid={bookingOrderEntity.Id}");
if (!bookingOrderEntity.CUSTOMERID.HasValue || (bookingOrderEntity.CUSTOMERID.HasValue && bookingOrderEntity.CUSTOMERID.Value == 0))
11 months ago
{
throw Oops.Oh($"订舱的委托客户不能为空");
}
var djyCustomerInfo = _djyCustomerService.Detail(new GetDjyCustomerInput { Id = bookingOrderEntity.CUSTOMERID.Value })
.GetAwaiter().GetResult();
11 months ago
if (djyCustomerInfo == null)
11 months ago
{
throw Oops.Oh($"委托单位详情获取失败,请确认委托单位是否存在或已删除");
}
_logger.LogInformation($"获取委托单位详情完成djyCustomerId={djyCustomerInfo.Id}");
DjyCustomerContactOutput djyCustomerContactMan = null;
//TO 邮件接收人
string toEmail = string.Empty;
//订舱OP的邮箱
string opEmail = string.Empty;
if (djyCustomerInfo.Contacts != null && djyCustomerInfo.Contacts.Count > 0)
{
djyCustomerContactMan = djyCustomerInfo.Contacts.FirstOrDefault(a =>
a.Remark.Equals("BCNotice", StringComparison.OrdinalIgnoreCase));
}
if (djyCustomerContactMan == null)
{
throw Oops.Oh($"委托单位为配置对用备注是BCNotice的联系人请修改");
}
if (string.IsNullOrWhiteSpace(djyCustomerContactMan.Email))
{
throw Oops.Oh($"委托单位为配置对用备注是BCNotice的联系人请修改");
}
toEmail = djyCustomerContactMan.Email.Trim();
_logger.LogInformation($"委托单位为配置对用备注是BCNotice的联系人toEmail={toEmail}");
//获取操作OP的邮箱
if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID))
{
var opId = long.Parse(bookingOrderEntity.OPID);
var opUser = _sysUserRepository.AsQueryable().First(a => a.Id == opId);
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Email))
11 months ago
{
opEmail = opUser.Email.Trim();
11 months ago
_logger.LogInformation($"获取操作OP的邮箱opEmail={opEmail} id={opId} name={opUser.Name}");
}
}
11 months ago
//提取当前公共邮箱的配置
var publicMailAccount = _djyUserMailAccount.FirstOrDefault(x => x.ShowName.Contains("BCNotice")
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
if (string.IsNullOrWhiteSpace(djyCustomerContactMan.Email))
{
throw Oops.Oh($"提取公共邮箱配置失败请在用户邮箱账号管理增加配置显示名为BCNotice");
}
_logger.LogInformation($"提取当前公共邮箱的配置完成id={publicMailAccount.Id}");
string emailTitle = $"Booking Confirmation : {taskBCInfo.MBL_NO}";
string filePath = string.Empty;
//读取邮件模板并填充数据
string emailHtml = GenerateSendEmailHtml(taskBCInfo, UserManager.TENANT_NAME).GetAwaiter().GetResult();
_logger.LogInformation($"生成邮件BODY结果{emailHtml}");
var fileInfo = _bookingFileRepository.AsQueryable().Where(a => a.BookingId == bookingOrderEntity.Id && a.TypeCode.Contains("bc_notice"))
.OrderByDescending(a => a.CreatedTime).First();
if (fileInfo == null)
{
throw Oops.Oh($"提取订舱的Booking Confirmation Notice文件失败不能发送邮件");
}
11 months ago
_logger.LogInformation($"获取订舱附件地址,结果:{fileInfo.FilePath}");
11 months ago
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
filePath = Path.Combine(dirAbs, fileInfo.FilePath);
EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto
{
SendTo = toEmail,
CCTo = opEmail,
Title = emailTitle,
Body = emailHtml,
Account = publicMailAccount.MailAccount?.Trim(),
Password = publicMailAccount.Password?.Trim(),
Server = publicMailAccount.SmtpServer?.Trim(),
Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465,
UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true,
Attaches = new List<AttachesInfo>()
};
_logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}");
//推送邮件
var emailRlt = await PushEmail(emailApiUserDefinedDto, filePath);
_logger.LogInformation($"推送邮件完成,结果:{JSON.Serialize(emailRlt)}");
result.succ = true;
result.msg = "成功";
}
catch (Exception ex)
{
_logger.LogInformation($"推送邮件失败,异常:{ex.Message}");
result.succ = false;
result.msg = $"推送邮件失败,异常:{ex.Message}";
}
return result;
}
#endregion
#region 通过邮件模板生成HTML
/// <summary>
/// 通过邮件模板生成HTML
/// </summary>
/// <param name="taskBCInfo">BC任务详情</param>
/// <param name="tenantName">当前租户全称</param>
/// <returns>返回生成的HTML</returns>
public async Task<string> GenerateSendEmailHtml(TaskBCInfo taskBCInfo,string tenantName)
{
string result = string.Empty;
/*
1HTML
2maincontatr
3HTML
*/
try
{
string templatePath = App.Configuration["EmailTemplateFilePath"];
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
templatePath = $"{dirAbs}{templatePath}\\BCEmailTemplate.html";
string baseHtml = File.ReadAllText(templatePath);
if (string.IsNullOrWhiteSpace(baseHtml))
throw Oops.Oh($"读取邮件模板失败");
HtmlDocument html = new HtmlDocument();
html.LoadHtml(baseHtml);
HtmlNode baseTable = html.DocumentNode.SelectNodes("//table[@class='base-table']").FirstOrDefault();
if (baseTable == null)
throw Oops.Oh($"读取邮件模板格式错误定位base-table失败");
var baseTrList = baseTable.SelectNodes(".//tr");
foreach (var baseTr in baseTrList)
{
var tdList = baseTr.SelectNodes(".//td");
foreach (var baseTd in tdList)
{
if (baseTd.Attributes["class"].Value == "billno-val")
{
baseTd.InnerHtml = taskBCInfo.MBL_NO;
}
else if (baseTd.Attributes["class"].Value == "takebillno-val")
{
baseTd.InnerHtml = taskBCInfo.MBL_NO;
}
else if (baseTd.Attributes["class"].Value == "pol-val")
{
baseTd.InnerHtml = taskBCInfo.PLACERECEIPT;
}
else if (baseTd.Attributes["class"].Value == "pod-val")
{
baseTd.InnerHtml = taskBCInfo.PLACEDELIVERY;
}
else if (baseTd.Attributes["class"].Value == "ctn-val")
{
baseTd.InnerHtml = taskBCInfo.CTN_STAT;
}
else if (baseTd.Attributes["class"].Value == "etd-val")
{
if (taskBCInfo.ETD.HasValue)
{
baseTd.InnerHtml = taskBCInfo.ETD.Value.ToString("yyyy-MM-dd");
}
}
else if (baseTd.Attributes["class"].Value == "eta-val")
{
if (taskBCInfo.ETA.HasValue)
{
baseTd.InnerHtml = taskBCInfo.ETA.Value.ToString("yyyy-MM-dd");
}
}
}
}
var noreplyTr = html.DocumentNode.SelectNodes("//tr[@class='email-noreply']").FirstOrDefault();
if (noreplyTr != null)
{
var currTd = noreplyTr.SelectNodes(".//td").FirstOrDefault();
if(currTd != null)
{
var currPList = currTd.SelectNodes(".//p");
foreach (var baseP in currPList)
{
if (baseP.Attributes["class"].Value == "notice-comp-val")
{
baseP.InnerHtml = tenantName;
11 months ago
}
}
}
11 months ago
}
result = html.DocumentNode.OuterHtml;
11 months ago
}
catch (Exception ex)
{
_logger.LogInformation($"通过邮件模板生成HTML异常原因={ex.Message}");
11 months ago
throw ex;
11 months ago
}
return result;
}
#endregion
#region 推送邮件
/// <summary>
/// 推送邮件
/// </summary>
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
/// <param name="filePath">文件路径</param>
/// <returns>返回回执</returns>
private async Task<CommonWebApiResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto, string filePath)
{
CommonWebApiResult result = new CommonWebApiResult { succ = true };
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value;
if (emailUrl == null)
throw Oops.Bah("字典未配置 url_set->email_api_url 请联系管理员");
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
int SplitSize = 5242880;//5M分片长度
int index = 1; //序号 第几片
long StartPosition = 5242880 * (index - 1);
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
if (lastLens < 5242880)
{
SplitSize = (int)lastLens;
}
byte[] heByte = new byte[SplitSize];
file.Seek(StartPosition, SeekOrigin.Begin);
//第一个参数是 起始位置
file.Read(heByte, 0, SplitSize);
//第三个参数是 读取长度(剩余长度)
file.Close();
string base64Str = Convert.ToBase64String(heByte);
emailApiUserDefinedDto.Attaches.Add(new AttachesInfo
{
AttachName = Path.GetFileName(filePath),
AttachContent = base64Str
});
emailList.Add(emailApiUserDefinedDto);
string strJoin = System.IO.File.ReadAllText(filePath);
DateTime bDate = DateTime.Now;
HttpResponseMessage res = null;
try
{
res = await emailUrl.SetBody(emailList, "application/json").PostAsync();
}
catch (Exception ex)
{
_logger.LogInformation($"发送邮件异常:{ex.Message}");
}
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation($"邮件上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,{strJoin}");
_logger.LogInformation($"发送邮件返回:{JSON.Serialize(res)}");
if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
{
Success = false,
Message = string.Empty,
Code = -9999,
});
result.succ = respObj.Success;
result.msg = respObj.Message;
}
return result;
}
#endregion
11 months ago
#region 发送邮件
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="taskPKId">BC任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageBC/SendEmail")]
11 months ago
public async Task<TaskManageOrderResultDto> SendEmail(string taskPKId)
{
if (string.IsNullOrWhiteSpace(taskPKId))
throw Oops.Oh($"BC任务主键不能为空");
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
if (bcTaskInfo == null)
{
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
}
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == bcTaskInfo.PK_ID);
if (bcOrder == null)
throw Oops.Oh($"任务主键{taskPKId}无法获取BC业务信息");
return await GenerateSendEmail(bcOrder);
11 months ago
}
#endregion
2 years ago
}
/// <summary>
/// 自定义邮件
/// </summary>
public class EmailApiUserDefinedDto
{
/// <summary>
/// 接收邮箱
/// </summary>
public string SendTo { get; set; }
/// <summary>
/// 抄送
/// </summary>
public string CCTo { get; set; }
/// <summary>
/// 邮件标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 邮件正文
/// </summary>
public string Body { get; set; }
/// <summary>
/// 账号
/// </summary>
public string Account { get; set; }
/// <summary>
/// 密码(126邮箱需要在网站生成密文)
/// </summary>
public string Password { get; set; }
/// <summary>
/// SMTP服务器
/// </summary>
public string Server { get; set; }
/// <summary>
/// SMTP端口
/// </summary>
public int Port { get; set; }
/// <summary>
/// 发件SSL
/// </summary>
public bool UseSSL { get; set; }
/// <summary>
/// 附件
/// </summary>
public List<AttachesInfo> Attaches { get; set; }
}
2 years ago
}