jianghaiqing 3 months ago
commit cc5cb0df79

@ -1492,7 +1492,7 @@ public static class MultiLanguageConst
public const string TaskStatusNotSupported = "Task_Status_Not_Supported";
[Description("当前任务状态不正确,无法提交审核")]
public const string TaskAuditStatusError = "Task_Audit_Status_Error";
[Description("无法从配置中获取任务接收人,请联系管理员检查系统配置")]
[Description("无法从配置中获取任务接收人,请检查是否设置了订单的操作/客服/单证等人员,或联系管理员检查配置")]
public const string TaskReceiverNotFound = "Task_Receiver_Not_Found";
[Description("任务邮件必须设置收件人")]

@ -1,4 +1,4 @@
namespace DS.WMS.Core.Op.Dtos.TaskInteraction
namespace DS.Module.Core.Data
{
/// <summary>
/// 邮件模板模型
@ -9,6 +9,11 @@
/// <summary>
/// 主要数据项
/// </summary>
public T? Primary { get; internal set; }
public T? Primary { get; set; }
/// <summary>
/// 附加数据
/// </summary>
public dynamic? ExtraData { get; set; }
}
}

@ -189,7 +189,7 @@ namespace DS.Module.Core
TRNAS_PLAN_HAS_CHANGE = 30,
#region 工作流--主流程
#region 工作流--主流程任务类型
/// <summary>
/// 审单
/// </summary>
@ -329,5 +329,19 @@ namespace DS.Module.Core
[Description("箱使")]
WAIT_XIANGSHI = 316,
#endregion
#region 工作流--流程编码
/// <summary>
/// 工作流任务创建主流程
/// </summary>
[Description("工作流任务创建主流程")]
WORK_FLOW_MAIN = 601,
/// <summary>
/// 工作流退舱流程
/// </summary>
[Description("工作流退舱流程")]
WORK_FLOW_RETURN_CABIN = 602
#endregion
}
}

@ -1,18 +1,13 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DS.WMS.Core.Code.Entity
{
/// <summary>
/// 用户邮箱账户
/// </summary>
[SqlSugar.SugarTable("code_user_email", "用户邮箱账户")]
[SugarTable("code_user_email", "用户邮箱账户")]
public class CodeUserEmail : BaseModel<long>
{
/// <summary>

@ -0,0 +1,42 @@
using System.ComponentModel;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Enums;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity
{
/// <summary>
/// 业务编码表
/// </summary>
[SqlSugar.SugarTable("op_business_sequence", "业务编码表")]
public class BusinessSequence: BaseModel<long>
{
[SugarColumn(ColumnDescription = "编码规则Id")]
public long SequenceId { get; set; }
/// <summary>
/// 当前值
/// </summary>
[SugarColumn(ColumnDescription = "当前值", IsNullable = true)]
public int CurrentNo { get; set; }
/// <summary>
/// 编码前缀
/// </summary>
[SugarColumn(ColumnDescription = "编码前缀", Length = 100, IsNullable = true)]
public string Prefix { get; set; }
/// <summary>
/// 当前编码
/// </summary>
[SugarColumn(ColumnDescription = "当前编码",Length =100,IsNullable = true)]
public string CurrentCode { get; set; }
/// <summary>
/// 当前重置依赖,即最后一次获取编码的日期
/// </summary>
[SugarColumn(ColumnDescription = "当前重置依赖", Length = 100, IsNullable = true)]
public string CurrentReset { get; set; }
}
}

@ -1,4 +1,5 @@
using DS.Module.Core.Data;
using System.ComponentModel;
using DS.Module.Core.Data;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity.TaskInteraction
@ -9,32 +10,26 @@ 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 TaskStatusEnum TaskStatus { get; set; } = TaskStatusEnum.Complete;
/// <summary>
/// 单据类型
/// </summary>
[SugarColumn(ColumnDescription = "单据类型")]
public DocumentType DocumentType { get; set; }
/// <summary>
/// 配置名称
/// 自定义名称
/// </summary>
[SugarColumn(ColumnDescription = "配置名称", Length = 100, IsNullable = false)]
public string Name { get; set; } = string.Empty;
[SugarColumn(ColumnDescription = "自定义名称", Length = 100, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 主题
/// 主题模板
/// </summary>
[SugarColumn(ColumnDescription = "主题", Length = 200, IsNullable = false)]
public string Title { get; set; } = string.Empty;
/// <summary>
/// 内容
/// 内容模板
/// </summary>
[SugarColumn(ColumnDescription = "内容", ColumnDataType = "text", IsNullable = false)]
public string Content { get; set; } = string.Empty;
@ -63,10 +58,64 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
[Navigate(NavigateType.OneToOne, nameof(Id))]
public BusinessTaskMailSender? Sender { get; set; }
/// <summary>
/// 抄送人设置
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(Id))]
public BusinessTaskMailCC? CC { get; set; }
/// <summary>
/// 附件设置
/// </summary>
[Navigate(NavigateType.OneToMany, nameof(BusinessTaskAttachment.TaskMailId))]
public List<BusinessTaskAttachment>? Attachments { get; set; }
}
/// <summary>
/// 单据类型
/// </summary>
public enum DocumentType
{
/// <summary>
/// 自定义
/// </summary>
[Description("自定义")]
Custom = 0,
/// <summary>
/// 订舱委托
/// </summary>
[Description("订舱委托")]
BookingNote = 1,
/// <summary>
/// BC
/// </summary>
[Description("BC")]
BC = 2,
/// <summary>
/// BN
/// </summary>
[Description("BN")]
BN = 3,
/// <summary>
/// 提单确认
/// </summary>
[Description("提单确认")]
BLConfirmation = 4,
/// <summary>
/// 提单留底
/// </summary>
[Description("提单留底")]
BLRetention = 5,
/// <summary>
/// 费用确认
/// </summary>
[Description("费用确认")]
CostConfirmation = 6,
}
}

@ -0,0 +1,43 @@
using System.ComponentModel;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity.TaskInteraction
{
/// <summary>
/// 任务邮件抄送人配置
/// </summary>
[SugarTable("business_task_mail_cc", "任务邮件抄送人配置")]
public class BusinessTaskMailCC
{
/// <summary>
/// 任务邮件配置ID
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public long TaskMailId { get; set; }
/// <summary>
/// 是否操作
/// </summary>
[Description("是否操作")]
public bool IsOperator { get; set; }
/// <summary>
/// 是否单证
/// </summary>
[Description("是否单证")]
public bool IsVouchingClerk { get; set; }
/// <summary>
/// 是否销售
/// </summary>
[Description("是否销售")]
public bool IsSale { get; set; }
/// <summary>
/// 是否客服
/// </summary>
[Description("是否客服")]
public bool IsCustomerService { get; set; }
}
}

@ -51,6 +51,13 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <returns></returns>
Task<DataResult> SubmitAuditAsync(TaskRequest request);
/// <summary>
/// 撤销审核任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<DataResult> WithdrawAsync(TaskRequest request);
/// <summary>
/// 任务审核
/// </summary>

@ -1,4 +1,5 @@
@{
@* @model DS.Module.Core.Data.MailTemplateModel<DS.WMS.Core.Op.Dtos.TaskInteraction.SeaExportOrder> *@
@{
var item = Model.Primary;
}

@ -460,11 +460,18 @@ public partial class SeaExportService : ISeaExportService
{
return await Task.FromResult(DataResult.Failed("截港日期不允许大于开船日期!", MultiLanguageConst.SeaExportCloseDateLimit));
}
var sequence = commonService.GetSequenceNext<SeaExport>();
//var sequence = commonService.GetSequenceNext<SeaExport>();
//if (!sequence.Succeeded)
//{
// return await Task.FromResult(DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist));
//}
//
var sequence = await commonService.GetSequenceNextAsync<SeaExport>(tenantDb,user);
if (!sequence.Succeeded)
{
return await Task.FromResult(DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist));
}
var data = req.Adapt<SeaExport>();
data.CustomerNo = sequence.Data;
#region 处理箱型箱量

@ -1,23 +1,25 @@
using DS.Module.PrintModule;
using System.Collections.Concurrent;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.PrintModule;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Info.Entity;
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.Interface;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor;
using DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.Booking;
using DS.WMS.Core.Sys.Entity;
using HtmlAgilityPack;
using Newtonsoft.Json;
using RazorEngineCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Mapster;
using DS.Module.Core;
using Masuit.Tools;
using Masuit.Tools.Systems;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.Booking;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using RazorEngineCore;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
@ -26,6 +28,9 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// </summary>
public class MailService : ServiceBase
{
static readonly ConcurrentDictionary<int, IRazorEngineCompiledTemplate> TemplateCache =
new ConcurrentDictionary<int, IRazorEngineCompiledTemplate>();
ITaskMailService service;
ISeaExportService seService;
IConfiguration config;
@ -42,8 +47,21 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
config = provider.GetRequiredService<IConfiguration>();
}
private async Task<string> RenderTemplateAsync(string name, string templateText, object model, RazorEngine? razorEngine = null)
{
int hashCode = name.GetHashCode();
IRazorEngineCompiledTemplate compiledTemplate = TemplateCache.GetOrAdd(hashCode, i =>
{
var engine = razorEngine ?? new RazorEngine();
return engine.Compile(templateText);
});
return await compiledTemplate.RunAsync(model);
}
/// <summary>
/// 发送业务邮件
/// 根据配置发送邮件
/// </summary>
/// <param name="mailConfig">邮件配置</param>
/// <param name="businessId">业务ID</param>
@ -60,20 +78,14 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
string title, content = string.Empty;
var templateModel = new MailTemplateModel<SeaExportOrder> { Primary = result.Data.Adapt<SeaExportOrder>() };
IRazorEngine razorEngine = new RazorEngine();
var razorEngine = new RazorEngine();
try
{
var titleTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportOrder>>>(mailConfig.Title);
title = await titleTemplate.RunAsync(x =>
{
x.Model = templateModel;
});
string key1 = mailConfig.Id + "-" + nameof(mailConfig.Title);
title = await RenderTemplateAsync(key1, mailConfig.Title, templateModel, razorEngine);
var contentTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportOrder>>>(mailConfig.Content);
content = await contentTemplate.RunAsync(x =>
{
x.Model = templateModel;
});
string key2 = mailConfig.Id + "-" + nameof(mailConfig.Content);
content = await RenderTemplateAsync(key2, mailConfig.Content, templateModel, razorEngine);
}
catch (Exception ex)
{
@ -107,10 +119,27 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (node != null)
node.InnerHtml = sender.SignatureHtml;
StringWriter writer = new();
htmlDoc.Save(writer);
content = writer.ToString();
writer.Close();
using (StringWriter writer = new())
{
htmlDoc.Save(writer);
content = writer.ToString();
writer.Close();
}
//设置抄送人
List<long> ccIds = [];
List<string> ccList = [];
if (mailConfig.CC.IsSale)
ccIds.Add(templateModel.Primary.SaleId);
else if (mailConfig.CC.IsOperator)
ccIds.Add(templateModel.Primary.OperatorId);
else if (mailConfig.CC.IsCustomerService)
ccIds.Add(templateModel.Primary.CustomerService);
else if (mailConfig.CC.IsVouchingClerk)
ccIds.Add(templateModel.Primary.Doc);
if (ccIds.Count > 0)
ccList = await Db.Queryable<SysUser>().Where(x => ccIds.Contains(x.Id)).Select(x => x.Email).ToListAsync();
//设置收件人
List<long> receiverIds = [];
@ -174,6 +203,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
SendTo = string.Join(",", receiverList.Select(x => x.Email)),
Title = title,
Body = content,
CCTo = string.Join(",", ccList),
ShowName = senderConfig.ShowName.IsNullOrEmpty() ? sender.UserName : senderConfig.ShowName,
Account = senderConfig.MailAccount,
senderConfig.Password,
@ -195,8 +225,8 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
}
return DataResult.Failed($"邮件发送失败API返回状态为{(int)mailResult.Data.StatusCode} {mailResult.Data.StatusCode}"
+"(委托单:{templateModel.Primary.CustomerNo}),收件人:"
+ string.Join(",", receiverList.Select(x => x.Email))
+ "(委托单:{templateModel.Primary.CustomerNo}),收件人:"
+ string.Join(",", receiverList.Select(x => x.Email))
+ "发件人:" + senderConfig.MailAccount);
}
catch (Exception ex)

@ -27,7 +27,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
public async Task<DataResult<List<BusinessTaskMail>>> GetListAsync(PageRequest request)
{
var whereList = request.GetConditionalModels(Db);
return await TenantDb.Queryable<BusinessTaskMail>().Includes(x => x.Receiver).Includes(x => x.Sender)
return await TenantDb.Queryable<BusinessTaskMail>().Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.CC)
.Where(whereList).ToQueryPageAsync(request.PageCondition);
}
@ -39,7 +39,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
public async Task<DataResult<BusinessTaskMail>> GetAsync(long id)
{
var entity = await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments)
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments).Includes(x => x.CC)
.Where(x => x.Id == id).FirstAsync();
return DataResult<BusinessTaskMail>.Success(entity);
@ -53,7 +53,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
public async Task<BusinessTaskMail> GetAsync(string name)
{
return await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments)
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments).Includes(x => x.CC)
.Where(x => x.Name == name).FirstAsync();
}
@ -71,6 +71,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
taskMail.Receiver ??= new();
taskMail.Sender ??= new();
taskMail.CC ??= new();
taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteReturnEntityAsync();
}

@ -1,5 +1,4 @@
using DS.Module.Core;
using DS.Module.Core.Condition;
using DS.Module.Core.Data;
using DS.Module.Core.Helpers;
using DS.WMS.Core.Flow.Dtos;
@ -18,7 +17,6 @@ using DS.WMS.Core.TaskPlat.Interface;
using Masuit.Tools;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using SqlSugar;
namespace DS.WMS.Core.Op.Method.TaskInteraction
@ -74,6 +72,23 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
ActionService = new Lazy<IActionManagerService>(provider.GetRequiredService<IActionManagerService>());
}
/// <summary>
/// 获取给定任务的下一默认任务类型
/// </summary>
/// <param name="current">任务信息</param>
/// <returns></returns>
internal static async Task<TaskBaseTypeEnum?> GetDefaultNextTypeAsync(BusinessTask current)
{
if (current.TaskType == TaskBaseTypeEnum.NOT_SPECIFIED || current.TaskType == TaskBaseTypeEnum.WAIT_CHECKOUT_BILL) //流程的最后一步
return null;
int currentTypeVal = (int)current.TaskType;
if (currentTypeVal >= 300) //300开始的枚举值为可选服务项目不存在前后关联性
return null;
return (TaskBaseTypeEnum)(currentTypeVal + 1);
}
/// <summary>
/// 获取给定任务的下一任务类型
/// </summary>
@ -83,8 +98,8 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
TaskFlowRuner flowRuner = new TaskFlowRuner(TenantDb, ServiceProvider);
var result = await flowRuner.GetWorkFlowNextConfig(new TaskFlowDataContext(
var result = await flowRuner.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, new TaskFlowDataContext(
), current.NextId);
if (result.HasValue)
@ -202,6 +217,53 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskStatusNotSupported));
}
/// <summary>
/// 撤销审核任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> WithdrawAsync(TaskRequest request)
{
var task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
await TenantDb.Ado.BeginTranAsync();
try
{
//同时删除工作流
if (task.FlowId.HasValue)
{
//long userId = long.Parse(User.UserId);
//await Db.Updateable(new FlowInstance
//{
// Id = task.FlowId.Value,
// DeleteBy = long.Parse(User.UserId),
// DeleteTime = DateTime.Now,
// Deleted = true
//}).UpdateColumns(x => new { x.DeleteBy, x.DeleteTime, x.Deleted }).ExecuteCommandAsync();
await Db.Deleteable<FlowInstance>().Where(x => x.Id == task.FlowId.Value).ExecuteCommandAsync();
}
await TenantDb.Deleteable<BusinessTask>().Where(x => x.BusinessId == request.BusinessId && x.BusinessType == request.BusinessType && x.TaskType == request.TaskType)
.ExecuteCommandAsync();
//记录日志
await LogService.WriteLogAsync(task, "撤销审核");
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>
@ -258,8 +320,8 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (task != null && task.TaskStatus != TaskStatusEnum.Cancel)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskExists));
if (await ShouldSkipAsync(request))
return DataResult.Success;
//if (await ShouldSkipAsync(request))
// return DataResult.Success;
long tenatId = long.Parse(User.TenantId);
string tenatName = Db.Queryable<SysTenant>().Where(x => x.Id == tenatId).Select(x => x.Name).First();
@ -299,13 +361,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (info.Main.RecvUserInfoList == null || info.Main.RecvUserInfoList.Count == 0)
{
if (AuditTaskTypes.Contains(request.TaskType))
{
info.Main.RecvUserInfoList = await GetRecvUsersAsync(long.Parse(User.UserId));
}
else
{
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskReceiverNotFound));
}
}
}
else
@ -313,6 +369,9 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
info.Main.RecvUserInfoList = await GetRecvUsersAsync(request.RecvUserIdList);
}
if (info.Main.RecvUserInfoList == null || info.Main.RecvUserInfoList.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskReceiverNotFound));
if (info.Main.TaskTitle.IsNullOrEmpty())
{
var biz = await TenantDb.Queryable<SeaExport>().Select(x => new
@ -347,7 +406,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
CreateBy = long.Parse(User.UserId),
CreateTime = DateTime.Now
};
task.NextType = await GetNextTypeAsync(task);
task.NextType = await GetDefaultNextTypeAsync(task);
await TenantDb.Insertable(task).ExecuteCommandAsync();
//审核任务需创建工作流
@ -380,21 +439,21 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
}
}
internal async Task<bool> ShouldSkipAsync(TaskRequest request)
{
var configList = await TenantDb.Queryable<BusinessTaskConfig>().Where(x => x.TaskType == request.TaskType && x.IsSkip)
.Select(x => new { x.Id, x.SourceName, x.MatchCondition }).ToListAsync();
if (configList.Count > 0)
{
var conditionList = configList.Select(x => new { x.Id, x.SourceName, MatchCondition = JsonConvert.DeserializeObject<ConditionContent>(x.MatchCondition) }).ToList();
foreach (var item in conditionList)
item.MatchCondition.SourceName = item.SourceName;
//internal async Task<bool> ShouldSkipAsync(TaskRequest request)
//{
// var configList = await TenantDb.Queryable<BusinessTaskConfig>().Where(x => x.TaskType == request.TaskType && x.IsSkip)
// .Select(x => new { x.Id, x.SourceName, x.MatchCondition }).ToListAsync();
// if (configList.Count > 0)
// {
// var conditionList = configList.Select(x => new { x.Id, x.SourceName, MatchCondition = JsonConvert.DeserializeObject<ConditionContent>(x.MatchCondition) }).ToList();
// foreach (var item in conditionList)
// item.MatchCondition.SourceName = item.SourceName;
return await ActionService.Value.IsMatchAsync(request, conditionList.Select(x => x.MatchCondition));
}
// return await ActionService.Value.IsMatchAsync(request, conditionList.Select(x => x.MatchCondition));
// }
return false;
}
// return false;
//}
/// <summary>
/// 创建并启动审批工作流
@ -516,8 +575,8 @@ 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 ? await GetNextTypeAsync(task) : null);
//ActionService.Value.TriggerAction(task);
return DataResult<TaskBaseTypeEnum?>.Success(task.TaskStatus == TaskStatusEnum.Complete ? await GetDefaultNextTypeAsync(task) : null);
}
catch (Exception ex)
{
@ -676,7 +735,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// <returns></returns>
protected internal async Task<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>> GetRecvUsersAsync(long id, BusinessType businessType, List<TaskBaseTypeEnum> taskTypes)
{
var biz = ActionService.Value.GetBusinessDataAsync(id, businessType);
var biz = await ActionService.Value.GetBusinessDataAsync(id, businessType);
var result = await TaskAllocationService.Value.GetAllotUserBySeaExportId(taskTypes, id, new TaskFlowDataContext(
(TaskFlowDataNameConst.Business, biz)
));

@ -1,5 +1,6 @@
using DS.Module.Core;
using DS.Module.Core.Extensions;
using DS.Module.UserModule;
using DS.WMS.Core.Code.Dtos;
using DS.WMS.Core.Sys.Dtos;
using DS.WMS.Core.Sys.Entity;
@ -204,6 +205,12 @@ public interface ICommonService
public DataResult<string> GetSequenceNext<T>();
/// <summary>
/// 获取最新业务单据编码
/// </summary>
/// <returns></returns>
public Task<DataResult<string>> GetSequenceNextAsync<T>(SqlSugarScopeProvider tenantDb, IUser user);
/// <summary>
/// 获取字典明细
/// </summary>

@ -24,6 +24,7 @@ using NPOI.SS.Formula.Functions;
using DS.WMS.Core.Flow.Dtos;
using Microsoft.Extensions.Logging;
using DS.Module.Core.Constants;
using DS.WMS.Core.Op.Entity;
namespace DS.WMS.Core.Sys.Method;
@ -1882,7 +1883,7 @@ public class CommonService : ICommonService
#endregion
}
/// <summary>
/// 计数 方式 重置规则
/// </summary>
@ -1979,6 +1980,210 @@ public class CommonService : ICommonService
return str;
}
#region 新的编码规则
/// <summary>
/// 获取最新业务单据编码
/// </summary>
/// <returns></returns>
public async Task<DataResult<string>> GetSequenceNextAsync<T>(SqlSugarScopeProvider tenantDb, IUser user)
{
//生成编号
string sequenceNewNo = "";
#region 获取序号生成器属性
var moduleName = typeof(T).Name.ToLower();
//获取序号生成器属性
var sequence = await db.Queryable<SysSequence>()
.FirstAsync(u => u.PermissionEntity.ToLower() == moduleName && u.Status == StatusEnum.Enable);
if (sequence != null)
{
var ruleList = await db.Queryable<SysSequenceRule>().OrderBy(x => x.OrderNo)
.Where(u => u.SequenceId == sequence.Id && u.Status == StatusEnum.Enable).ToListAsync();
var businessSeq = new BusinessSequence();
if (ruleList.Any())
{
int delimiterNum = 0;
for (global::System.Int32 i = 0; i < ruleList.Count; i++)
{
var item = ruleList[i];
delimiterNum++;
switch (item.RuleType)
{
case "const": //常量方式
sequenceNewNo += item.RuleValue;
break;
case "variable": //变量方式 TODO
if (item.RuleValue == "UserNumber")
{
var userInfo = await db.Queryable<SysUser>().FirstAsync(x => x.Id ==long.Parse(user.UserId));
if (userInfo.UserNumber.IsNull())
{
return await Task.FromResult(DataResult<string>.Failed("该用户编码未维护!"));
}
sequenceNewNo += userInfo.UserNumber;
}
break;
case "shortdate": //短日期 年2位月2位日期2位
sequenceNewNo += DateTime.Now.ToString("yyyyMMdd").Substring(2);
break;
case "date": //日期年4位
sequenceNewNo += DateTime.Now.ToString("yyyyMMdd");
break;
case "ydate": //年月年4位月2位
sequenceNewNo += DateTime.Now.ToString("yyyyMMdd").Substring(0, 6);
break;
case "sydate": //年月年2位月2位
sequenceNewNo += DateTime.Now.ToString("yyyyMMdd").Substring(2, 4);
break;
case "timestamp": //日期时间精确到毫秒
sequenceNewNo += DateTime.Now.ToString("yyyyMMddHHmmssffff");
break;
case "number": //计数,流水号
var prefix = sequenceNewNo;//前缀
businessSeq = await tenantDb.Queryable<BusinessSequence>().Where(x => x.SequenceId == sequence.Id && x.Prefix == prefix).FirstAsync();
int num = CurrentReset(sequence, item, businessSeq, tenantDb);
//计数拼接
sequenceNewNo += NumberingSeqRule(item, num).ToString();
//更新当前序号,
sequence.CurrentNo = num;
if (businessSeq.IsNull())
{
businessSeq = new BusinessSequence()
{
SequenceId = sequence.Id,
Prefix = prefix,
CurrentNo = num
};
}
else
{
businessSeq.CurrentNo = num;
}
break;
case "guid": //Guid
sequenceNewNo += GuidHelper.NewGuidFormatN();
break;
case "random": //随机数
Random random = new Random();
string strMax = "9".ToString().PadLeft(item.RuleValue.Length, '9');
string strRandom = random.Next(item.RuleValue.ToInt(), strMax.ToInt()).ToString(); //生成随机编号
sequenceNewNo += strRandom;
break;
}
if (!string.IsNullOrEmpty(sequence.SequenceDelimiter) && delimiterNum != ruleList.Count())
{
sequenceNewNo += sequence.SequenceDelimiter;
}
}
//当前编号
sequence.CurrentCode = sequenceNewNo;
sequence.CurrentReset = DateTime.Now.ToString("yyyyMMdd");
businessSeq.CurrentCode = sequenceNewNo;
businessSeq.CurrentReset = DateTime.Now.ToString("yyyyMMdd");
await db.Updateable(sequence).ExecuteCommandAsync();
await tenantDb.Storageable(businessSeq).ExecuteCommandAsync();
return await Task.FromResult(DataResult<string>.Success(sequenceNewNo));
}
else
{
return await Task.FromResult(DataResult<string>.Failed("未查询到业务编码对应的编码规则配置, 请检查编码规则配置!"));
}
}
else
{
return await Task.FromResult(DataResult<string>.Failed("请定义" + moduleName + "的单据编码!"));
}
#endregion
}
/// <summary>
/// 计数 方式 重置规则
/// </summary>
/// <param name="seq"></param>
/// <param name="seqRule"></param>
/// <returns></returns>
private static int CurrentReset(SysSequence seq, SysSequenceRule seqRule, BusinessSequence businessSeq, SqlSugarScopeProvider tenantDb)
{
int newNo = 0, ruleNo = 0;
try
{
ruleNo = seqRule.RuleValue.ToInt();
}
catch (Exception ex)
{
newNo = 1;
// Log4NetHelper.Error(ex.Message, ex);
}
switch (seq.SequenceReset)
{
case "D": //每天重置
if (!string.IsNullOrEmpty(seq.CurrentReset) && seq.CurrentReset != DateTime.Now.ToString("yyyyMMdd"))
{
newNo = 1;
}
break;
case "M": //每月重置
if (!string.IsNullOrWhiteSpace(seq.CurrentReset))
{
if (!seq.CurrentReset.Contains(DateTime.Now.ToString("yyyyMM")))
{
newNo = ruleNo;
}
}
else
{
newNo = 1;
}
break;
case "Y": //每年重置
if (!string.IsNullOrWhiteSpace(seq.CurrentReset))
{
if (!seq.CurrentReset.Contains(DateTime.Now.ToString("yyyy")))
{
newNo = ruleNo;
}
}
else
{
newNo = 1;
}
break;
}
if (newNo == 0)
{
if (businessSeq.IsNull()|| businessSeq.CurrentNo == 0)
{
newNo = ruleNo;
}
else
{
//当前序号+步长
//newNo = seq.CurrentNo + seq.Step;
newNo = businessSeq.CurrentNo + seq.Step;
}
}
return newNo;
}
#endregion
#endregion

@ -40,17 +40,17 @@ namespace DS.WMS.Core.TaskPlat.Entity
[SugarColumn(ColumnDescription = "所属主入口流程主键", IsNullable = true)]
public long? MainConfigId { get; set; }
///// <summary>
///// 下一流程主键
///// </summary>
//[SugarColumn(ColumnDescription = "下一流程主键", IsNullable = true)]
//public long? NextConfigId { get; set; }
/// <summary>
/// 父项流程主键
/// 下一流程主键列表(使用,分隔)
/// </summary>
[SugarColumn(ColumnDescription = "父项流程主键", IsNullable = true)]
public long? ParentConfigId { get; set; }
[SugarColumn(ColumnDescription = "下一流程主键", IsNullable = true, Length = 255)]
public string? NextConfigId { get; set; }
///// <summary>
///// 父项流程主键
///// </summary>
//[SugarColumn(ColumnDescription = "父项流程主键", IsNullable = true)]
//public long? ParentConfigId { get; set; }
/// <summary>
/// 当执行过程中发生异常时是否继续执行下一个节点

@ -65,6 +65,10 @@ namespace DS.WMS.Core.TaskPlat.Interface
/// <param name="taskBaseTypeEnum">业务类型</param>
/// <param name="userInfos">要转交的人员信息列表</param>
Task<DataResult> TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List<RecvUserInfo> userInfos);
Task<DataResult> TestTaskFlow(string taskType, long taskId);
/// <summary>
/// 测试用
/// </summary>
Task<DataResult> TestTaskFlow(string taskType, long taskId, int testType);
}
}

@ -271,18 +271,17 @@ namespace DS.WMS.Core.TaskPlat.Method
}
// 查出涉及到的订单
SeaExport? order = null;
SeaExportRes? order = null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (dataContext.ContainsKey(TaskFlowDataNameConst.Business))
{
var orderDto = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
order = orderDto.Adapt<SeaExport>();
order = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
}
else
{
order = await tenantDb.Queryable<SeaExport>()
.Where(x => x.Id == seaExportId)
.Select(x => new SeaExport
.Select(x => new SeaExportRes
{
Id = x.Id,
MBLNO = x.MBLNO,
@ -402,18 +401,17 @@ namespace DS.WMS.Core.TaskPlat.Method
}
// 查出涉及到的订单
SeaExport? order = null;
SeaExportRes? order = null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (dataContext.ContainsKey(TaskFlowDataNameConst.Business))
{
var orderDto = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
order = orderDto.Adapt<SeaExport>();
order = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
}
else
{
order = await tenantDb.Queryable<SeaExport>()
.Where(x => x.Id == seaExportId)
.Select(x => new SeaExport
.Select(x => new SeaExportRes
{
Id = x.Id,
MBLNO = x.MBLNO,

@ -19,6 +19,7 @@ using DS.WMS.Core.TaskPlat.Interface;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
@ -2194,7 +2195,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.ClearFilter(typeof(IOrgId))
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.Where(whereList)
.Where((t, a) => t.IS_PUBLIC == 1 || (t.IS_PUBLIC == 0 && a.Status != null && (t.CreateBy == userId || a.UserId == userId)))
.Where((t, a) => t.IS_PUBLIC == 1 || (t.IS_PUBLIC == 0 && a.Status != null && (a.UserId == userId))) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
.GroupBy((t, a) => new { t.TASK_TYPE, t.STATUS, a.Status, t.IS_PUBLIC })
.Select((t, a) => new
{
@ -2206,21 +2207,6 @@ namespace DS.WMS.Core.TaskPlat.Method
IsPublic = t.IS_PUBLIC
}).ToListAsync();
//var sql = tenantDb.Queryable<TaskBaseInfo>()
// .LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
// .Where(whereList)
// .Where((t, a) => t.IS_PUBLIC == 1 || (t.IS_PUBLIC == 0 && a.Status != null && (t.CreateBy == userId || a.UserId == userId)))
// .GroupBy((t, a) => new { t.TASK_TYPE, t.STATUS, a.Status, t.IS_PUBLIC })
// .Select((t, a) => new
// {
// Total = SqlFunc.AggregateDistinctCount(t.Id),
// TaskType = t.TASK_TYPE,
// TStatus = t.STATUS,
// AStatus = a.Status,
// //IsExcept = t.IS_EXCEPT,
// IsPublic = t.IS_PUBLIC
// }).ToSqlString();
//var exceptList = groupList
// .Where(t => t.IsExcept == 1).ToList();
@ -2678,7 +2664,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskType.ToString())
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (t.CreateBy == userId || a.UserId == userId)
&& (a.UserId == userId) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == status)
.OrderByDescending(t => t.Id);
}
@ -2697,7 +2683,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskType.ToString())
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (t.CreateBy == userId || a.UserId == userId)
&& (a.UserId == userId) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == status)
.OrderByDescending(t => t.Id);
}
@ -2749,32 +2735,72 @@ namespace DS.WMS.Core.TaskPlat.Method
return DataResult<CodePortRes>.FailedData(portInfo);
}
public async Task<DataResult> TestTaskFlow(string taskType, long taskId)
/// <summary>
/// 测试用
/// </summary>
public async Task<DataResult> TestTaskFlow(string taskType, long taskId, int testType)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskTypeEnum = (TaskBaseTypeEnum)Enum.Parse(typeof(TaskBaseTypeEnum), taskType);
TaskManageOrderMessageInfo p1 = new TaskManageOrderMessageInfo()
switch (testType)
{
Main = new TaskManageOrderMessageMainInfo()
{
BCInfo = new TaskManageOrderBCInfo()
// 任务编排执行测试
case 1:
{
Vessel = "TESTVESSEL"
var taskTypeEnum = (TaskBaseTypeEnum)Enum.Parse(typeof(TaskBaseTypeEnum), taskType);
TaskManageOrderMessageInfo p1 = new TaskManageOrderMessageInfo()
{
Main = new TaskManageOrderMessageMainInfo()
{
BCInfo = new TaskManageOrderBCInfo()
{
Vessel = "TESTVESSEL"
}
}
};
TaskFlowDataContext dataContext = new(
((TaskFlowDataNameConst.TaskManageOrderMessageInfo), p1),
(("Name"), "QD-ZXF"),
(("Age"), 19),
(("Height"), 160)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(taskTypeEnum, taskId, dataContext);
break;
}
}
};
TaskFlowDataContext dataContext = new(
((TaskFlowDataNameConst.TaskManageOrderMessageInfo), p1),
(("Name"), "QD-ZXF"),
(("Age"), 19),
(("Height"), 160)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(taskTypeEnum, taskId, dataContext);
// 分配测试
case 2:
{
var order = await tenantDb.Queryable<SeaExport>().Select<Core.Op.Dtos.SeaExportRes>().FirstAsync(x => x.Id == 1816649497120477184);
TaskFlowDataContext dataContext2 = new(
(TaskFlowDataNameConst.Business, order)
);
var taskAllocationService = serviceProvider.GetRequiredService<ITaskAllocationService>();
var result = await taskAllocationService.GetAllotUserBySeaExportId(new List<TaskBaseTypeEnum>() {
TaskBaseTypeEnum.INVOICE_BILL_MAIL,
TaskBaseTypeEnum.NOT_LOADED,
TaskBaseTypeEnum.NOT_SHIPMENG,
}, 1816649497120477184, dataContext2);
break;
}
// 工作流获取下一节点测试
case 3:
{
var order = await tenantDb.Queryable<SeaExport>().Select<Core.Op.Dtos.SeaExportRes>().FirstAsync(x => x.Id == 1816649497120477184);
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.Business, order)
);
TaskFlowRuner runer = new TaskFlowRuner(tenantDb, serviceProvider);
var result1 = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, null); // 首位
var result2 = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, 20001); // 正常
var result3 = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, 20002); // 分支判断
var result4 = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, 20003); // 分支结尾判断
var result5 = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, 20008); // 末位
break;
}
}
return DataResult.Successed("测试成功");
}

@ -212,7 +212,12 @@ namespace DS.WMS.Core.TaskPlat
flowLogDetail.ConfigId = executeConfig.Id;
// 如果当前节点要执行(或者配置了默认执行节点)取出下一批要进行条件判断的节点列表
waitMatchConfigList = configList.Where(x => x.ParentConfigId == executeConfig.Id).ToList();
waitMatchConfigList.Clear();
if (!string.IsNullOrEmpty(executeConfig.NextConfigId))
{
var ids = executeConfig.NextConfigId.Split(',').Where(x => !string.IsNullOrEmpty(x)).Select(x => Convert.ToInt64(x));
waitMatchConfigList = configList.Where(x => ids.Contains(x.Id)).ToList();
}
// 注入参数
var paramItemList = paramList.Where(x => x.ConfigId == executeConfig.Id).ToList();
@ -304,7 +309,7 @@ namespace DS.WMS.Core.TaskPlat
flowLogDetail.ElapsedMillisecond = stopwatch.ElapsedMilliseconds;
flowLogDetail.IsComplete = true;
await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync();
await tenantDb.CopyNew().Insertable(flowLogDetail).ExecuteCommandAsync();
}
catch (Exception ex)
{
@ -324,7 +329,7 @@ namespace DS.WMS.Core.TaskPlat
flowLogDetail.IsComplete = false;
flowLogDetail.IsSuccess = false;
await tenantDb.Insertable(flowLogDetail).ExecuteCommandAsync();
await tenantDb.CopyNew().Insertable(flowLogDetail).ExecuteCommandAsync();
if (executeConfig.IsExceptionContinue)
{
@ -337,7 +342,7 @@ namespace DS.WMS.Core.TaskPlat
}
}
await tenantDb.Insertable(flowLog).ExecuteCommandAsync();
await tenantDb.CopyNew().Insertable(flowLog).ExecuteCommandAsync();
return (flowLog.Id, flowLog.IsComplete, flowLog.IsSuccess);
}
@ -361,78 +366,102 @@ namespace DS.WMS.Core.TaskPlat
/// <summary>
/// 根据当前节点Id获取工作流下一个任务类型
/// </summary>
/// <param name="workFlowType">工作流流程类型</param>
/// <param name="dataContext"></param>
/// <param name="currentConfigId">当前执行的配置Id如果为空则返回首个任务类型</param>
/// <returns>下一个任务类型下一节点Id</returns>
public async Task<(TaskBaseTypeEnum taskType, long configId)?> GetWorkFlowNextConfig(TaskFlowDataContext dataContext, long? currentConfigId = null)
public async Task<(TaskBaseTypeEnum taskType, long configId)?> GetWorkFlowNextConfig(TaskBaseTypeEnum workFlowType, TaskFlowDataContext dataContext, long? currentConfigId = null)
{
var allConfigList = await tenantDb.Queryable<TaskFlowConfig>()
.Where(t => t.MainConfigId == SqlFunc.Subqueryable<TaskFlowConfig>().Where(x => x.IsMain && x.TaskType == "WORK_FLOW").Select(x => x.Id))
.Where(t => t.MainConfigId == SqlFunc.Subqueryable<TaskFlowConfig>().Where(x => x.IsMain && x.TaskType == workFlowType.ToString()).Select(x => x.Id))
.OrderBy(t => t.Id)
.ToListAsync();
if (allConfigList.Count == 0) return null;
List<TaskFlowConfig> waitMatchConfigList = new();
long configId;
if (currentConfigId == null)
{
waitMatchConfigList.Add(allConfigList.First(x => x.IsMain));
configId = allConfigList.First(x => x.IsMain).Id;
}
else
{
var currentConfig = allConfigList.FirstOrDefault(x => x.Id == currentConfigId);
if (currentConfig == null) return null;
waitMatchConfigList.AddRange(allConfigList.Where(x => x.ParentConfigId == currentConfig.Id));
configId = currentConfigId.Value;
}
if (waitMatchConfigList.Count == 0) return null;
List<TaskFlowConfig> waitMatchConfigList = new();
for (int i = 0; i < allConfigList.Count; i++)
{
var currentConfig = allConfigList.FirstOrDefault(x => x.Id == configId);
if (currentConfig == null || string.IsNullOrEmpty(currentConfig.NextConfigId))
return null;
var configIdList = waitMatchConfigList.Select(x => x.Id);
var conditionList = await tenantDb.Queryable<TaskFlowCondition>()
.Where(x => configIdList.Contains(x.ConfigId))
.ToListAsync();
var nextIds = currentConfig.NextConfigId.Split(',').Where(x => !string.IsNullOrEmpty(x)).Select(x => Convert.ToInt64(x));
waitMatchConfigList = allConfigList.Where(x => nextIds.Contains(x.Id)).ToList();
var matchedConfigList = new List<TaskFlowConfig>();
foreach (var item in waitMatchConfigList)
{
var condition = conditionList.FirstOrDefault(x => x.ConfigId == item.Id);
if (condition == null || string.IsNullOrEmpty(condition.Content))
{
matchedConfigList.Add(item);
}
else
if (waitMatchConfigList.Count == 0) return null; // 如果走了这一步的return说明配置有问题配置了下一节点的id但是却查不到
var configIdList = waitMatchConfigList.Select(x => x.Id);
var conditionList = await tenantDb.Queryable<TaskFlowCondition>()
.Where(x => configIdList.Contains(x.ConfigId))
.ToListAsync();
var matchedConfigList = new List<TaskFlowConfig>();
foreach (var item in waitMatchConfigList)
{
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
if (ConditionHelper.IsPass(contitionContent, dataContext))
var condition = conditionList.FirstOrDefault(x => x.ConfigId == item.Id);
if (condition == null || string.IsNullOrEmpty(condition.Content))
{
matchedConfigList.Add(item);
}
else
{
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
if (ConditionHelper.IsPass(contitionContent, dataContext))
{
matchedConfigList.Add(item);
}
}
}
}
TaskFlowConfig? executeConfig = null;
if (matchedConfigList.Count == 1)
{
executeConfig = matchedConfigList[0];
}
else if (matchedConfigList.Count > 1)
{
executeConfig = matchedConfigList.FirstOrDefault(x => x.IsMoreMatchDefault);
}
if (executeConfig == null)
{
executeConfig = waitMatchConfigList.FirstOrDefault(x => x.IsUnMatchDefault);
}
TaskFlowConfig? executeConfig = null;
if (matchedConfigList.Count == 1)
{
executeConfig = matchedConfigList[0];
}
else if (matchedConfigList.Count > 1)
{
executeConfig = matchedConfigList.FirstOrDefault(x => x.IsMoreMatchDefault);
}
if (executeConfig == null) return null;
if (executeConfig == null)
{
executeConfig = waitMatchConfigList.FirstOrDefault(x => x.IsUnMatchDefault);
}
var taskType = await tenantDb.Queryable<TaskFlowModule>().Where(x => x.Id == executeConfig.ExecuteModuleId).Select(x => x.TaskType).FirstAsync();
if (executeConfig == null)
{
// 如果最终还是没有匹配到,则需要判断情况
// 如果待匹配的分支只有1个则继续循环判断下一节点否则如果待匹配的分支有多个则无法判断下一节点
if (waitMatchConfigList.Count == 1)
{
configId = waitMatchConfigList[0].Id;
continue;
}
else
{
return null;
}
}
else
{
var taskType = await tenantDb.Queryable<TaskFlowModule>().Where(x => x.Id == executeConfig.ExecuteModuleId).Select(x => x.TaskType).FirstAsync();
if (taskType != null && Enum.TryParse(typeof(TaskBaseTypeEnum), taskType, out object? temp))
{
return ((TaskBaseTypeEnum)temp, executeConfig.Id);
if (taskType != null && Enum.TryParse(typeof(TaskBaseTypeEnum), taskType, out object? temp))
{
return ((TaskBaseTypeEnum)temp, executeConfig.Id);
}
}
}
return null;
}

@ -75,14 +75,16 @@ namespace DS.WMS.PrintApi.Service
//var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
//str.Json = req.JsonDataStr;
//dataSource.ConnectionString = str.ConnectionString;
var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
str.Json = req.JsonDataStr;
//var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
//str.Json = req.JsonDataStr;
//str.JsonSchema.InitSchema();
//report.Dictionary.Connections.Clear();
if (report.Dictionary.Connections.Count == 0)
{
//重置数据源
report.Dictionary.Connections.Add(new JsonDataSourceConnection()
{
ConnectionString = str.ConnectionString,
ConnectionString = $"JSON={req.JsonDataStr};Encoding=utf-8",
Name = "Connection",
});
}
@ -90,11 +92,12 @@ namespace DS.WMS.PrintApi.Service
{
var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
dataSource.Name = "Connection";
dataSource.ConnectionString = str.ConnectionString;
dataSource.ConnectionString = $"JSON={req.JsonDataStr};Encoding=utf-8";
}
report.Save(printFile);
report.Prepare();
var printName = string.Empty;
var saveFile = string.Empty;
@ -184,12 +187,27 @@ namespace DS.WMS.PrintApi.Service
//dataSource.ConnectionString = str.ConnectionString;
var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
str.Json = req.JsonDataStr;
//if (report.Dictionary.Connections.Count == 0)
//{
// //重置数据源
// report.Dictionary.Connections.Add(new JsonDataSourceConnection()
// {
// ConnectionString = str.ConnectionString,
// Name = "Connection",
// });
//}
//else
//{
// var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
// dataSource.Name = "Connection";
// dataSource.ConnectionString = str.ConnectionString;
//}
if (report.Dictionary.Connections.Count == 0)
{
//重置数据源
report.Dictionary.Connections.Add(new JsonDataSourceConnection()
{
ConnectionString = str.ConnectionString,
ConnectionString = $"JSON={req.JsonDataStr};Encoding=utf-8",
Name = "Connection",
});
}
@ -197,9 +215,8 @@ namespace DS.WMS.PrintApi.Service
{
var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
dataSource.Name = "Connection";
dataSource.ConnectionString = str.ConnectionString;
dataSource.ConnectionString = $"JSON={req.JsonDataStr};Encoding=utf-8";
}
report.Save(printFile);
report.Save(printFile);
@ -365,21 +382,37 @@ namespace DS.WMS.PrintApi.Service
report.Load(printFile);
var str = new FastReport.Data.JsonConnection.JsonDataSourceConnectionStringBuilder();
str.Json = JsonConvert.SerializeObject(data);
//if (report.Dictionary.Connections.Count == 0)
//{
// //重置数据源
// report.Dictionary.Connections.Add(new JsonDataSourceConnection()
// {
// ConnectionString = str.ConnectionString,
// Name = "Connection",
// });
//}
//else {
// var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
// dataSource.Name = "Connection";
// dataSource.ConnectionString = str.ConnectionString;
//}
if (report.Dictionary.Connections.Count == 0)
{
//重置数据源
report.Dictionary.Connections.Add(new JsonDataSourceConnection()
{
ConnectionString = str.ConnectionString,
ConnectionString = $"JSON={JsonConvert.SerializeObject(data)};Encoding=utf-8",
Name = "Connection",
});
}
else {
var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
else
{
var dataSource = report.Dictionary.Connections[0] as JsonDataSourceConnection;
dataSource.Name = "Connection";
dataSource.ConnectionString = str.ConnectionString;
dataSource.ConnectionString = $"JSON={JsonConvert.SerializeObject(data)};Encoding=utf-8";
}
report.Save(printFile);
report.Prepare();

@ -3,6 +3,7 @@ using DS.Module.Core.Data;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.TaskPlat;
using DS.WMS.Core.TaskPlat.Dtos;
using DS.WMS.Core.TaskPlat.Entity;
using DS.WMS.Core.TaskPlat.Interface;
@ -53,27 +54,4 @@ public class TaskAllocationController : ApiController
return result;
}
/// <summary>
/// (测试)任务台任务分配
/// </summary>
/// <returns></returns>
[HttpPost("Test")]
public async Task Test()
{
var saasDbService = serviceProvider.GetService<ISaasDbService>();
var user = serviceProvider.GetService<IUser>();
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var order = await tenantDb.Queryable<SeaExport>().FirstAsync(x => x.Id == 1816649497120477184);
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.Business, order)
);
var result = taskAllocationService.GetAllotUserBySeaExportId(new List<TaskBaseTypeEnum>() {
TaskBaseTypeEnum.INVOICE_BILL_MAIL,
TaskBaseTypeEnum.NOT_LOADED,
TaskBaseTypeEnum.NOT_SHIPMENG,
}, 1816649497120477184, dataContext);
}
}

@ -212,12 +212,11 @@ public class TaskManageController : ApiController
}
/// <summary>
/// 测试执行任务编排
/// 测试
/// </summary>
/// <returns></returns>
[HttpGet("TestTaskFlow")]
public async Task<DataResult> TestTaskFlow([FromQuery] string taskType, [FromQuery] long taskId)
public async Task<DataResult> TestTaskFlow([FromQuery] string taskType, [FromQuery] long taskId, [FromQuery] int testType)
{
return await taskManageService.TestTaskFlow(taskType, taskId);
return await taskManageService.TestTaskFlow(taskType, taskId, testType);
}
}

@ -60,7 +60,7 @@ public class SaasDBUpdateTest
var tenantDb = saasService.GetBizDbScopeById(item.TenantId).CopyNew();
StaticConfig.CodeFirst_MySqlCollate = "utf8mb4_0900_ai_ci"; //较高版本支持
//tenantDb.CodeFirst.InitTables(types); //指定表空间下的实体
tenantDb.CodeFirst.InitTables(typeof(CodeCountry));//指定更新特定实体
tenantDb.CodeFirst.InitTables(typeof(BusinessSequence));//指定更新特定实体
}
Assert.True(true);

@ -265,6 +265,6 @@ public class SaasTest
(TaskFlowDataNameConst.Business, order)
);
TaskFlowRuner runer = new TaskFlowRuner(tenantDb, _serviceProvider);
var result =await runer.GetWorkFlowNextConfig(dataContext, null);
var result = await runer.GetWorkFlowNextConfig(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext);
}
}
Loading…
Cancel
Save