cjy 4 months ago
commit f8bfb41671

2
.gitignore vendored

@ -67,3 +67,5 @@ LinkAttach
/ds-wms-service/DS.WMS.AdminApi/Logs/internal-nlog.txt
/ds-wms-service/DS.WMS.ContainerManagementApi/Logs/internal-nlog.txt
/ds-wms-service/DS.WMS.OpApi/TempFiles/S24080044
/ds-wms-service/DS.WMS.TaskApi/TaskEmailTemplate
/ds-wms-service/DS.WMS.Core/TaskPlat.zip

@ -1491,6 +1491,11 @@ public static class MultiLanguageConst
public const string TaskAuditStatusError = "Task_Audit_Status_Error";
[Description("无法从配置中获取任务接收人,请联系管理员检查系统配置")]
public const string TaskReceiverNotFound = "Task_Receiver_Not_Found";
[Description("任务邮件必须设置收件人")]
public const string TaskMailReceiverNotNull = "Task_Mail_Receiver_Not_Null";
[Description("任务邮件必须设置发件人")]
public const string TaskMailSenderNotNull = "Task_Mail_Sender_Not_Null";
#endregion
#region 任务台相关

@ -40,5 +40,7 @@
/// 任务主表主键
/// </summary>
public const string TaskPkId = "taskPkId";
public const string BusinessTask = "BusinessTask";
}
}

@ -30,6 +30,6 @@ public abstract class BaseOrgModelV2<TKey> : BaseModelV2<TKey>, IOrgId
/// <summary>
/// 机构Id
/// </summary>
[SugarColumn(ColumnDescription = "机构Id")]
[SugarColumn(ColumnDescription = "机构Id", IsOnlyIgnoreUpdate = true)]
public long OrgId { get; set; }
}

@ -38,7 +38,7 @@ public class ClientContactRes
/// <summary>
/// 职务
/// </summary>
public string[]? Jobs => Job.IsNullOrEmpty() ? [] : Job.Split([','], StringSplitOptions.RemoveEmptyEntries);
public string[]? Jobs => Job.IsNullOrEmpty() ? [] : Job.Split(',', StringSplitOptions.RemoveEmptyEntries);
/// <summary>
/// Desc:通讯地址

@ -344,7 +344,7 @@ public class ClientInfoRes
/// 所属分部
/// </summary>
public long[] SaleOrgIdList => SaleOrgId.IsNullOrEmpty() ? [] :
SaleOrgId.Split([','], StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray();
SaleOrgId.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray();
/// <summary>
/// 所属分部名称

@ -381,6 +381,36 @@ namespace DS.WMS.Core.Op.Dtos
/// 计费日期
/// </summary>
public Nullable<DateTime> PriceCalculationDate { get; set; }
/// <summary>
/// 设置温度
/// </summary>
public string TemperatureSet { get; set; }
/// <summary>
/// 最低温度
/// </summary>
public string TemperatureMin { get; set; }
/// <summary>
/// 最高温度
/// </summary>
public string TemperatureMax { get; set; }
/// <summary>
/// Desc:湿度
/// </summary>
public string Humidity { get; set; }
/// <summary>
/// 卸货港
/// </summary>
public string DischargePort { get; set; }
/// <summary>
/// 目的地
/// </summary>
public string Destination { get; set; }
}
public class ParserBCCTNInfoDto

@ -0,0 +1,15 @@
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
namespace DS.WMS.Core.Op.Dtos.TaskInteraction
{
/// <summary>
/// 动作执行上下文
/// </summary>
public class ActionExecutionContext
{
public BusinessTask Task { get; set; }
}
}

@ -5,8 +5,8 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
/// <summary>
/// 任务邮件附件配置
/// </summary>
[SugarTable("business_task_mail_attachment", "任务邮件附件配置")]
public class BusinessTaskMailAttachment
[SugarTable("business_task_attachment", "任务邮件附件配置")]
public class BusinessTaskAttachment
{
/// <summary>
/// 任务邮件配置ID

@ -105,6 +105,12 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
/// 审核
/// </summary>
[Description("审核")]
Audit = 101
Audit = 101,
/// <summary>
/// 邮件服务
/// </summary>
[Description("邮件服务")]
Mail = 201
}
}

@ -8,7 +8,7 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
/// 任务邮件发送配置
/// </summary>
[SugarTable("business_task_mail", "任务邮件发送配置")]
public class BusinessTaskMail : BaseModelV2<long>
public class BusinessTaskMail : BaseOrgModelV2<long>
{
/// <summary>
/// 任务类型
@ -16,11 +16,11 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
[SugarColumn(ColumnDescription = "任务类型", IsNullable = false)]
public TaskBaseTypeEnum TaskType { get; set; }
/// <summary>
/// 任务状态
/// </summary>
[SugarColumn(ColumnDescription = "任务状态", IsNullable = false)]
public TaskStatusEnum TaskStatus { get; set; }
///// <summary>
///// 任务状态
///// </summary>
//[SugarColumn(ColumnDescription = "任务状态", IsNullable = false)]
//public TaskStatusEnum TaskStatus { get; set; } = TaskStatusEnum.Complete;
/// <summary>
/// 主题
@ -41,10 +41,16 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
public string? CustomerName { get; set; }
/// <summary>
/// 机构ID
/// 服务器设置ID
/// </summary>
[SugarColumn(ColumnDescription = "任务类型", IsNullable = false)]
public long ServerId { get; set; }
/// <summary>
/// 服务器设置
/// </summary>
[SugarColumn(ColumnDescription = "机构ID", IsNullable = false)]
public long OrgId { get; set; }
[Navigate(NavigateType.OneToOne, nameof(ServerId))]
public BusinessTaskMailServer? Server { get; set; }
/// <summary>
/// 接收人设置
@ -61,7 +67,7 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
/// <summary>
/// 附件设置
/// </summary>
[Navigate(NavigateType.OneToMany, nameof(BusinessTaskMailAttachment.TaskMailId))]
public List<BusinessTaskMailAttachment>? Attachments { get; set; }
[Navigate(NavigateType.OneToMany, nameof(BusinessTaskAttachment.TaskMailId))]
public List<BusinessTaskAttachment>? Attachments { get; set; }
}
}

@ -0,0 +1,42 @@
using DS.Module.Core.Data;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity.TaskInteraction
{
/// <summary>
/// 任务邮件服务器配置
/// </summary>
[SugarTable("business_task_mail_server", "任务邮件服务器配置")]
public class BusinessTaskMailServer : BaseOrgModelV2<long>
{
/// <summary>
/// 服务器地址
/// </summary>
[SugarColumn(ColumnDescription = "服务器地址", Length = 200, IsNullable = false)]
public string Server { get; set; } = string.Empty;
/// <summary>
/// 端口号
/// </summary>
[SugarColumn(ColumnDescription = "端口号")]
public int Port { get; set; }
/// <summary>
/// 使用SSL连接
/// </summary>
[SugarColumn(ColumnDescription = "使用SSL连接", DefaultValue = "1")]
public bool UseSSL { get; set; } = true;
/// <summary>
/// 登录账号
/// </summary>
[SugarColumn(ColumnDescription = "登录账号", Length = 200, IsNullable = true)]
public string? LoginName { get; set; }
/// <summary>
/// 登录密码
/// </summary>
[SugarColumn(ColumnDescription = "登录密码", Length = 200, IsNullable = true)]
public string? Password { get; set; }
}
}

@ -0,0 +1,17 @@
using DS.WMS.Core.Op.Dtos.TaskInteraction;
namespace DS.WMS.Core.Op.Interface.TaskInteraction
{
/// <summary>
/// 动作执行器
/// </summary>
public interface IActionExecutor
{
/// <summary>
/// 执行特定动作
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
Task ExecuteAsync(ActionExecutionContext context);
}
}

@ -0,0 +1,25 @@
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
namespace DS.WMS.Core.Op.Interface.TaskInteraction
{
/// <summary>
/// 动作执行管理
/// </summary>
public interface IActionManager
{
/// <summary>
/// 执行特定动作
/// </summary>
/// <param name="dataContext">数据上下文</param>
/// <returns></returns>
Task ExecuteAsync(TaskFlowDataContext dataContext);
/// <summary>
/// 触发任务执行动作
/// </summary>
/// <param name="businessTask">任务信息</param>
/// <returns></returns>
Task TriggerAction(BusinessTask businessTask);
}
}

@ -1,9 +1,40 @@
namespace DS.WMS.Core.Op.Interface.TaskInteraction
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
namespace DS.WMS.Core.Op.Interface.TaskInteraction
{
/// <summary>
/// 邮件配置服务定义
/// </summary>
public interface ITaskMailService
{
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<DataResult<List<BusinessTaskMail>>> GetListAsync(PageRequest request);
/// <summary>
/// 详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<DataResult<BusinessTaskMail>> GetAsync(long id);
/// <summary>
/// 编辑
/// </summary>
/// <param name="taskMail"></param>
/// <returns></returns>
Task<DataResult> EditAsync(BusinessTaskMail taskMail);
/// <summary>
/// 删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<DataResult> DeleteAsync(IdModel model);
}
}

@ -901,7 +901,8 @@ namespace DS.WMS.Core.Op.Method
PriceCalculationDate = taskBCInfoDto.PriceCalculationDate,
CtnList = new List<BookingSlotCtnSaveInput>()
},
OpType = messageInfo.Head.RequestAction?.ToLower()
OpType = messageInfo.Head.RequestAction?.ToLower(),
BatchNo = messageInfo.Main.TaskBatchNo
};
if (int.TryParse(taskBCInfoDto.WeekAt, out int week))
@ -917,7 +918,7 @@ namespace DS.WMS.Core.Op.Method
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.CtnName) && a.CtnName.Equals(t.CtnALL, StringComparison.OrdinalIgnoreCase));
t.CtnCode = ctnCode != null ? ctnCode.EdiCode : "(箱型未收录)";
t.CtnCode = ctnCode != null ? ctnCode.EdiCode : "";
}
BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput
@ -1222,10 +1223,10 @@ namespace DS.WMS.Core.Op.Method
}
else if (dto.OpType == "update")
{
model = await tenantDb.Queryable<BookingSlotBase>().FirstAsync(x => x.SlotBookingNo == dto.DataObj.SlotBookingNo);
model = tenantDb.Queryable<BookingSlotBase>().First(x => x.SlotBookingNo == dto.DataObj.SlotBookingNo);
if (model == null)
{
//throw Oops.Bah($"未找到订舱编号为 {dto.DataObj.SlotBookingNo} 的数据");
throw new Exception($"未找到订舱编号为 {dto.DataObj.SlotBookingNo} 的数据");
}
id = model.Id;
@ -1299,6 +1300,8 @@ namespace DS.WMS.Core.Op.Method
dto.DataObj.Adapt(model);
model.Id = id;
// 1.判断新的舱位信息的7个库存统计维度是否发生变化
// 2.如果有变化,则需要更新旧的库存信息
bool isNeedUpdateOldStock = false;
@ -1311,7 +1314,11 @@ namespace DS.WMS.Core.Op.Method
{
isNeedUpdateOldStock = true;
}
await tenantDb.Updateable<BookingSlotBase>(model).ExecuteCommandAsync();
await tenantDb.Updateable<BookingSlotBase>(model).IgnoreColumns(x=>new {
x.CreateBy,
x.CreateTime,
x.CreateUserName
}).ExecuteCommandAsync();
if (isNeedUpdateOldStock)
{
@ -1420,7 +1427,7 @@ namespace DS.WMS.Core.Op.Method
{
// 更新标志
var slotNO = dto.DataObj.SlotBookingNo;
model = await tenantDb.Queryable<BookingSlotBase>().FirstAsync(x => x.SlotBookingNo == slotNO);
model = tenantDb.Queryable<BookingSlotBase>().First(x => x.SlotBookingNo == slotNO);
if (model == null)
{
throw new Exception($"未找到订舱编号为 {slotNO} 的数据");

@ -1030,7 +1030,7 @@ public partial class SeaExportService : ISeaExportService
3
*/
var orderList = await tenantDb.Queryable<SeaExport>()
.Where(a => (a.MBLNO == mblNo || a.OrderNo == mblNo) && a.Deleted == false).ToListAsync();
.Where(a => (a.MBLNO == mblNo || a.OrderNo == mblNo) && a.Deleted == false && a.ParentId == 0).ToListAsync();
var currOrder = orderList.FirstOrDefault(a => a.MBLNO == mblNo);

@ -0,0 +1,45 @@
using DS.Module.Core;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
public class ActionExecutor : ServiceBase
{
//任务日志服务
//readonly ITaskLogService LogService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public ActionExecutor(IServiceProvider provider) : base(provider)
{
//LogService = provider.GetRequiredService<ITaskLogService>();
}
///// <summary>
///// 执行特定任务类型的邮件服务
///// </summary>
///// <param name="task">任务</param>
///// <returns></returns>
///// <exception cref="ArgumentNullException"><paramref name="task"/>为null</exception>
//public async Task<DataResult> ExecuteAsync(BusinessTask task)
//{
// ArgumentNullException.ThrowIfNull(task, nameof(task));
// var list = await TenantDb.Queryable<BusinessTaskMail>().Where(x => x.TaskType == task.TaskType && x.TaskStatus == task.TaskStatus)
// .Select(x => new
// {
// TemplateIds = x.Attachments.Select(x => x.TemplateId),
// x.Receiver,
// x.Sender,
// x.Title,
// x.Content
// }).ToListAsync();
//}
}
}

@ -0,0 +1,69 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.TaskPlat;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
/// <summary>
/// 动作执行管理
/// </summary>
public class ActionManager : ServiceBase, IActionManager
{
Dictionary<TaskActionType, IActionExecutor> ExecutorMappings;
/// <summary>
/// 初始化
/// </summary>
public ActionManager(IServiceProvider serviceProvider) : base(serviceProvider)
{
ExecutorMappings = new Dictionary<TaskActionType, IActionExecutor>();
ExecutorMappings[TaskActionType.Mail] = new MailActionExecutor();
}
/// <summary>
/// 触发任务执行动作
/// </summary>
/// <param name="businessTask">任务信息</param>
/// <returns></returns>
public async Task TriggerAction(BusinessTask businessTask)
{
ArgumentNullException.ThrowIfNull(businessTask, nameof(businessTask));
//目前只限制任务完成才触发
if (businessTask.TaskStatus != TaskStatusEnum.Complete)
return;
// 执行自动化操作
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.BusinessTask, businessTask)
);
TaskFlowRuner taskFlow = new(TenantDb, ServiceProvider);
await taskFlow.Run(businessTask.TaskType, businessTask.BusinessId, dataContext);
}
public async Task ExecuteAsync(TaskFlowDataContext dataContext)
{
ArgumentNullException.ThrowIfNull(dataContext, nameof(dataContext));
}
}
/// <summary>
/// 任务执行类型
/// </summary>
public enum TaskActionType
{
/// <summary>
/// 后台任务
/// </summary>
BackgroundWorker,
/// <summary>
/// 邮件
/// </summary>
Mail,
}
}

@ -0,0 +1,13 @@
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
public class MailActionExecutor : IActionExecutor
{
public Task ExecuteAsync(ActionExecutionContext context)
{
throw new NotImplementedException();
}
}
}

@ -199,7 +199,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (((JObject)result.data)["ext"] is not JArray extArray || extArray.Count == 0)
return [];
return extArray.Select(x => x["projectName"]?.Value<string>() ?? string.Empty).ToArray();
return extArray.Where(x => x["isYield"].Value<bool>()).Select(x => x["projectName"]?.Value<string>() ?? string.Empty).ToArray();
}
//public override async Task MarkerChangedAsync(MarkerChangedCallback callback)

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
@ -30,36 +31,87 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
.Where(whereList).ToQueryPageAsync(request.PageCondition);
}
///// <summary>
///// 编辑
///// </summary>
///// <param name="taskMail"></param>
///// <returns></returns>
//public async Task<DataResult> EditAsync(BusinessTaskMail taskMail)
//{
// try
// {
/// <summary>
/// 详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DataResult<BusinessTaskMail>> GetAsync(long id)
{
var entity = await TenantDb.Queryable<BusinessTaskMail>().Includes(x => x.Receiver).Includes(x => x.Sender)
.Where(x => x.Id == id).FirstAsync();
return DataResult<BusinessTaskMail>.Success(entity);
}
/// <summary>
/// 编辑
/// </summary>
/// <param name="taskMail"></param>
/// <returns></returns>
public async Task<DataResult> EditAsync(BusinessTaskMail taskMail)
{
await TenantDb.Ado.BeginTranAsync();
try
{
if (taskMail.Id == 0)
{
taskMail.Receiver ??= new();
taskMail.Sender ??= new();
// }
// catch (Exception ex)
// {
// await TenantDb.Ado.RollbackTranAsync();
// await ex.LogAsync(Db);
// return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
// }
taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteReturnEntityAsync();
}
else
{
await TenantDb.UpdateNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteCommandAsync();
}
// if (taskMail.Id == 0)
// {
// taskMail.Receiver ??= new();
// taskMail.Sender ??= new();
if (taskMail.Attachments?.Count > 0)
{
var list = taskMail.Attachments.FindAll(x => x.TaskMailId == 0);
foreach (var item in list)
item.TaskMailId = taskMail.Id;
await TenantDb.Deleteable<BusinessTaskAttachment>().Where(x => x.TaskMailId == taskMail.Id).ExecuteCommandAsync();
await TenantDb.Insertable(taskMail.Attachments).ExecuteCommandAsync();
}
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
/// <summary>
/// 删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<DataResult> DeleteAsync(IdModel model)
{
await TenantDb.Ado.BeginTranAsync();
try
{
await TenantDb.DeleteNav<BusinessTaskMail>(x => model.Ids.Contains(x.Id))
.Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Attachments).ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
// await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteCommandAsync();
// }
// else
// {
// }
//}
}
}

@ -12,6 +12,10 @@ namespace DS.WMS.Core
/// </summary>
public abstract class ServiceBase
{
/// <summary>
/// 获取服务容器
/// </summary>
protected IServiceProvider ServiceProvider { get; private set; }
/// <summary>
/// 获取用户相关信息
/// </summary>
@ -46,6 +50,7 @@ namespace DS.WMS.Core
/// <param name="serviceProvider">服务提供程序</param>
protected ServiceBase(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
User = serviceProvider.GetRequiredService<IUser>();
Db = serviceProvider.GetRequiredService<ISqlSugarClient>();
SaasService = serviceProvider.GetRequiredService<ISaasDbService>();

@ -306,6 +306,9 @@ namespace DS.WMS.Core.TaskPlat.Dtos
///// 单票账单的解析
///// </summary>
//public perbill perbillInfo { get; set; }
/// <summary>
/// 任务批次号
/// </summary>
public string TaskBatchNo { get; set; }
}
}

@ -6,8 +6,8 @@ namespace DS.WMS.Core.TaskPlat.Interface
public interface IMyModuleTest1
{
Task<DataResult> TestMethod11(TaskFlowDataContext dataContext);
Task<DataResult> TestMethod11();
DataResult TestMethod12(TaskFlowDataContext dataContext);
//Task<DataResult> TestMethod11();
Task<DataResult> TestMethod12(TaskFlowDataContext dataContext);
//public string G()
//{

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.DjyServiceStatus;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.TaskPlat.Dtos;
@ -34,5 +35,13 @@ namespace DS.WMS.Core.TaskPlat.Interface
/// <param name="taskPKId">BC任务主键</param>
/// <returns>返回回执</returns>
Task<DataResult> SyncBookingSlotChange(long taskPKId);
/// <summary>
/// 同步舱位变更(任务自动)
/// </summary>
/// <param name="dataContext">上下文</param>
/// <returns>返回回执</returns>
Task<DataResult> SyncBookingSlotChangeTask(TaskFlowDataContext dataContext);
}
}

@ -21,13 +21,14 @@ namespace DS.WMS.Core.TaskPlat.Method
return Task.FromResult(DataResult.Successed($"TestMethod11返回的成功结果address:{address}height:{height}bcInfoVessel:{bcInfoVessel}"));
}
public Task<DataResult> TestMethod11()
//public Task<DataResult> TestMethod11()
//{
// return Task.FromResult(DataResult.Successed($"TestMethod11返回的成功结果"));
//}
public Task<DataResult> TestMethod12(TaskFlowDataContext dataContext)
{
return Task.FromResult(DataResult.Successed($"TestMethod11返回的成功结果"));
}
public DataResult TestMethod12(TaskFlowDataContext dataContext)
{
throw new Exception("TestMethod12内的测试异常");
//throw new Exception("TestMethod12内的测试异常");
return Task.FromResult(DataResult.Successed($"TestMethod12返回的成功结果"));
}
}
}

@ -13,7 +13,8 @@ namespace DS.WMS.Core.TaskPlat.Method
{
public Task<DataResult> TestMethod21(TaskFlowDataContext dataContext)
{
throw new Exception("TestMethod21内的测试异常");
//throw new Exception("TestMethod21内的测试异常");
return Task.FromResult(DataResult.Successed($"TestMethod21返回的成功结果"));
}
}
}

@ -1,6 +1,7 @@
using Amazon.Runtime.Internal.Util;
using DS.Module.Core;
using DS.Module.Core.Constants;
using DS.Module.Core.Data;
using DS.Module.DjyServiceStatus;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
@ -37,7 +38,9 @@ using NPOI.XWPF.UserModel;
using SqlSugar;
using System;
using System.Security.Cryptography;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using DS.Module.Core.Helpers;
namespace DS.WMS.Core.TaskPlat.Method
{
@ -55,6 +58,7 @@ namespace DS.WMS.Core.TaskPlat.Method
private readonly IUserService _userService;
private readonly IUserEmailService _userEmailService;
private readonly IWebHostEnvironment _environment;
private readonly ISqlSugarClient db;
// 按需构建
private Lazy<IBookingSlotService> bookingSlotService;
@ -93,6 +97,8 @@ namespace DS.WMS.Core.TaskPlat.Method
_userEmailService = userEmailService;
_environment = environment;
db = serviceProvider.GetRequiredService<ISqlSugarClient>();
bookingSlotService = new Lazy<IBookingSlotService>(serviceProvider.GetRequiredService<IBookingSlotService>);
seaExportService = new Lazy<ISeaExportService>(serviceProvider.GetRequiredService<ISeaExportService>);
djyServiceStatusService = new Lazy<IDjyServiceStatusService>(serviceProvider.GetRequiredService<IDjyServiceStatusService>);
@ -257,7 +263,7 @@ namespace DS.WMS.Core.TaskPlat.Method
throw new Exception($"未获取有效任务记录,更新失败");
}
//var currBCOrder = await tenantDb.Queryable<TaskBaseInfo>().Where(a => a.Id == bcEntity.Id).FirstAsync();
//if (currBCOrder != null && model.IsDirectSend)
@ -1110,6 +1116,81 @@ namespace DS.WMS.Core.TaskPlat.Method
}
#endregion
/// <summary>
/// 对比BC与海运出口订单任务台使用
/// </summary>
public async Task<DataResult<TaskManageExcuteResultDto>> ExcuteCompareTask(TaskFlowDataContext dataContext)
{
try
{
var taskBcId = dataContext.Get<long?>(TaskFlowDataNameConst.TaskBCId);
if (taskBcId == null)
{
throw new ArgumentException($"缺少参数:{nameof(TaskFlowDataNameConst.TaskBCId)}");
}
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskBcInfo = await tenantDb.Queryable<TaskBCInfo>().Where(x => x.Id == taskBcId).FirstAsync();
if (taskBcInfo == null)
{
string msg = $"执行ExcuteCompareTask时根据未获取到BC信息";
logger.LogInformation(msg);
return DataResult<TaskManageExcuteResultDto>.Failed("对比失败:" + msg);
}
var taskBcCtnList = await tenantDb.Queryable<TaskBCCTNInfo>().Where(x => x.P_ID == taskBcInfo.Id).ToListAsync();
// 运费协议号(约号)是唯一的,服务合同号可能不是唯一的
// BC信息
ParserBCInfoDto bcSrcDto = new ParserBCInfoDto()
{
ContractNo = taskBcInfo.CONTRACTNO,
Vessel = taskBcInfo.VESSEL,
VoyNo = taskBcInfo.VOYNO,
//TemperatureMin = taskBcInfo
};
//bcTargetDto.CtnList = dto.DataObj.CtnList.GroupBy(x => x.CtnAll)
// .Select(x =>
// {
// return new ParserBCCTNInfoDto
// {
// CtnALL = x.Key,
// CtnNum = x.ToList().Sum(a => a.CtnNum)
// };
// }).ToList();
var seaExport = await tenantDb.Queryable<SeaExport>().Where(x => x.MBLNO == taskBcInfo.MBL_NO).FirstAsync();
// 订单信息
ParserBCInfoDto bcTargetDto = new ParserBCInfoDto()
{
ContractNo = seaExport.ContractNo,
Vessel = seaExport.Vessel,
VoyNo = seaExport.Voyno,
TemperatureMin = seaExport.TemperatureMin,
TemperatureMax = seaExport.TemperatureMax,
TemperatureSet = seaExport.TemperatureSet,
Humidity = seaExport.Humidity,
DischargePort = seaExport.DischargePort,
Destination = seaExport.Destination,
//CtnList = new List<ParserBCCTNInfoDto>(),
};
}
catch (Exception)
{
throw;
}
return default;
}
#region 生成并推送邮件
/// <summary>
@ -1120,7 +1201,9 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <param name="orderInfo">检索订舱相关</param>
/// <param name="usePersonalEmailSend">是否默认使用用户个人邮箱发送</param>
/// <returns>返回回执</returns>
private async Task<DataResult> GenerateSendEmail(TaskBCInfo taskBCInfo, TaskBaseInfo bcTaskInfo, SeaExportOrderExtension orderInfo, bool usePersonalEmailSend = false)
private async Task<DataResult> GenerateSendEmail(TaskBCInfo taskBCInfo, TaskBaseInfo bcTaskInfo, SeaExportOrderExtension orderInfo, SeaExport currSeaExportOrder,
bool saveBookingId = false,
bool usePersonalEmailSend = false)
{
bool result = false;
string msg = string.Empty;
@ -1153,10 +1236,26 @@ namespace DS.WMS.Core.TaskPlat.Method
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var bookingOrderEntity = orderInfo.currOrder;
var bookingOrderEntity = currSeaExportOrder;
Logger.Log(NLog.LogLevel.Info, $"获取订舱详情完成bookid={bookingOrderEntity.Id}");
if (saveBookingId && taskBCInfo.BOOKING_ORDER_ID != currSeaExportOrder.Id)
{
taskBCInfo.BOOKING_ORDER_ID = currSeaExportOrder.Id;
taskBCInfo.UpdateTime = DateTime.Now;
taskBCInfo.UpdateBy = long.Parse(user.UserId);
taskBCInfo.UpdateUserName = user.UserName;
await tenantDb.Updateable<TaskBCInfo>(taskBCInfo).UpdateColumns(x => new
{
x.BOOKING_ORDER_ID,
x.UpdateTime,
x.UpdateBy,
x.UpdateUserName
}).ExecuteCommandAsync();
}
if (bookingOrderEntity.CustomerId == 0)
{
throw new Exception($"订舱的委托客户不能为空");
@ -1180,7 +1279,7 @@ namespace DS.WMS.Core.TaskPlat.Method
string opEmail = string.Empty;
var bookingContactList = tenantDb.Queryable<BusinessOrderContact>()
.Where(a => a.BusinessId == taskBCInfo.BOOKING_ORDER_ID).ToList();
.Where(a => a.BusinessId == currSeaExportOrder.Id).ToList();
if (bookingContactList == null || bookingContactList.Count == 0)
{
@ -1265,8 +1364,15 @@ namespace DS.WMS.Core.TaskPlat.Method
}
else
{
fileInfo = tenantDb.Queryable<TaskFileInfo>().Where(a => a.TASK_PKID == taskBCInfo.TASK_ID && a.FILE_CATEGORY.Contains("BC_MODIFY_NOTICE"))
.OrderByDescending(a => a.CreateTime).First();
if (orderInfo.splitOrMergeFlag == 1)
{
//这里需要按照箱量重新修改变更附件
}
else
{
fileInfo = tenantDb.Queryable<TaskFileInfo>().Where(a => a.TASK_PKID == taskBCInfo.TASK_ID && a.FILE_CATEGORY.Contains("BC_MODIFY_NOTICE"))
.OrderByDescending(a => a.CreateTime).First();
}
}
}
@ -1541,7 +1647,7 @@ namespace DS.WMS.Core.TaskPlat.Method
if (string.IsNullOrEmpty(basePath))
{
dirAbs = Path.Combine(_environment.WebRootPath, relativePath);
dirAbs = Path.Combine(_environment.WebRootPath ?? "", relativePath);
}
else
{
@ -1815,11 +1921,11 @@ namespace DS.WMS.Core.TaskPlat.Method
private async Task<DataResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto, string filePath)
{
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
bool result = false;
string msg = string.Empty;
var emailUrl = "";
var emailUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "email_api_url" && x.TenantId == 1288018625843826688).First().Value;
if (emailUrl == null)
throw new Exception("字典未配置 url_set->email_api_url 请联系管理员");
@ -1854,10 +1960,13 @@ namespace DS.WMS.Core.TaskPlat.Method
DateTime bDate = DateTime.Now;
HttpResponseMessage res = null;
string res = string.Empty;
try
{
var jsonBody = JsonConvert.SerializeObject(emailList);
res = RequestHelper.Post(jsonBody, emailUrl);
//res = await emailUrl.SetBody(emailList, "application/json").PostAsync();
}
catch (Exception ex)
@ -1871,13 +1980,13 @@ namespace DS.WMS.Core.TaskPlat.Method
Logger.Log(NLog.LogLevel.Info, $"邮件上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,");
Logger.Log(NLog.LogLevel.Info, $"发送邮件返回:{JsonConvert.SerializeObject(res)}");
Logger.Log(NLog.LogLevel.Info, $"发送邮件返回:{res}");
if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
if (!string.IsNullOrWhiteSpace(res))
{
var userResult = await res.Content.ReadAsStringAsync();
//var userResult = await res.Content.ReadAsStringAsync();
var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
var respObj = JsonConvert.DeserializeAnonymousType(res, new
{
Success = false,
Message = string.Empty,
@ -1952,23 +2061,73 @@ namespace DS.WMS.Core.TaskPlat.Method
if (orderInfo != null && orderInfo.currOrder != null)
{
//更新订舱相关内容
if (paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
{
await GenerateSendEmail(taskBcInfo, taskBaseInfo, orderInfo);
//如果是拆票需要按照分票明细单个发送邮件
if (orderInfo.splitOrMergeFlag == 1)
{
var splitOrderIds = new List<long>();
splitOrderIds.Add(orderInfo.currOrder.Id);
splitOrderIds.Append(orderInfo.otherOrderList.Select(b => b.Id).ToList());
var bookList = tenantDb.Queryable<SeaExport>().Where(b => splitOrderIds.Contains(b.Id)).ToList();
foreach (var seaExportId in splitOrderIds)
{
var currSeaExport = bookList.FirstOrDefault(b => b.Id == seaExportId);
bool saveBookingId = currSeaExport.Id == orderInfo.currOrder.Id;
await GenerateSendEmail(taskBcInfo, taskBaseInfo, orderInfo, currSeaExport, saveBookingId);
}
}
else
{
var currSeaExport = tenantDb.Queryable<SeaExport>().First(b => b.Id == orderInfo.currOrder.Id);
//普通和合票都按单票处理
await GenerateSendEmail(taskBcInfo, taskBaseInfo, orderInfo, currSeaExport, true);
}
}
else
{
//这里没有取到订舱信息,终止,并发出邮件通知
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} mblno={taskBcInfo.MBL_NO} 当前租户未配置自动转发邮件");
}
}
else
{
//终止执行
//这里没有取到订舱信息,终止,并发出邮件通知
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} mblno={taskBcInfo.MBL_NO} 没有找到订单");
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"执行SyncBookingSlotChange时异常{ex.Message}");
return DataResult.Failed($"执行SyncBookingSlotChange时异常{ex.Message}");
}
return DataResult.Successed("");
return DataResult.Successed(MultiLanguageConst.DataCreateSuccess);
}
#endregion
/// <summary>
/// 同步舱位变更(任务自动)
/// </summary>
/// <param name="dataContext">上下文</param>
/// <returns>返回回执</returns>
public async Task<DataResult> SyncBookingSlotChangeTask(TaskFlowDataContext dataContext)
{
var taskBaseId = dataContext.Get<long?>(TaskFlowDataNameConst.TaskBaseId);
if (taskBaseId == null)
{
Logger.Log(NLog.LogLevel.Info, $"执行ApiReceiveTask时未获取到{TaskFlowDataNameConst.TaskBaseId}");
}
return await SyncBookingSlotChange(taskBaseId.Value);
}
}
}

@ -71,7 +71,7 @@ namespace DS.WMS.Core.TaskPlat.Method
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
TaskBaseInfo taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.OrderByDescending(a => a.Id)
.FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString());
if (taskInfo == null)
@ -121,7 +121,7 @@ namespace DS.WMS.Core.TaskPlat.Method
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
TaskBaseInfo taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.OrderByDescending(a => a.Id)
.FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString());
if (taskInfo == null)
@ -184,7 +184,7 @@ namespace DS.WMS.Core.TaskPlat.Method
{
var taskId = await tenantDb.Queryable<TaskBaseInfo>()
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString())
.OrderByDescending(a => a.CreateTime)
.OrderByDescending(a => a.Id)
.Select<long?>(t => t.Id)
.FirstAsync();
@ -254,7 +254,7 @@ namespace DS.WMS.Core.TaskPlat.Method
taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.Where(t => t.OUT_BS_NO == info.Head.BSNO)
.WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == info.Main.TaskType.ToString())
.OrderByDescending(a => a.CreateTime)
.OrderByDescending(a => a.Id)
.FirstAsync();
}
// 否则通过Head.GID进行判断
@ -263,7 +263,7 @@ namespace DS.WMS.Core.TaskPlat.Method
taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.Where(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}")
.WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == info.Main.TaskType.ToString())
.OrderByDescending(a => a.CreateTime)
.OrderByDescending(a => a.Id)
.FirstAsync();
}
@ -411,6 +411,11 @@ namespace DS.WMS.Core.TaskPlat.Method
taskInfo.NeedArriveTime = info.Main.TruckInfo.NeedArriveTime;
}
if(string.IsNullOrWhiteSpace(info.Main.TaskBatchNo))
{
info.Main.TaskBatchNo = SnowFlakeSingle.Instance.NextId().ToString();
}
await tenantDb.Insertable(taskInfo).ExecuteCommandAsync();
if (!string.IsNullOrWhiteSpace(info.Main.FilePath))
@ -873,6 +878,8 @@ namespace DS.WMS.Core.TaskPlat.Method
bcInfo.CreateBy = taskInfo.CreateBy;
bcInfo.CreateTime = taskInfo.CreateTime;
bcInfo.BATCH_NO = info.Main.TaskBatchNo;
if (info.Main.BCInfo.BookingSlotId.HasValue && info.Main.BCInfo.BookingSlotId.Value > 0)
bcInfo.BOOKING_SLOT_ID = info.Main.BCInfo.BookingSlotId.Value;
@ -891,7 +898,7 @@ namespace DS.WMS.Core.TaskPlat.Method
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.CtnName) && a.CtnName.Equals(bcCtnInfo.CTNALL, StringComparison.OrdinalIgnoreCase));
bcCtnInfo.CTNCODE = ctnCode != null ? ctnCode.EdiCode : "(箱型未收录)";
bcCtnInfo.CTNCODE = ctnCode != null ? ctnCode.EdiCode : "";
}
bcInfo.CreateBy = taskInfo.CreateBy;
@ -916,7 +923,8 @@ namespace DS.WMS.Core.TaskPlat.Method
(TaskFlowDataNameConst.TaskManageOrderMessageInfo, info),
(TaskFlowDataNameConst.TaskBCId, bcInfo.Id),
(TaskFlowDataNameConst.BCFile, file),
(TaskFlowDataNameConst.AmendmentFile, modifyFile)
(TaskFlowDataNameConst.AmendmentFile, modifyFile),
(TaskFlowDataNameConst.TaskBaseId, taskInfo.Id)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
@ -2151,13 +2159,12 @@ namespace DS.WMS.Core.TaskPlat.Method
//var b = user.GetOrgId();
//var b232 = user.OrgId;
// 任务匹配
if (LastMatchTaskTime < DateTime.Now.AddSeconds(-5)) // 效果距上一次全局任务匹配执行如果超过5秒才进行匹配
{
await MatchTask();
LastMatchTaskTime = DateTime.Now;
}
//if (LastMatchTaskTime < DateTime.Now.AddSeconds(-5)) // 效果距上一次全局任务匹配执行如果超过5秒才进行匹配
//{
//LastMatchTaskTime = DateTime.Now;
//}
await MatchTask();
//序列化查询条件
List<IConditionalModel>? whereList = null;

@ -31,6 +31,8 @@ namespace DS.WMS.Core.TaskPlat
this.serviceProvider = serviceProvider;
this.logger = serviceProvider.GetRequiredService<ILogger<TaskFlowRuner>>();
}
/// <summary>
/// 执行
/// </summary>
@ -199,17 +201,29 @@ namespace DS.WMS.Core.TaskPlat
};
// 执行流程
foreach (var configItem in configList)
long? nextExecuteConfigId = targetConfig.Id;
for (int i = 0; i < configList.Count; i++)
{
if (nextExecuteConfigId == null || nextExecuteConfigId == 0)
{
break;
}
var executeConfig = configList.FirstOrDefault(x => x.Id == nextExecuteConfigId);
if (executeConfig == null)
{
break;
}
nextExecuteConfigId = executeConfig.NextExecuteConfigId;
TaskFlowLogDetail flowLogDetail = new()
{
ConfigId = configItem.Id,
ConfigId = executeConfig.Id,
PId = flowLog.Id,
IsSuccess = true,
};
try
{
var paramItemList = paramList.Where(x => x.ConfigId == configItem.Id).ToList();
var paramItemList = paramList.Where(x => x.ConfigId == executeConfig.Id).ToList();
foreach (var paramItem in paramItemList)
{
dataContext.Set(paramItem.FieldName!, paramItem.FieldValue!);
@ -224,10 +238,10 @@ namespace DS.WMS.Core.TaskPlat
//}
}
var module = moduleList.FirstOrDefault(x => x.Id == configItem.ExecuteModuleId);
var module = moduleList.FirstOrDefault(x => x.Id == executeConfig.ExecuteModuleId);
if (module == null)
{
throw new Exception($"未找到指定流程配置ExecuteModuleId{configItem.ExecuteModuleId}");
throw new Exception($"未找到指定流程配置ExecuteModuleId{executeConfig.ExecuteModuleId}");
}
flowLogDetail.ModuleId = module.Id;
@ -319,7 +333,7 @@ namespace DS.WMS.Core.TaskPlat
flowLogDetail.ExceptionMessage = WriteLog("模块执行过程中发生异常", ex);
await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync();
if (configItem.IsExceptionContinue)
if (executeConfig.IsExceptionContinue)
{
continue;
}
@ -334,6 +348,22 @@ namespace DS.WMS.Core.TaskPlat
return (flowLog.Id, flowLog.IsComplete, flowLog.IsSuccess);
}
/// <summary>
/// 执行通过业务Id
/// </summary>
/// <param name="taskBaseType">任务类型</param>
/// <param name="bsno">业务Id</param>
/// <param name="dataContext">起始入参数据上下文</param>
/// <returns>(执行日志Id,模块是否全部执行完成,模块执行结果是否全部为success)</returns>
public async Task<(long? flowLogId, bool isAllComplete, bool isAllSuccess)> RunWithBsno(TaskBaseTypeEnum taskBaseType, long bsno, TaskFlowDataContext dataContext)
{
long taskId = await tenantDb.Queryable<TaskBaseInfo>()
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseType.ToString())
.OrderByDescending(a => a.Id)
.Select(t => t.Id)
.FirstAsync();
return await Run(taskBaseType, taskId, dataContext);
}
/// <summary>
/// 深度获取对象属性值

@ -1,6 +1,5 @@
using System.Net;
using DS.Module.Core;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Entity;

@ -0,0 +1,63 @@
using DS.Module.Core;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Microsoft.AspNetCore.Mvc;
namespace DS.WMS.OpApi.Controllers
{
/// <summary>
/// 任务邮件API
/// </summary>
public class TaskMailController : ApiController
{
readonly ITaskMailService service;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service"></param>
public TaskMailController(ITaskMailService service)
{
this.service = service;
}
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost, Route("GetList")]
public async Task<DataResult<List<BusinessTaskMail>>> GetListAsync(PageRequest request)
{
return await service.GetListAsync(request);
}
/// <summary>
/// 详情
/// </summary>
/// <param name="id">ID</param>
/// <returns></returns>
[HttpGet, Route("Edit")]
public async Task<DataResult<BusinessTaskMail>>GetAsync(long id)
{
return await service.GetAsync(id);
}
/// <summary>
/// 编辑
/// </summary>
/// <param name="taskMail">邮件配置</param>
/// <returns></returns>
[HttpPost, Route("Edit")]
public async Task<DataResult> EditAsync(BusinessTaskMail taskMail)
{
if (taskMail.Receiver == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskMailReceiverNotNull));
if (taskMail.Sender == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskMailSenderNotNull));
return await service.EditAsync(taskMail);
}
}
}
Loading…
Cancel
Save