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.

660 lines
28 KiB
C#

This file contains ambiguous Unicode characters!

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

using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Helpers;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.TaskPlat.Dtos;
using DS.WMS.Core.TaskPlat.Entity;
using DS.WMS.Core.TaskPlat.Interface;
using Mapster;
using Masuit.Tools.Systems;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
using System.Runtime.InteropServices;
namespace DS.WMS.Core.TaskPlat.Method
{
public class TaskManageService : ITaskManageService
{
private readonly ILogger<TaskManageService> _logger;
private readonly IUser user;
private readonly ISaasDbService saasDbService;
private readonly IServiceProvider serviceProvider;
private readonly IWebHostEnvironment environment;
public TaskManageService(ILogger<TaskManageService> logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IUser user,
IWebHostEnvironment environment)
{
_logger = logger;
this.saasDbService = saasDbService;
this.serviceProvider = serviceProvider;
this.user = user;
this.environment = environment;
}
public async Task<DataResult> InitTaskJob(TaskManageOrderMessageInfo info, IFormFile file = null, IFormFile modifyFile = null)
{
string batchNo = Guid.NewGuid().ToString();
try
{
_logger.LogInformation("批次={no} 接收到创建任务报文 报文={msg}", batchNo, JsonConvert.SerializeObject(info));
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.FirstAsync(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}");
_logger.LogInformation("批次={no} 接收到创建任务报文 结束查询任务 {msg}", batchNo, taskInfo == null ? "不存在" : "存在");
/*
只要任务最后一次处理任务的状态是已取消、已完成,就可以重入新的任务
*/
if (taskInfo != null && taskInfo.STATUS != TaskStatusEnum.Cancel.ToString() && taskInfo.STATUS != TaskStatusEnum.Complete.ToString())
{
_logger.LogInformation("批次={no} 状态已存在,不能重复创建任务 status={status}", batchNo, taskInfo.STATUS);
//throw new Exception($"状态已存在,不能重复创建任务");
}
//如果文件路径不为空 判断文件是否真实存在
if (!string.IsNullOrWhiteSpace(info.Main.FilePath) && !File.Exists(info.Main.FilePath))
{
throw new Exception(string.Format("{0}文件不存在", info.Main.FilePath));
}
//如果文件路径不为空 判断文件是否真实存在
if (!string.IsNullOrWhiteSpace(info.Main.ModifyFile) && !File.Exists(info.Main.ModifyFile))
{
throw new Exception(string.Format("{0}文件不存在", info.Main.ModifyFile));
}
taskInfo = new TaskBaseInfo
{
Id = SnowFlakeSingle.Instance.NextId(),
STATUS = TaskStatusEnum.Create.ToString(),
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(),
VESSEL_VOYNO = info.Main.VesselVoyno?.Trim(),
CONTA_INFO = info.Main.ContaInfo,
TASK_REQ_USERNAME = info.Main.TaskUserName,
YARD_NAME = info.Main.YardName,
ETD = info.Main.ETD,
CUSTOMER_ID = info.Main.CustomerId,
CUSTOMER_NAME = info.Main.CustomerName,
BATCH_STATIC = info.Main.BatchStatic,
DJYUserId = info.Head.DJYUserId,
};
long taskReqUserId = 0;
if (!string.IsNullOrWhiteSpace(info.Main.TaskUserId))
{
if (long.TryParse(info.Main.TaskUserId, out taskReqUserId))
{
taskInfo.TASK_REQ_USERID = taskReqUserId;
}
}
// 忽略
taskInfo.CreateBy = long.Parse(user.UserId);
taskInfo.CreateTime = DateTime.Now;
//taskInfo.CreatedUserId = userTendInfo.userId;
//taskInfo.CreatedUserName = userTendInfo.userName;
//taskInfo.TenantId = userTendInfo.tendId;
//taskInfo.TenantName = userTendInfo.tenantName;
if (info.Main.TaskType == TaskBaseTypeEnum.TRUCK_DISPATCH || info.Main.TaskType == TaskBaseTypeEnum.CAUTION_NOTICE)
{
taskInfo.IS_PUBLIC = 0;
}
else
{
taskInfo.IS_PUBLIC = 1;
}
_logger.LogInformation("批次={no} 获取登录人详情 userid={userid} UserId={UserId}", batchNo,
info.Main.RecvUserId,
user.UserId);
if (info.Main != null && info.Main.TruckInfo != null && info.Main.TruckInfo.NeedArriveTime.HasValue)
{
taskInfo.NeedArriveTime = info.Main.TruckInfo.NeedArriveTime;
}
await tenantDb.Insertable(taskInfo).ExecuteCommandAsync();
if (!string.IsNullOrWhiteSpace(info.Main.FilePath))
{
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "advisoryfiles";
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = Path.GetFileName(info.Main.FilePath),
FileType = Path.GetExtension(info.Main.FilePath).ToLower(),
FilePath = info.Main.FilePath,
FileCategory = fileCategory
});
}
else
{
if (file != null)
{
var bytes = file.ToByteArray();
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "advisoryfiles";
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
var fileFullName = await SaveFile(bytes,
batchNo,
GetFileType(file.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(fileFullName))
{
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = file.FileName,
FileType = Path.GetExtension(file.FileName).ToLower(),
FilePath = fileFullName,
FileCategory = fileCategory
});
}
}
}
if (!string.IsNullOrWhiteSpace(info.Main.ModifyFile))
{
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString();
if (info.Main.FileList == null)
info.Main.FileList = new List<TaskManageOrderFileInfo>();
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = Path.GetFileName(info.Main.ModifyFile),
FileType = Path.GetExtension(info.Main.ModifyFile).ToLower(),
FilePath = info.Main.FilePath,
FileCategory = fileCategory
});
}
else
{
if (modifyFile != null)
{
var bytes = modifyFile.ToByteArray();
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifynoticefiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftnoticefiles";
fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString();
}
var noExtensionFileName = Path.GetFileNameWithoutExtension(modifyFile.FileName);
var fileFullName = await SaveFile(bytes,
batchNo,
GetFileType(modifyFile.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(fileFullName))
{
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = modifyFile.FileName,
FileType = Path.GetExtension(modifyFile.FileName).ToLower(),
FilePath = fileFullName,
FileCategory = fileCategory
});
}
}
}
#region 附件
//附件
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
{
info.Main.FileList.ForEach(async file =>
{
var fileInfo = new TaskFileInfo();
fileInfo.Id = SnowFlakeSingle.Instance.NextId();
fileInfo.TASK_PKID = taskInfo.Id;
fileInfo.CreateBy = taskInfo.CreateBy;
fileInfo.CreateTime = taskInfo.CreateTime;
//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(file.FileCategory))
{
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
fileInfo.FILE_CATEGORY = TaskFileCategoryEnum.BC.ToString();
fileInfo.FILE_CATEGORY_NAME = TaskFileCategoryEnum.BC.GetDescription();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
fileInfo.FILE_CATEGORY = TaskFileCategoryEnum.BC_MODIFY.ToString();
fileInfo.FILE_CATEGORY_NAME = TaskFileCategoryEnum.BC_MODIFY.GetDescription();
}
}
else
{
TaskFileCategoryEnum fileCategoryEnum = TaskFileCategoryEnum.NONE;
System.Enum.TryParse(file.FileCategory, out fileCategoryEnum);
fileInfo.FILE_CATEGORY = fileCategoryEnum.ToString();
fileInfo.FILE_CATEGORY_NAME = fileCategoryEnum.GetDescription();
}
if (string.IsNullOrWhiteSpace(fileInfo.FILE_NAME))
{
var fileModel = new FileInfo(file.FilePath);
fileInfo.FILE_NAME = fileModel.Name;
fileInfo.FILE_TYPE = fileModel.Extension?.Replace(".", "");
}
await tenantDb.Insertable(fileInfo).ExecuteCommandAsync();
});
}
#endregion
#region 邮件
//邮件
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
{
info.Main.EmailList.ForEach(async email =>
{
var emailInfo = new TaskEmail();
emailInfo.Id = SnowFlakeSingle.Instance.NextId();
emailInfo.TASK_PKID = taskInfo.Id;
emailInfo.CreateTime = taskInfo.CreateTime;
emailInfo.CreateBy = taskInfo.CreateBy;
emailInfo.MAIL_PATH = email.MailPath;
await tenantDb.Insertable(emailInfo).ExecuteCommandAsync();
});
}
#endregion
#region BC 任务
if (info.Main.TaskType == TaskBaseTypeEnum.BC
|| info.Main.TaskType == TaskBaseTypeEnum.BC_MODIFY
|| info.Main.TaskType == TaskBaseTypeEnum.CANCELLATION)
{
//异步写入
var bcInfo = info.Main.BCInfo.Adapt<TaskBCInfo>();
bcInfo.Id = SnowFlakeSingle.Instance.NextId();
bcInfo.TASK_ID = taskInfo.Id;
bcInfo.CreateBy = taskInfo.CreateBy;
bcInfo.CreateTime = taskInfo.CreateTime;
if (info.Main.BCInfo.BookingSlotId.HasValue && info.Main.BCInfo.BookingSlotId.Value > 0)
bcInfo.BOOKING_SLOT_ID = info.Main.BCInfo.BookingSlotId.Value;
await tenantDb.Insertable(bcInfo).ExecuteCommandAsync();
//异步写入集装箱
var ctnList = info.Main.BCInfo.CtnList.Select(ctn =>
{
var bcCtnInfo = ctn.Adapt<TaskBCCTNInfo>();
bcCtnInfo.Id = SnowFlakeSingle.Instance.NextId();
bcCtnInfo.P_ID = bcInfo.Id;
bcInfo.CreateBy = taskInfo.CreateBy;
bcInfo.CreateTime = taskInfo.CreateTime;
return bcCtnInfo;
}).ToList();
await tenantDb.Insertable(ctnList).ExecuteCommandAsync();
/*
BC_MODIFY
1、检索对应舱位提取比对差异结果
2、检索舱位对应的订舱信息如果有则生成用户通知邮件
3、推送钉钉消息@操作人 通知收到变更
CANCELLATION
1、检索舱位对应的订舱信息如果有则生成用户通知邮件
2、推送钉钉消息@操作人 通知收到变更
*/
if (info.Main.TaskType == TaskBaseTypeEnum.BC)
{
//Dictionary<string, object> dataContext = new()
//{
// { nameof(TaskManageOrderMessageInfo), info },
//};
TaskFlowDataContext dataContext = new(nameof(TaskManageOrderMessageInfo), info);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType,info, taskInfo, dataContext);
}
else if (info.Main.TaskType == TaskBaseTypeEnum.CANCELLATION)
{
}
else if (info.Main.TaskType == TaskBaseTypeEnum.BC_MODIFY)
{
}
}
#endregion
var taskNo = await tenantDb.Queryable<TaskBaseInfo>().Where(a => a.Id == taskInfo.Id).Select(a => a.TASK_NO).FirstAsync();
//回写任务号
var result = new DataResult(ResultCode.Success, "新增任务成功", taskNo);
return await Task.FromResult(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "任务台:初始化任务的过程中发生未知异常,批次号={no}", batchNo);
return DataResult.Failed(ex.Message);
}
}
#region 私有方法
static object? GetNestedDynamicPropertyValue(dynamic obj, string propertyPath)
{
var properties = propertyPath.Split('.');
dynamic currentObj = obj;
foreach (var property in properties)
{
if (currentObj is IDictionary<string, object> dictionary)
{
if (dictionary.TryGetValue(property, out var value))
{
currentObj = value;
}
else
{
return null;
}
}
else
{
return null;
}
}
return currentObj;
}
/// <summary>
/// 保存文件并返回文件完整路径
/// </summary>
/// <param name="fileBytes">文件二进制流</param>
/// <param name="batchNo">批次号</param>
/// <param name="printFileType">文件类型</param>
/// <param name="attachFileType">附件类型 bcfiles-BC文件 sofile-订舱附件</param>
/// <returns>返回文件完整路径</returns>
private async Task<string> SaveFile(byte[] fileBytes, string batchNo,
PrintFileTypeEnum printFileType, string attachFileType = "sofiles")
{
var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
var relativePath = AppSetting.app(new string[] { "FileSettings", "RelativePath" });
if (!string.IsNullOrWhiteSpace(attachFileType))
relativePath += $"\\{attachFileType}";
string? dirAbs;
if (string.IsNullOrEmpty(basePath))
{
dirAbs = Path.Combine(environment.WebRootPath, relativePath);
}
else
{
dirAbs = Path.Combine(basePath, relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
var fileType = string.Empty;
if (printFileType == PrintFileTypeEnum.PDF)
{
fileType = ".pdf";
}
else if (printFileType == PrintFileTypeEnum.XLSX)
{
fileType = ".xlsx";
}
else if (printFileType == PrintFileTypeEnum.DOCX)
{
fileType = ".docx";
}
else if (printFileType == PrintFileTypeEnum.XLS)
{
fileType = ".xls";
}
else if (printFileType == PrintFileTypeEnum.DOC)
{
fileType = ".doc";
}
var id = SnowFlakeSingle.Instance.NextId();
var fileSaveName = $"{id}{fileType}".ToLower();
string fileRelaPath = Path.Combine(relativePath, fileSaveName).ToLower();
string fileAbsPath = Path.Combine(dirAbs, fileSaveName).ToLower();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
relativePath = relativePath.Replace("\\", "/");
fileRelaPath = fileRelaPath.Replace("\\", "/");
fileAbsPath = fileAbsPath.Replace("\\", "/");
}
_logger.LogInformation("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, fileRelaPath, RuntimeInformation.OSDescription);
await File.WriteAllBytesAsync(fileAbsPath, fileBytes);
string bookFilePath;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileAbsPath, relativePath.Replace("/", "\\/") + ".*").Value;
}
else
{
bookFilePath = System.Text.RegularExpressions.Regex.Match(fileAbsPath, relativePath.Replace("\\", "\\\\") + ".*").Value;
}
return bookFilePath;
}
/// <summary>
/// 获取文件类型
/// </summary>
/// <param name="fileName">文件完成路径</param>
/// <returns>返回文件类型枚举</returns>
private PrintFileTypeEnum GetFileType(string fileName)
{
PrintFileTypeEnum fileType = PrintFileTypeEnum.PDF;
switch (Path.GetExtension(fileName).ToLower())
{
case ".pdf":
fileType = PrintFileTypeEnum.PDF;
break;
case ".xlsx":
fileType = PrintFileTypeEnum.XLSX;
break;
case ".docx":
fileType = PrintFileTypeEnum.DOCX;
break;
case ".xls":
fileType = PrintFileTypeEnum.XLS;
break;
case ".doc":
fileType = PrintFileTypeEnum.DOC;
break;
}
return fileType;
}
#endregion
}
}