zhangxiaofeng 4 months ago
commit b57dc1b1bf

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 任务台相关

@ -34,5 +34,13 @@
/// BC修改文件
/// </summary>
public const string AmendmentFile = "AmendmentFile";
/// <summary>
/// 任务主表主键
/// </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; }
}

@ -1,4 +1,5 @@
using DS.Module.Core;
using SqlSugar;
namespace DS.WMS.Core.Code.Dtos;
@ -19,8 +20,11 @@ public class CodeServiceSelectRes
/// 中文名称
/// </summary>
public string CnName { get; set; }
/// <summary>
/// EDI代码
/// </summary>
public string EdiCode { get; set; }
/// <summary>
/// 备注
/// </summary>

@ -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} 的数据");
@ -3450,7 +3457,7 @@ namespace DS.WMS.Core.Op.Method
// 判断是否启用了委托单位查看控制权限
bool isEnableCustomerAuthority = false;
if (paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrWhiteSpace(paramConfig) && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
{
isEnableCustomerAuthority = true;
}
@ -3784,7 +3791,7 @@ namespace DS.WMS.Core.Op.Method
// 判断是否启用了委托单位查看控制权限
bool isEnableCustomerAuthority = false;
if (paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrWhiteSpace(paramConfig) && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
{
isEnableCustomerAuthority = true;
}

@ -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; }
}
}

@ -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);
}
}

@ -38,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
{
@ -56,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;
@ -94,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>);
@ -1196,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;
@ -1229,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($"订舱的委托客户不能为空");
@ -1256,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)
{
@ -1269,7 +1292,10 @@ namespace DS.WMS.Core.TaskPlat.Method
if (bookingOrderEntity.OperatorId > 0)
{
var opId = bookingOrderEntity.OperatorId;
var opUser = _userService.GetUserInfo(opId.ToString()).Data;
var opUser = db.Queryable<SysUser>().Filter(null,true).First(x => x.Id == bookingOrderEntity.OperatorId && x.TenantId == long.Parse(user.TenantId));
//var opUser = _userService.GetUserInfo(opId.ToString()).Data;
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Email))
{
@ -1303,7 +1329,7 @@ namespace DS.WMS.Core.TaskPlat.Method
string emailTitle = $"Booking Confirmation : {taskBCInfo.MBL_NO}";
string filePath = string.Empty;
UserViewModel opUserInfo = _userService.GetUserInfo(bookingOrderEntity.OperatorId.ToString()).Data;
var opUserInfo = db.Queryable<SysUser>().Filter(null, true).First(x => x.Id == bookingOrderEntity.OperatorId && x.TenantId == long.Parse(user.TenantId));
if (taskBCInfo.BUSI_TYPE == "BookingAmendment")
{
@ -1341,8 +1367,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();
}
}
}
@ -1440,7 +1473,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <param name="opUserInfo">订舱OP详情</param>
/// <param name="tenantName">当前租户全称</param>
/// <returns>返回生成的HTML</returns>
public async Task<string> GenerateSendEmailHtml(TaskBCInfo taskBCInfo, UserViewModel opUserInfo, string tenantName)
public async Task<string> GenerateSendEmailHtml(TaskBCInfo taskBCInfo, SysUser opUserInfo, string tenantName)
{
string result = string.Empty;
@ -1599,7 +1632,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <param name="opUserInfo">订舱OP详情</param>
/// <param name="tenantName">当前租户全称</param>
/// <returns>返回生成的HTML</returns>
public async Task<string> GenerateSendEmailHtmlAmendment(TaskBCInfo taskBCInfo, UserViewModel opUserInfo, string tenantName)
public async Task<string> GenerateSendEmailHtmlAmendment(TaskBCInfo taskBCInfo, SysUser opUserInfo, string tenantName)
{
string result = string.Empty;
@ -1617,7 +1650,7 @@ namespace DS.WMS.Core.TaskPlat.Method
if (string.IsNullOrEmpty(basePath))
{
dirAbs = Path.Combine(_environment.WebRootPath, relativePath);
dirAbs = Path.Combine(_environment.WebRootPath ?? "", relativePath);
}
else
{
@ -1891,11 +1924,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 请联系管理员");
@ -1930,10 +1963,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)
@ -1947,13 +1983,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,
@ -2028,23 +2064,73 @@ namespace DS.WMS.Core.TaskPlat.Method
if (orderInfo != null && orderInfo.currOrder != null)
{
//更新订舱相关内容
if (!string.IsNullOrWhiteSpace(paramConfig) && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
{
//如果是拆票需要按照分票明细单个发送邮件
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();
if (paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
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
{
await GenerateSendEmail(taskBcInfo, taskBaseInfo, orderInfo);
//这里没有取到订舱信息,终止,并发出邮件通知
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);
}
}
}

@ -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);

@ -45,13 +45,13 @@ public class ClientCommonController : ApiController
/// <summary>
/// 获取商品下拉列表-客户端
/// </summary>
/// <param name="code">商品代码</param>
/// <param name="queryKey">商品代码</param>
/// <returns></returns>
[HttpGet]
[Route("GetClientGoodsList")]
public async Task<DataResult<List<CodeGoodsSelectRes>>> GetClientGoodsList([FromQuery] string code)
public async Task<DataResult<List<CodeGoodsSelectRes>>> GetClientGoodsList([FromQuery] string queryKey)
{
var res = await _invokeService.GetClientGoodsList(code);
var res = await _invokeService.GetClientGoodsList(queryKey);
return res;
}
/// <summary>
@ -574,9 +574,9 @@ public class ClientCommonController : ApiController
/// <returns></returns>
[HttpGet]
[Route("GetVesselSelectList")]
public DataResult<List<CodeVesselSelectRes>> GetVesselSelectList()
public DataResult<List<CodeVesselSelectRes>> GetVesselSelectList([FromQuery] string queryKey = "")
{
var res = _invokeService.GetVesselSelectList();
var res = _invokeService.GetVesselSelectList(queryKey);
return res;
}
@ -586,9 +586,9 @@ public class ClientCommonController : ApiController
/// <returns></returns>
[HttpGet]
[Route("GetVoynoSelectList")]
public DataResult<List<CodeVoynoSelectRes>> GetVoynoSelectList()
public DataResult<List<CodeVoynoSelectRes>> GetVoynoSelectList([FromQuery] string queryKey = "")
{
var res = _invokeService.GetVoynoSelectList();
var res = _invokeService.GetVoynoSelectList(queryKey);
return res;
}

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NameOfLastUsedPublishProfile>D:\Source\Repos\DS8\ds-wms-service\DS.WMS.MainApi\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<NameOfLastUsedPublishProfile>D:\Code\DS\ds8-solution-pro\ds-wms-service\DS.WMS.MainApi\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
</PropertyGroup>
</Project>

@ -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);
}
}
}

@ -39,6 +39,7 @@ builder.Host
builder.Services.AddAppWebInstal();
builder.Services.AddCorsInstall();
builder.Services.AddUserModuleInstall(); //用户服务
builder.Services.AddRedisModuleInstall();//redis
builder.Services.AddSqlSugarInstall();
builder.Services.AddSwaggerInstall();
builder.Services.AddJwtInstall();
@ -46,7 +47,7 @@ builder.Services.AddSaasDbInstall();//
builder.Services.AddMultiLanguageInstall();//多语言服务
builder.Services.AddDjyModuleInstall();//Djy服务
builder.Services.AddRuleEngineModuleInstall();//Djy规则引擎校验服务
builder.Services.AddRedisModuleInstall();//redis
// builder.Services.AddEndpointsApiExplorer();
// builder.Services.AddSwaggerGen();

@ -14,6 +14,7 @@ using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.Extensions.DependencyInjection;
using DS.WMS.PrintApi.Middleware;
using Newtonsoft.Json.Schema;
namespace DS.WMS.PrintApi.Service
{
@ -311,6 +312,8 @@ namespace DS.WMS.PrintApi.Service
var printFileName = $"{fileName}.frx";
var printFile = Path.Combine(savePath, printFileName);
//写入CRX文件
using (FileStream fs = new FileStream(printFile, FileMode.Create))
{
@ -322,18 +325,43 @@ namespace DS.WMS.PrintApi.Service
FastReport.Report report = new FastReport.Report();
report.Load(printFile);
report.Dictionary.Connections.Clear();
//var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
str.Json = JsonConvert.SerializeObject(data);
//dataSource.ConnectionString = str.ConnectionString;
//重置数据源
report.Dictionary.Connections.Add(new JsonDataSourceConnection()
if (report.Dictionary.Connections.Count == 0)
{
ConnectionString = str.ConnectionString,
Alias = "JSON"
});
//重置数据源
report.Dictionary.Connections.Add(new JsonDataSourceConnection()
{
ConnectionString = str.ConnectionString,
Name = "Connection",
});
}
//else {
// var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
// dataSource.ConnectionString = str.ConnectionString;
//}
//var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
//var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
//str.Json = JsonConvert.SerializeObject(data);
//dataSource.ConnectionString = str.ConnectionString;
//JsonSchemaGenerator generator = new JsonSchemaGenerator();
//JsonSchema jsonSchema = generator.Generate()
//report.Dictionary.Connections.Clear();
//var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
//var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
//str.Json = JsonConvert.SerializeObject(data);
////dataSource.ConnectionString = str.ConnectionString;
////重置数据源
//report.Dictionary.Connections.Add(new JsonDataSourceConnection()
//{
// ConnectionString = str.ConnectionString,
// Alias = "JSON"
//});
//report.Dictionary.Connections[0].ConnectionString = str.ConnectionString;
report.Prepare();

@ -38,6 +38,7 @@ builder.Host
builder.Services.AddAppWebInstal();
builder.Services.AddCorsInstall();
builder.Services.AddUserModuleInstall(); //用户服务
builder.Services.AddRedisModuleInstall();//redis
builder.Services.AddSqlSugarInstall();
builder.Services.AddSwaggerInstall();
builder.Services.AddJwtInstall();
@ -45,7 +46,7 @@ builder.Services.AddSaasDbInstall();//
builder.Services.AddMultiLanguageInstall();//多语言服务
builder.Services.AddDjyModuleInstall();//Djy服务
builder.Services.AddRuleEngineModuleInstall();//Djy规则引擎校验服务
builder.Services.AddRedisModuleInstall();//redis
builder.Services.AddTaskPlatMapsterSetup(); // 全局的Mapster自定义映射规则
// builder.Services.AddEndpointsApiExplorer();
// builder.Services.AddSwaggerGen();

Loading…
Cancel
Save