jianghaiqing 4 months ago
commit 04cb2f9bcc

@ -1,4 +1,9 @@
namespace DS.Module.Core.Data
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace DS.Module.Core.Data
{
/// <summary>
/// 任务模块之间用于传入、获取数据的容器
@ -26,6 +31,14 @@
}
}
public IReadOnlyCollection<string> Keys => dataContext.Keys;
public object? this[string key]
{
get { return dataContext[key]; }
set { dataContext[key] = value; }
}
/// <summary>
///
/// </summary>
@ -52,6 +65,10 @@
{
return t;
}
else if (value != null)
{
return (T)Convert.ChangeType(value, typeof(T));
}
}
return default;
}
@ -60,5 +77,7 @@
///
/// </summary>
public bool ContainsKey(string key) => dataContext.ContainsKey(key);
}
}

@ -12,7 +12,7 @@ public static class StringExtensions
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static bool IsSqlInjection(string input)
public static bool IsSqlInjection(this string input)
{
string[] sqlCheckList = { "TRUNCATE", "INSERT", "UPDATE", "DELETE", "DROP", "--", ";", "'" };
foreach (string item in sqlCheckList)

@ -1,5 +1,5 @@
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using SqlSugar;
namespace DS.WMS.Core.Op.Dtos.TaskInteraction
{
@ -8,8 +8,12 @@ namespace DS.WMS.Core.Op.Dtos.TaskInteraction
/// </summary>
public class ActionExecutionContext
{
public BusinessTask Task { get; set; }
public BusinessTask TaskInfo { get; internal set; }
public IServiceProvider ServiceProvider { get; internal set; }
public ISqlSugarClient TenantDb { get; internal set; }
public IDictionary<string, object?> AdditionalData { get; set; } = new Dictionary<string, object?>();
}
}

@ -1,5 +1,4 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Data;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity.TaskInteraction
@ -10,11 +9,11 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
[SugarTable("business_task_mail", "任务邮件发送配置")]
public class BusinessTaskMail : BaseOrgModelV2<long>
{
/// <summary>
/// 任务类型
/// </summary>
[SugarColumn(ColumnDescription = "任务类型", IsNullable = false)]
public TaskBaseTypeEnum TaskType { get; set; }
///// <summary>
///// 任务类型
///// </summary>
//[SugarColumn(ColumnDescription = "任务类型", IsNullable = false)]
//public TaskBaseTypeEnum TaskType { get; set; }
///// <summary>
///// 任务状态
@ -22,6 +21,12 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
//[SugarColumn(ColumnDescription = "任务状态", IsNullable = false)]
//public TaskStatusEnum TaskStatus { get; set; } = TaskStatusEnum.Complete;
/// <summary>
/// 配置名称
/// </summary>
[SugarColumn(ColumnDescription = "配置名称", Length = 100, IsNullable = false)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 主题
/// </summary>

@ -10,7 +10,7 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <summary>
/// 执行特定动作
/// </summary>
/// <param name="context"></param>
/// <param name="context">执行上下文</param>
/// <returns></returns>
Task ExecuteAsync(ActionExecutionContext context);
}

@ -6,7 +6,7 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <summary>
/// 动作执行管理
/// </summary>
public interface IActionManager
public interface IActionManagerService
{
/// <summary>
/// 执行特定动作

@ -23,6 +23,13 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <returns></returns>
Task<DataResult<BusinessTaskMail>> GetAsync(long id);
/// <summary>
/// 根据配置名获取
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Task<BusinessTaskMail> GetAsync(string name);
/// <summary>
/// 编辑
/// </summary>

@ -1,5 +1,6 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.TaskPlat;
@ -9,14 +10,14 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// <summary>
/// 动作执行管理
/// </summary>
public class ActionManager : ServiceBase, IActionManager
public class ActionManagerService : ServiceBase, IActionManagerService
{
Dictionary<TaskActionType, IActionExecutor> ExecutorMappings;
/// <summary>
/// 初始化
/// </summary>
public ActionManager(IServiceProvider serviceProvider) : base(serviceProvider)
public ActionManagerService(IServiceProvider serviceProvider) : base(serviceProvider)
{
ExecutorMappings = new Dictionary<TaskActionType, IActionExecutor>();
ExecutorMappings[TaskActionType.Mail] = new MailActionExecutor();
@ -27,7 +28,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// </summary>
/// <param name="businessTask">任务信息</param>
/// <returns></returns>
public async Task TriggerAction(BusinessTask businessTask)
public async Task TriggerAction(BusinessTask businessTask)
{
ArgumentNullException.ThrowIfNull(businessTask, nameof(businessTask));
@ -41,13 +42,29 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
);
TaskFlowRuner taskFlow = new(TenantDb, ServiceProvider);
await taskFlow.Run(businessTask.TaskType, businessTask.BusinessId, dataContext);
await taskFlow.RunWithBsno(businessTask.TaskType, businessTask.BusinessId, dataContext);
}
public async Task ExecuteAsync(TaskFlowDataContext dataContext)
{
ArgumentNullException.ThrowIfNull(dataContext, nameof(dataContext));
TaskActionType actionType = (TaskActionType)dataContext.Get<int>("ActionType");
if (ExecutorMappings.TryGetValue(actionType, out IActionExecutor executor))
{
var context = new ActionExecutionContext
{
TaskInfo = dataContext.Get<BusinessTask>(TaskFlowDataNameConst.BusinessTask),
ServiceProvider = ServiceProvider,
TenantDb = TenantDb
};
foreach (var key in dataContext.Keys)
{
context.AdditionalData[key] = dataContext[key];
}
await executor.ExecuteAsync(context);
}
}
}

@ -1,13 +1,43 @@
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
using RazorEngineCore;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
/// <summary>
/// 用于邮件发送的执行器
/// </summary>
public class MailActionExecutor : IActionExecutor
{
public Task ExecuteAsync(ActionExecutionContext context)
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task ExecuteAsync(ActionExecutionContext context)
{
throw new NotImplementedException();
var service = context.ServiceProvider.GetRequiredService<ITaskMailService>();
var logService = context.ServiceProvider.GetRequiredService<ITaskLogService>();
var mailName = context.AdditionalData["MailName"] as string;
if (mailName.IsNullOrEmpty())
{
await logService.WriteLogAsync(context.TaskInfo, $"未配置【{context.TaskInfo.TaskType.GetDescription()}】任务的邮件设置");
return;
}
var mailConfig = await service.GetAsync(mailName);
if (mailConfig == null)
{
await logService.WriteLogAsync(context.TaskInfo, $"未能获取名为【{mailName}】的邮件配置");
return;
}
IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate titleTemplate = razorEngine.Compile(mailConfig.Title);
IRazorEngineCompiledTemplate contentTemplate = razorEngine.Compile(mailConfig.Content);
}
}
}

@ -1,13 +0,0 @@
using RazorEngineCore;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
internal class MailTemplate
{
public MailTemplate()
{
IRazorEngine razorEngine = new RazorEngine();
}
}
}

@ -38,12 +38,25 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// <returns></returns>
public async Task<DataResult<BusinessTaskMail>> GetAsync(long id)
{
var entity = await TenantDb.Queryable<BusinessTaskMail>().Includes(x => x.Receiver).Includes(x => x.Sender)
var entity = await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Server).Includes(x => x.Attachments)
.Where(x => x.Id == id).FirstAsync();
return DataResult<BusinessTaskMail>.Success(entity);
}
/// <summary>
/// 根据配置名获取
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<BusinessTaskMail> GetAsync(string name)
{
return await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Server).Includes(x => x.Attachments)
.Where(x => x.Name == name).FirstAsync();
}
/// <summary>
/// 编辑
/// </summary>
@ -58,12 +71,13 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
taskMail.Receiver ??= new();
taskMail.Sender ??= new();
taskMail.Server ??= new();
taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteReturnEntityAsync();
taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).ExecuteReturnEntityAsync();
}
else
{
await TenantDb.UpdateNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteCommandAsync();
await TenantDb.UpdateNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).ExecuteCommandAsync();
}
if (taskMail.Attachments?.Count > 0)
@ -99,7 +113,8 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
try
{
await TenantDb.DeleteNav<BusinessTaskMail>(x => model.Ids.Contains(x.Id))
.Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Attachments).ExecuteCommandAsync();
.Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).Include(x => x.Attachments)
.ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;

@ -47,6 +47,11 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// </summary>
protected Lazy<IClientFlowInstanceService> FlowService { get; private set; }
/// <summary>
/// 工作流服务
/// </summary>
protected Lazy<IActionManagerService> ActionService { get; private set; }
/// <summary>
/// 初始化
/// </summary>
@ -56,6 +61,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
ManagerService = provider.GetRequiredService<ITaskManageService>();
LogService = provider.GetRequiredService<ITaskLogService>();
FlowService = new Lazy<IClientFlowInstanceService>(provider.GetRequiredService<IClientFlowInstanceService>());
ActionService = new Lazy<IActionManagerService>(provider.GetRequiredService<IActionManagerService>());
}
/// <summary>
@ -462,6 +468,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (useTransaction)
await TenantDb.Ado.CommitTranAsync();
ActionService.Value.TriggerAction(task);
return DataResult<TaskBaseTypeEnum?>.Success(task.TaskStatus == TaskStatusEnum.Complete ? GetNextType(task) : null);
}
catch (Exception ex)
@ -556,7 +563,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
BusinessId = callback.BusinessId,
BusinessType = callback.BusinessType.GetValueOrDefault(),
TaskTypeName = (taskType == TaskBaseTypeEnum.WAIT_ORDER_AUDIT ?
TaskTypeName = (taskType == TaskBaseTypeEnum.WAIT_ORDER_AUDIT ?
TaskBaseTypeEnum.ORDER_AUDIT_REJECTED : TaskBaseTypeEnum.RETURN_CABIN_REJECTED).ToString(),
RecvUserIdList = [task.CreateBy] //通知任务发起人
});
@ -622,7 +629,10 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
}
var allocation = allocations.Find(x => x.CarrierId == carrierId);
//未找到匹配值
//首先使用船公司匹配
if (allocation == null)
allocation = allocations.Find(x => x.CarrierId == null); //使用默认值匹配
if (allocation == null)
return null;
@ -631,15 +641,15 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
expr = expr.Or(x => x.IsCustomerService);
}
else if (allocation.IsAllotOperator)
if (allocation.IsAllotOperator)
{
expr = expr.Or(x => x.IsOperator);
}
else if (allocation.IsAllotSale)
if (allocation.IsAllotSale)
{
expr = expr.Or(x => x.IsSale);
}
else if (allocation.IsAllotVouchingClerk)
if (allocation.IsAllotVouchingClerk)
{
expr = expr.Or(x => x.IsVouchingClerk);
}

@ -46,7 +46,7 @@ namespace DS.WMS.Core.Sys.Interface
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public DataResult EditSysPrintTemplate(SysPrintTemplateReq req);
public Task<DataResult> EditSysPrintTemplate(SysPrintTemplateReq req);
/// <summary>
/// 打印模块删除

@ -12,6 +12,7 @@ using DS.Module.SqlSugar;
using DS.WMS.Core.Code.Entity;
using Org.BouncyCastle.Ocsp;
using System.Collections.Generic;
using Masuit.Tools.Strings;
namespace DS.WMS.Core.Sys.Method
{
@ -96,29 +97,71 @@ namespace DS.WMS.Core.Sys.Method
.First();
return DataResult<SysPrintTemplateRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
}
public DataResult EditSysPrintTemplate(SysPrintTemplateReq req)
public async Task<DataResult> EditSysPrintTemplate(SysPrintTemplateReq req)
{
if (req.Id == 0)
{
var isExist = db.Queryable<SysPrintTemplate>().Where(x => x.TemplateCode == req.TemplateCode).WhereIF(req.CarrierId != 0, x => x.CarrierId == req.CarrierId).First();
if (isExist != null)
if (db.Queryable<SysPrintTemplate>().Where(x => x.TemplateCode == req.TemplateCode).WhereIF(req.CarrierId != 0, x => x.CarrierId == req.CarrierId).Any())
{
return DataResult.Failed("打印模板唯一编码已存在!");
return await Task.FromResult(DataResult.Failed("打印模板唯一编码已存在!"));
}
if (req.IsUseDataSource) {
if (string.IsNullOrEmpty(req.SourceSql))
{
return await Task.FromResult(DataResult.Failed("打印数据源不能为空!"));
}
if (!req.SourceSql.Contains(';'))
{
return await Task.FromResult(DataResult.Failed("数据源必须包含分号!"));
}
if (req.SourceSql.Substring(req.SourceSql.Length - 1, 1) != ";")
{
return await Task.FromResult(DataResult.Failed("数据源最后必须包含分号!"));
}
if (req.SourceSql.IsSqlInjection())
{
return await Task.FromResult(DataResult.Failed("sql数据源包含非法字符,请检查!"));
}
}
var data = req.Adapt<SysPrintTemplate>();
var entity = db.Insertable(data).ExecuteReturnEntity();
var entity = await db.Insertable(data).ExecuteReturnEntityAsync();
return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess);
}
else
{
var info = db.Queryable<SysPrintTemplate>().Where(x => x.Id == req.Id).First();
var info = await db.Queryable<SysPrintTemplate>().Where(x => x.Id == req.Id).FirstAsync();
if (req.IsUseDataSource)
{
if (string.IsNullOrEmpty(req.SourceSql))
{
return await Task.FromResult(DataResult.Failed("打印数据源不能为空!"));
}
if (!req.SourceSql.Contains(';'))
{
return await Task.FromResult(DataResult.Failed("数据源必须包含分号!"));
}
if (req.SourceSql.Substring(req.SourceSql.Length - 1, 1) != ";")
{
return await Task.FromResult(DataResult.Failed("数据源最后必须包含分号!"));
}
if (req.SourceSql.IsSqlInjection())
{
return await Task.FromResult(DataResult.Failed("sql数据源包含非法字符,请检查!"));
}
}
info = req.Adapt(info);
db.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
await db.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
return await Task.FromResult(DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess));
}
}

@ -325,12 +325,22 @@ namespace DS.WMS.Core.TaskPlat
}
catch (Exception ex)
{
string exMessage;
if (ex is TargetInvocationException ex2 && ex2.InnerException != null)
{
exMessage = WriteLog("模块内部执行过程中发生异常", ex2.InnerException);
}
else
{
exMessage = WriteLog("模块外部调用过程中发生异常", ex);
}
flowLogDetail.ExceptionMessage = exMessage;
flowLog.IsComplete = false;
flowLog.IsSuccess = false;
flowLogDetail.IsComplete = false;
flowLogDetail.IsSuccess = false;
flowLogDetail.ExceptionMessage = WriteLog("模块执行过程中发生异常", ex);
await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync();
if (executeConfig.IsExceptionContinue)

@ -94,9 +94,9 @@ public class PrintTemplateController : ApiController
/// <returns></returns>
[HttpPost]
[Route("EditSysPrintTemplate")]
public DataResult EditSysPrintTemplate([FromBody] SysPrintTemplateReq req)
public async Task<DataResult> EditSysPrintTemplate([FromBody] SysPrintTemplateReq req)
{
var res = _invokeService.EditSysPrintTemplate(req);
var res = await _invokeService.EditSysPrintTemplate(req);
return res;
}

@ -312,8 +312,7 @@ namespace DS.WMS.PrintApi.Service
var printFileName = $"{fileName}.frx";
var printFile = Path.Combine(savePath, printFileName);
//写入CRX文件
using (FileStream fs = new FileStream(printFile, FileMode.Create))
{
@ -324,7 +323,6 @@ namespace DS.WMS.PrintApi.Service
//生成报表
FastReport.Report report = new FastReport.Report();
report.Load(printFile);
var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
str.Json = JsonConvert.SerializeObject(data);
if (report.Dictionary.Connections.Count == 0)
@ -336,34 +334,9 @@ namespace DS.WMS.PrintApi.Service
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.Save(printFile);
report.Prepare();
var printName = string.Empty;
var saveFile = string.Empty;

Loading…
Cancel
Save