using DS.Module.Core; using DS.Module.Core.Condition; using DS.Module.Core.Data; using DS.WMS.Core.Code.Entity; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Dtos.TaskInteraction; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Op.Method.TaskInteraction.ActionSelector; using DS.WMS.Core.TaskPlat; using Fasterflect; using Masuit.Tools; using Microsoft.Extensions.DependencyInjection; using SqlSugar; using static AnyDiff.DifferenceLines; namespace DS.WMS.Core.Op.Method.TaskInteraction { /// /// 动作执行管理 /// public class ActionManagerService : ServiceBase, IActionManagerService { ITaskLogService logService; /// /// 初始化 /// public ActionManagerService(IServiceProvider serviceProvider) : base(serviceProvider) { logService = serviceProvider.GetRequiredService(); TenantDb.QueryFilter.Clear(); } /// /// 根据指定条件返回是否匹配的结果 /// /// 要对比的数据源 /// 匹配条件 /// public bool IsMatch(object source, ConditionContent condition) { ArgumentNullException.ThrowIfNull(source, nameof(source)); ArgumentNullException.ThrowIfNull(condition, nameof(condition)); TaskFlowDataContext dataContext = new((TaskFlowDataNameConst.Business, source)); return ConditionHelper.IsPass(condition, dataContext); } /// /// 根据指定条件返回是否匹配的结果 /// /// 业务ID /// 业务类型 /// 匹配条件 /// public async Task IsMatchAsync(long bsId, BusinessType businessType, IEnumerable conditions) { ArgumentNullException.ThrowIfNull(conditions, nameof(conditions)); var biz = await GetBusinessDataAsync(bsId, businessType, conditions); if (biz != null) { TaskFlowDataContext dataContext = new((TaskFlowDataNameConst.Business, biz)); //循环匹配 foreach (var item in conditions) { if (ConditionHelper.IsPass(item, dataContext)) return true; } } return false; } /// /// 获取所需业务数据 /// /// 业务ID /// 业务类型 /// 条件字段 /// public async Task GetBusinessDataAsync(long businessId, BusinessType businessType, IEnumerable conditions) { ArgumentNullException.ThrowIfNull(conditions, nameof(conditions)); HashSet fields = []; foreach (var item in conditions) { if (item.Conditions != null) fields.AddRange(item.Conditions.Select(x => x.Field)); if (item.Groups != null) fields.AddRange(item.Groups.SelectMany(x => x.Conditions.Select(x => x.Field))); } return await GetBusinessDataAsync(businessId, businessType, fields.ToArray()); } /// /// 获取所需业务数据 /// /// 业务ID /// 业务类型 /// 返回字段列表 /// public async Task GetBusinessDataAsync(long businessId, BusinessType businessType, params string[] fields) { object? biz = null; switch (businessType) { case BusinessType.OceanShippingExport: //未设置查询字段 if (fields == null || fields.Length == 0) { biz = await TenantDb.Queryable().Where(a => a.Id == businessId) .Select().Mapper(it => { it.DischargePortCountry = TenantDb.Queryable().Where(x => x.Id == it.DischargePortId).Select(x => x.CountryName).First(); }).FirstAsync(); } else { var selectors = fields.Select(x => new SelectModel { FieldName = x }).ToList(); biz = await TenantDb.Queryable().AS("op_sea_export") .Where("Id=@Id", new { Id = businessId }).Select(selectors).FirstAsync(); } break; case BusinessType.OceanShippingImport: break; } return biz; } /// /// 执行放舱任务(任务台使用) /// public async Task SpaceReleaseTask(TaskFlowDataContext dataContext) { dataContext.Set("TypeName", "DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.SpaceRelease.SpaceReleaseActionExecutor,DS.WMS.Core"); var businessId = dataContext.Get(TaskFlowDataNameConst.BusinessId); ArgumentNullException.ThrowIfNull(businessId, TaskFlowDataNameConst.BusinessId); //await TriggerActionAsync(businessId.Value, BusinessType.OceanShippingExport, TaskBaseTypeEnum.WAIT_SPACE_RELEASE); var businessTask = await TenantDb.Queryable().Where( x => x.BusinessId == businessId && x.BusinessType == BusinessType.OceanShippingExport && x.TaskType == TaskBaseTypeEnum.WAIT_SPACE_RELEASE).FirstAsync(); dataContext.Set(TaskFlowDataNameConst.BusinessTask, businessTask); await ExecuteAsync(dataContext); //var service = ServiceProvider.GetRequiredService(); //await service.CreateSubTaskAsync(businessTask); } /// /// 触发任务执行动作 /// /// 任务信息 /// 是否包含订单数据 /// 附加参数 /// public async Task TriggerActionAsync(BusinessTask businessTask, bool includeOrder = false, IDictionary? additionalData = null) { ArgumentNullException.ThrowIfNull(businessTask, nameof(businessTask)); TaskFlowDataContext dataContext = new( (TaskFlowDataNameConst.BusinessTask, businessTask) ); if (includeOrder) { var biz = GetBusinessDataAsync(businessTask.BusinessId, businessTask.BusinessType); dataContext[TaskFlowDataNameConst.Business] = biz; } if (additionalData != null) { foreach (var item in additionalData) dataContext[item.Key] = item.Value; } TaskFlowRuner taskFlow = new(TenantDb, ServiceProvider); await taskFlow.RunWithBsno(businessTask.TaskType, businessTask.BusinessId, dataContext); } /// /// 自动订舱 /// /// 业务ID /// 业务类型 /// public async Task AutomaticBooking(long businessId, BusinessType businessType) { try { var businessTask = await TenantDb.Queryable().Where( x => x.BusinessId == businessId && x.BusinessType == businessType && x.TaskType == TaskBaseTypeEnum.WAIT_BOOKING).FirstAsync(); if (businessTask == null) return DataResult.FailedWithDesc(MultiLanguageConst.BookingTaskNotFound); TaskFlowDataContext dataContext = new ( (TaskFlowDataNameConst.BusinessTask, businessTask), ("TypeName", typeof(BookingSelector).AssemblyQualifiedName) ); await ExecuteAsync(dataContext); return DataResult.Success; } catch (Exception ex) { await ex.LogAsync(Db); return DataResult.FailedWithDesc(MultiLanguageConst.Operation_Failed); } } /// /// 执行动作 /// /// /// public async Task ExecuteAsync(TaskFlowDataContext dataContext) { ArgumentNullException.ThrowIfNull(dataContext, nameof(dataContext)); var context = new ActionExecutionContext { ActionManager = this, TaskInfo = dataContext.GetOrDefault(TaskFlowDataNameConst.BusinessTask), ServiceProvider = ServiceProvider }; foreach (var key in dataContext.Keys) context.AdditionalData[key] = dataContext[key]; var typeName = dataContext.GetOrDefault("TypeName"); if (typeName.IsNullOrEmpty()) return; Type? t = Type.GetType(typeName, true, false); if (t == null) { await new ApplicationException($"未能获取类型【{typeName}】的信息,请检查配置").LogAsync(Db); return; } IActionExecutor? currentExecutor = null; object instance = ConstructorExtensions.CreateInstance(t); if (instance is IActionSelector selector) { currentExecutor = await selector.GetActionExecutor(context); } else if (instance is IActionExecutor executor) { currentExecutor = executor; } if (currentExecutor == null) { await new ApplicationException($"未能创建类型【{t.AssemblyQualifiedName}】的实例").LogAsync(Db); return; } var logService = context.ServiceProvider.GetRequiredService(); await logService.WriteLogAsync(context.TaskInfo, $"开始运行后台任务({currentExecutor.GetType().FullName})..."); await currentExecutor.ExecuteAsync(context); } } }