using DS.Module.Core; using DS.Module.Core.Data; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; using Newtonsoft.Json; using SqlSugar; using System.Diagnostics; using System.Reflection; namespace DS.WMS.Core.TaskPlat { /// /// 任务编排执行器 /// public class TaskFlowRuner { private readonly SqlSugarScopeProvider tenantDb = null!; private readonly IServiceProvider serviceProvider = null!; private TaskFlowRuner() { } /// /// /// /// /// public TaskFlowRuner(SqlSugarScopeProvider tenantDb, IServiceProvider serviceProvider) { this.tenantDb = tenantDb; this.serviceProvider = serviceProvider; } public async Task Run(TaskBaseTypeEnum taskBaseType, TaskManageOrderMessageInfo messageInfo, TaskBaseInfo taskInfo, TaskFlowDataContext dataContext) { if (taskInfo == null) { throw new ArgumentNullException(nameof(taskInfo)); } if (dataContext == null) { throw new ArgumentNullException(nameof(dataContext)); } var allConfigList = await tenantDb.Queryable() .Where(t => t.IsMain && t.TaskType == taskBaseType.ToString()) .OrderBy(t => t.Id) .ToListAsync(); if (allConfigList.Count == 0) { string msg = $"未找到任何用于【{taskBaseType}】业务的处理流程"; TaskFlowLog log = new() { IsMatch = false, TaskId = taskInfo.Id, TaskType = taskBaseType.ToString(), ExecuteStatus = 2, ExceptionMessage = msg }; await tenantDb.Insertable(log).ExecuteCommandAsync(); throw new Exception(msg); } var allConfigIdList = allConfigList.Select(x => x.Id); var allConditionList = await tenantDb.Queryable() .Where(x => allConfigIdList.Contains(x.ConfigId)) .ToListAsync(); Dictionary configMatchCount = allConfigList.ToDictionary(x => x.Id, x => 0); //dynamic taskInfoDynamic = taskInfo; foreach (var configItem in allConfigList) { var conditionListGroup = allConditionList.Where(x => x.ConfigId == configItem.Id); foreach (var conditionItem in conditionListGroup) { var (_, val, _) = GetPropertyValue(messageInfo, conditionItem.FieldName); if (val == null) continue; var valStr = val.ToString()!; if (conditionItem.MatchType == 1) { if (valStr.Equals(conditionItem.MatchValue, StringComparison.CurrentCultureIgnoreCase)) { configMatchCount[configItem.Id] = configMatchCount[configItem.Id] + 1; } } else if (conditionItem.MatchType == 2) { if (valStr.Contains(conditionItem.MatchValue!, StringComparison.CurrentCultureIgnoreCase)) { configMatchCount[configItem.Id] = configMatchCount[configItem.Id] + 1; } } else if (conditionItem.MatchType == 3) { if (valStr.StartsWith(conditionItem.MatchValue!, StringComparison.CurrentCultureIgnoreCase)) { configMatchCount[configItem.Id] = configMatchCount[configItem.Id] + 1; } } else if (conditionItem.MatchType == 4) { if (valStr.EndsWith(conditionItem.MatchValue!, StringComparison.CurrentCultureIgnoreCase)) { configMatchCount[configItem.Id] = configMatchCount[configItem.Id] + 1; } } } } KeyValuePair? bestMatched = null!; foreach (var item in configMatchCount) { if (bestMatched == null) { bestMatched = new KeyValuePair(item.Key, item.Value); continue; } if (item.Value > bestMatched.Value.Value) { bestMatched = new KeyValuePair(item.Key, item.Value); continue; } if (item.Value == bestMatched.Value.Value) { if (item.Key < bestMatched.Value.Key) { bestMatched = new KeyValuePair(item.Key, item.Value); continue; } } } var targetConfig = allConfigList.First(x => x.Id == bestMatched.Value.Key); var configList = await tenantDb.Queryable().Where(x => x.MainConfigId == targetConfig.Id).ToListAsync(); var configIdList = configList.Select(x => x.Id).ToList(); var moduleIdList = configList.Select(x => x.ExecuteModuleId).ToList(); var paramList = await tenantDb.Queryable().Where(x => configIdList.Contains(x.ConfigId)).ToListAsync(); var moduleList = await tenantDb.Queryable().Where(x => moduleIdList.Contains(x.Id)).ToListAsync(); TaskFlowLog flowLog = new() { Id = SnowFlakeSingle.Instance.NextId(), IsMatch = true, TaskId = taskInfo.Id, TaskType = taskBaseType.ToString(), MatchMainConfigId = targetConfig.Id, ConfigList = JsonConvert.SerializeObject(configList), ModuleList = JsonConvert.SerializeObject(moduleList), ExecuteStatus = 1 }; foreach (var configItem in configList) { TaskFlowLogDetail flowLogDetail = new() { ConfigId = configItem.Id, PId = flowLog.Id, }; try { var paramItemList = paramList.Where(x => x.ConfigId == configItem.Id).ToList(); foreach (var paramItem in paramItemList) { dataContext.Set(paramItem.FieldName!, paramItem.FieldValue!); //if (dataContext.ContainsKey(paramItem.FieldName!)) //{ // dataContext[paramItem.FieldName!] = paramItem.FieldValue!; //} //else //{ // dataContext.TryAdd(paramItem.FieldName!, paramItem.FieldValue!); //} } var module = moduleList.FirstOrDefault(x => x.Id == configItem.ExecuteModuleId); if (module == null) { throw new Exception($"未找到指定流程配置,ExecuteModuleId:{configItem.ExecuteModuleId}"); } Assembly assembly; if (module.NameSpace!.StartsWith("DS.WMS.Core")) { //assembly = Assembly.GetEntryAssembly()!; assembly = Assembly.GetExecutingAssembly(); } else { assembly = Assembly.Load(module.NameSpace!); } //var interfaceType2 = assembly.GetType(module.InterfaceName!); var interfaceType = assembly.DefinedTypes.FirstOrDefault(x => x.Name == module.InterfaceName!); if (interfaceType == null) { throw new Exception($"在命名空间【{module.NameSpace}】下未找到Interface【{module.InterfaceName}】"); } object? imp = serviceProvider.GetService(interfaceType); if (imp == null) { throw new Exception($"在依赖注入容器未找到Interface【{module.InterfaceName}】的实现类"); } MethodInfo? method = imp.GetType().GetMethod(module.MethodName!); if (method == null) { throw new Exception($"在Interface【{module.InterfaceName}】的实现类中未找到Method【{module.MethodName}】"); } Stopwatch stopwatch = Stopwatch.StartNew(); var invokeResult = method.Invoke(imp, new object[] { dataContext }); // 这里需要取一下返回值 //var b = invokeResult as DataResult; //var c = invokeResult as Task; //var d = c.Result; if (invokeResult is DataResult result) { } else if (invokeResult is Task result2) { } stopwatch.Stop(); flowLogDetail.ElapsedMillisecond = stopwatch.ElapsedMilliseconds; flowLogDetail.ExecuteStatus = 1; await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync(); } catch (Exception ex) { flowLog.ExecuteStatus = 2; flowLogDetail.ExceptionMessage = WriteLog("", ex); flowLogDetail.ExecuteStatus = 2; await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync(); if (configItem.IsExceptionContinue) { continue; } else { break; } } } await tenantDb.Insertable(flowLog).ExecuteCommandAsync(); } /// /// 深度获取对象属性值 /// /// 对象 /// 属性路径 static (bool isOk, object? val, string? otherPropertyPath) GetPropertyValue(object obj, string propertyPath) { var propertyName = propertyPath.Split('.').FirstOrDefault(); var type = obj.GetType(); var property = type.GetProperty(propertyName); if (property == null) { return (true, null, null); } if (property.PropertyType.IsClass && property.PropertyType != typeof(string)) { var val = property.GetValue(obj); if (val == null) { return (true, null, null); } var otherPropertyPath = propertyPath.Substring(propertyPath.IndexOf('.') + 1); return GetPropertyValue(val, otherPropertyPath); } else { var val = property.GetValue(obj); return (true, val, null); } } static string WriteLog(string throwMsg, Exception ex) { return string.Format("【自定义错误】:{0} \r\n【异常类型】:{1} \r\n【异常信息】:{2} \r\n【堆栈调用】:{3}", new object[] { throwMsg, ex.GetType().Name, ex.Message, ex.StackTrace }); } } }