diff --git a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs index 305c165a..065a5889 100644 --- a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs +++ b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs @@ -1554,6 +1554,12 @@ public static class MultiLanguageConst public const string TaskMailSenderNotNull = "Task_Mail_Sender_Not_Null"; [Description("驳回成功")] public const string TaskRejected = "Task_Rejected"; + [Description("未传入子任务信息")] + public const string SubTaskCannotNull = "Sub_Task_Cannot_Null"; + [Description("同一任务的步骤类型不可重复")] + public const string DuplicateStepType = "Duplicate_Step_Type"; + [Description("此任务尚有未完成的子任务或前置条件")] + public const string UnfinishedItems = "Unfinished_Items"; #endregion #region 任务台相关 diff --git a/ds-wms-service/DS.Module.Core/Enums/ContainerManagementEnum.cs b/ds-wms-service/DS.Module.Core/Enums/ContainerManagementEnum.cs index d842b156..dd6c4a56 100644 --- a/ds-wms-service/DS.Module.Core/Enums/ContainerManagementEnum.cs +++ b/ds-wms-service/DS.Module.Core/Enums/ContainerManagementEnum.cs @@ -3,11 +3,57 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Net.NetworkInformation; +using System.Reflection; using System.Text; using System.Threading.Tasks; namespace DS.Module.Core.Enums { + public class EnumsHelper { + ///// + ///// 根据枚举值获取枚举Description + ///// + ///// + ///// + ///// + //public static string GetEnumDescriptionFromValue(T val) + //{ + // Type t = typeof(T); + // MemberInfo[] field = t.GetMember(val.ToString()); + // object[] attrs = field?.FirstOrDefault().GetCustomAttributes(typeof(DescriptionAttribute), true); + // string description = ((DescriptionAttribute)attrs.FirstOrDefault()).Description; + // return description; + //} + + + /// + /// 根据Description获取枚举 + /// + /// + /// + /// + /// + ///// 调用示例 + ///GetEnumByDescription("description") + + public T GetEnumByDescription(string description) where T : Enum + { + System.Reflection.FieldInfo[] fields = typeof(T).GetFields(); + foreach (System.Reflection.FieldInfo field in fields) + { + object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false); //获取描述属性 + if (objs.Length > 0 && (objs[0] as DescriptionAttribute).Description == description) + { + return (T)field.GetValue(null); + } + } + + throw new ArgumentException(string.Format("{0} 未能找到对应的枚举.", description), "Description"); + } + + } + + /// /// 箱管 箱上线状态 /// @@ -458,4 +504,8 @@ namespace DS.Module.Core.Enums [Description("审核通过")] 审核通过 = 1100, } + + + + } diff --git a/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CMServiceBase.cs b/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CMServiceBase.cs index 9e02f738..445b2cbe 100644 --- a/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CMServiceBase.cs +++ b/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CMServiceBase.cs @@ -194,6 +194,7 @@ namespace DS.WMS.ContainerManagement.Info.Method CtnValue_Base = b.CtnValue_Base, CreateTime= c.CreateTime, ProductionDate= b.ProductionDate, + CtnFlowStateId = c.CtnFlowStateId, }); return query1; diff --git a/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CM_State_Change_TemplatImportService.cs b/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CM_State_Change_TemplatImportService.cs index fcab69b1..f2c40a5b 100644 --- a/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CM_State_Change_TemplatImportService.cs +++ b/ds-wms-service/DS.WMS.Core/ContainerManagement/Method/CM_State_Change_TemplatImportService.cs @@ -48,6 +48,7 @@ using DS.WMS.Core.Code.Entity; using NPOI.OpenXmlFormats; using System.Runtime.CompilerServices; using iText.StyledXmlParser.Jsoup.Safety; +using Dm; namespace DS.WMS.ContainerManagement.Info.Method; @@ -1121,7 +1122,45 @@ public class CM_State_Change_TemplatImportService : CMServiceBase, ICM_State_Cha if (field != null && dt.Columns.Contains(字段.ColumnTitle)) { var _value = row[字段.ColumnTitle]; - field.SetValue(newchange, _value); + //field.SetValue(newchange, _value); + + if (field.PropertyType.IsGenericType) + { + //if (field.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + //{ + if (field.PropertyType.GetGenericArguments()[0] == typeof(DateTime) || field.PropertyType.GetGenericArguments()[0] == typeof(DateTime?)) + { + if (_value != null) + { + try { + var _dt = Convert.ToDateTime(_value); + field.SetValue(newchange, _dt); + } + catch (Exception e) + { + var _dt2=DateTime.FromOADate(Convert.ToDouble(_value)); + field.SetValue(newchange, _dt2); + } + } + } + else + if (field.PropertyType.GetGenericArguments()[0] == typeof(decimal) || field.PropertyType.GetGenericArguments()[0] == typeof(decimal?)) + { + if (_value != null) + { + field.SetValue(newchange, Convert.ToDecimal(_value)); + } + } + else + { + field.SetValue(newchange, _value); + } + //} + } + else + { + field.SetValue(newchange, _value); + } } else if (field == null && 字段.FieldTitle == "XXDM") @@ -1133,8 +1172,24 @@ public class CM_State_Change_TemplatImportService : CMServiceBase, ICM_State_Cha { XXCM = row[字段.ColumnTitle].ToString(); } + else + if (field == null && 字段.FieldTitle == "CtnFlowState") + { + //XXCM = row[字段.ColumnTitle].ToString(); + //根据字典表对应一个值 + field = type.GetProperty("CtnFlowStateId"); + if (field != null) { + var tablevalue=row[字段.ColumnTitle].ToString(); + + var eh = new EnumsHelper(); + var _value=eh.GetEnumByDescription(tablevalue); + + field.SetValue(newchange, _value); + } + + } //else - + //if (field == null && 字段.FieldTitle == "Vessel") //{ // Vessel = row[字段.ColumnTitle].ToString(); diff --git a/ds-wms-service/DS.WMS.Core/Fee/Dtos/Report/ProfitAccounting.cs b/ds-wms-service/DS.WMS.Core/Fee/Dtos/Report/ProfitAccounting.cs index 5aa013c9..206dd7fc 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Dtos/Report/ProfitAccounting.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Dtos/Report/ProfitAccounting.cs @@ -101,7 +101,9 @@ namespace DS.WMS.Core.Fee.Dtos.Report /// /// 开船日期 /// - public DateTime? ETD { get; set; } + public string? ETD => ETDValue.HasValue ? ETDValue.Value.ToString("yyyy-MM-dd") : string.Empty; + + public DateTime? ETDValue { get; set; } ///// ///// 预抵日期 @@ -219,14 +221,14 @@ namespace DS.WMS.Core.Fee.Dtos.Report public string StlName { get; set; } /// - /// 件数 + /// 包装 /// - public int? PKGS { get; set; } + public string? KindPkgsName { get; set; } /// - /// 包装 + /// 件数 /// - public string? KindPkgs { get; set; } + public int? PKGS { get; set; } /// /// 毛重 @@ -293,6 +295,29 @@ namespace DS.WMS.Core.Fee.Dtos.Report /// public int ECCU { get; set; } + /// + /// 船公司 + /// + public string? Carrier { get; set; } + + /// + /// 船名 + /// + public string? Vessel { get; set; } + + /// + /// 航次 + /// + public string? Voyno { get; set; } + + /// + /// 内部航次 + /// + public string? InnerVoyno { get; set; } + + /// + /// 费用统计 + /// public FeeAuditStatistics Statistics { get; set; } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/ProfitAccountingReport.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/ProfitAccountingReport.cs index 605c45d2..06bd46c8 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/ProfitAccountingReport.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/ProfitAccountingReport.cs @@ -7,6 +7,7 @@ using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.TaskInteraction.Dtos; using Masuit.Tools.Systems; +using SqlSugar; namespace DS.WMS.Core.Fee.Method.ReportProviders { @@ -28,6 +29,7 @@ namespace DS.WMS.Core.Fee.Method.ReportProviders .Select((s, c) => new ProfitAccounting { CustomerCode = c.CodeName, + ETDValue = s.ETD, Sale = s.Sale, Operator = s.OperatorName, CustomerService = s.CustomerServiceName, diff --git a/ds-wms-service/DS.WMS.Core/Op/EDI/VOLTAEdiHelper.cs b/ds-wms-service/DS.WMS.Core/Op/EDI/VOLTAEdiHelper.cs index 680a7b23..c9929a44 100644 --- a/ds-wms-service/DS.WMS.Core/Op/EDI/VOLTAEdiHelper.cs +++ b/ds-wms-service/DS.WMS.Core/Op/EDI/VOLTAEdiHelper.cs @@ -941,7 +941,7 @@ namespace DS.WMS.Core.Op.EDI Shipping = formatEdiStr("txt", bill.SHIPPER); - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (ShippingList.Count != 0 && Shipping.Length > 0) { @@ -954,31 +954,31 @@ namespace DS.WMS.Core.Op.EDI Shipping = formatEdiStr("txt", bill.CONSIGNEE); - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (ShippingList.Count != 0 && Shipping.Length > 0) { //2024-09-13 韩工确认最大行数6改为9 - r.WriteLine("21::" + formatListStr(ShippingList, 9) + "'"); + r.WriteLine("21::" + formatListStr(ShippingList, 6) + "'"); icount = icount + 1; } Shipping = formatEdiStr("txt", bill.NOTIFYPARTY); - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (ShippingList.Count != 0 && Shipping.Length > 0) { //2024-09-13 韩工确认最大行数6改为9 - r.WriteLine("22::" + formatListStr(ShippingList, 9) + "'"); + r.WriteLine("22::" + formatListStr(ShippingList, 6) + "'"); icount = icount + 1; } Shipping = formatEdiStr("txt", !string.IsNullOrWhiteSpace(bill.NOTIFYPARTY2) ? bill.NOTIFYPARTY2 : ""); - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (!string.IsNullOrWhiteSpace(Shipping)) { @@ -991,7 +991,7 @@ namespace DS.WMS.Core.Op.EDI } Shipping = bill.AMSCONSIGNEE; - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (!string.IsNullOrWhiteSpace(Shipping)) { @@ -1002,7 +1002,7 @@ namespace DS.WMS.Core.Op.EDI Shipping = bill.AMSNOTIFYPARTY; - ShippingList = formatlengthStr(Shipping, 35); + ShippingList = formatlengthStr(Shipping, 75); if (!string.IsNullOrWhiteSpace(Shipping)) { diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskCreationRequest.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskCreationRequest.cs index 49eeb3b5..135b9ee1 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskCreationRequest.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskCreationRequest.cs @@ -1,4 +1,5 @@ using DS.Module.Core; +using DS.WMS.Core.TaskInteraction.Entity; namespace DS.WMS.Core.TaskInteraction.Dtos { diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs index 0e95262a..68fbb364 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs @@ -39,11 +39,31 @@ namespace DS.WMS.Core.TaskInteraction.Dtos /// public string TaskTypeName { get; set; } = string.Empty; + /// + /// 父级ID(用于子任务) + /// + public long? ParentId { get; set; } + + /// + /// 父级业务ID(用于子任务) + /// + public long? ParentBusinessId { get; set; } + /// /// 附加数据(内部使用) /// public object? ExtraData { get; set; } + /// + /// 是否自动同步更新主任务状态 + /// + public bool AutoSync { get; set; } + + /// + /// 任务步骤 + /// + public List? Steps { get; set; } + /// /// 确定当前对象是否有效 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskStepDto.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskStepDto.cs new file mode 100644 index 00000000..09eefd18 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskStepDto.cs @@ -0,0 +1,35 @@ +using DS.WMS.Core.TaskInteraction.Entity; +using SqlSugar; + +namespace DS.WMS.Core.TaskInteraction.Dtos +{ + /// + /// 任务步骤 + /// + public class TaskStepDto + { + /// + /// 步骤类型 + /// + [SugarColumn(ColumnDescription = "明细类型")] + public StepType Type { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnDescription = "名称", Length = 50, IsNullable = true)] + public string? Name { get; set; } + + /// + /// 值 + /// + [SugarColumn(ColumnDescription = "值", IsNullable = true)] + public object? Value { get; set; } + + /// + /// 是否已完成 + /// + [SugarColumn(ColumnDescription = "是否已完成")] + public bool IsCompleted { get; set; } + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTask.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTask.cs index 3cad0101..eb277583 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTask.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/BusinessTask.cs @@ -20,7 +20,7 @@ namespace DS.WMS.Core.TaskInteraction.Entity /// /// 上级任务ID /// - [SugarColumn(ColumnDescription = "上级任务ID")] + [SugarColumn(ColumnDescription = "上级任务ID", IsNullable = true)] public long? ParentId { get; set; } /// @@ -35,6 +35,12 @@ namespace DS.WMS.Core.TaskInteraction.Entity [SugarColumn(ColumnDescription = "业务类型", IsNullable = false)] public BusinessType? BusinessType { get; set; } + /// + /// 上级业务ID + /// + [SugarColumn(ColumnDescription = "上级业务ID", IsNullable = true)] + public long? ParentBusinessId { get; set; } + /// /// 任务类型 /// @@ -101,5 +107,11 @@ namespace DS.WMS.Core.TaskInteraction.Entity /// [SugarColumn(ColumnDescription = "审批驳回理由", Length = 200, IsNullable = true)] public string? RejectReason { get; set; } + + /// + /// 任务步骤 + /// + [Navigate(NavigateType.OneToMany, nameof(TaskStep.TaskId))] + public List? Steps { get; set; } } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskStep.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskStep.cs new file mode 100644 index 00000000..5893d296 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskStep.cs @@ -0,0 +1,147 @@ +using System.ComponentModel; +using Newtonsoft.Json; +using SqlSugar; + +namespace DS.WMS.Core.TaskInteraction.Entity +{ + /// + /// 任务步骤表 + /// + [SugarTable("business_task_step", "任务步骤表")] + public class TaskStep + { + /// + /// ID + /// + [SugarColumn(IsPrimaryKey = true)] + public long Id { get; set; } + + /// + /// 任务ID + /// + [SugarColumn(ColumnDescription = "任务ID")] + public long TaskId { get; set; } + + /// + /// 步骤类型 + /// + [SugarColumn(ColumnDescription = "明细类型")] + public StepType Type { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnDescription = "名称", Length = 50, IsNullable = true)] + public string? Name { get; set; } + + /// + /// 值 + /// + [SugarColumn(ColumnDescription = "值", IsNullable = true)] + public string? Value { get; set; } + + /// + /// 是否已完成 + /// + [SugarColumn(ColumnDescription = "是否已完成")] + public bool IsCompleted { get; set; } + + /// + /// 排序值 + /// + [SugarColumn(ColumnDescription = "排序值")] + public int SortOrder { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnDescription = "创建人", IsNullable = false)] + public long CreateBy { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnDescription = "创建时间", IsNullable = false)] + public DateTime CreateTime { get; set; } + + /// + /// 更新人 + /// + [SugarColumn(ColumnDescription = "更新人", IsNullable = true)] + public long? UpdateBy { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnDescription = "更新时间", IsNullable = true)] + public DateTime? UpdateTime { get; set; } + + /// + /// 返回指定类型的值 + /// + /// 值的类型 + /// + public T? GetValue() + { + if (string.IsNullOrEmpty(Value)) + return default; + + var type = typeof(T); + + if (type.IsEnum) + return (T)Enum.Parse(type, Value); + + if (!type.IsClass) + return (T)Convert.ChangeType(Value, type); + + return JsonConvert.DeserializeObject(Value); + } + + /// + /// 设置值 + /// + /// 要设置的值 + /// + public void SetValue(object? value) + { + if (value == null) + return; + + var type = value.GetType(); + if (type.IsClass && type != typeof(string)) + { + Value = JsonConvert.SerializeObject(value); + } + else + { + Value = value.ToString(); + } + + } + } + + + /// + /// 任务步骤类型 + /// + public enum StepType + { + /// + /// 未指定 + /// + [Description("未指定")] + NotSpecified = 0, + + /// + /// 客户确认 + /// + [Description("客户确认")] + CustomerConfirm = 1, + + /// + /// 国外代理确认 + /// + [Description("国外代理确认")] + ForeignAgentConfirm = 2, + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskService.cs index e2baabd0..42b416da 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskService.cs @@ -58,6 +58,14 @@ namespace DS.WMS.Core.TaskInteraction.Interface /// Task SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true); + /// + /// 设置任务步骤状态 + /// + /// + /// 是否使用事务 + /// + Task SetStepsAsync(TaskRequest request, bool useTransaction = true); + /// /// 更新任务台描述 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs index 2310a3e9..7e3838da 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/ActionExecutor/BLConfirm/SubBLConfirmActionExecutor.cs @@ -1,16 +1,19 @@ -using DS.WMS.Core.TaskInteraction.Dtos; +using DS.Module.Core; +using DS.WMS.Core.Op.Entity; +using DS.WMS.Core.TaskInteraction.Dtos; +using DS.WMS.Core.TaskInteraction.Entity; using DS.WMS.Core.TaskInteraction.Interface; -using DS.WMS.Core.TaskPlat.Interface; +using Masuit.Tools.Systems; using Microsoft.Extensions.DependencyInjection; namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm { /// - /// 分单提单确认 + /// 分单提单确认动作 /// public class SubBLConfirmActionExecutor : ServiceBase, IActionExecutor { - ITaskManageBCService bCService; + //ITaskManageBCService bCService; ISeaExportTaskService taskService; ITaskLogService logService; @@ -20,7 +23,7 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm /// public SubBLConfirmActionExecutor(IServiceProvider provider) : base(provider) { - bCService = provider.GetRequiredService(); + //bCService = provider.GetRequiredService(); taskService = provider.GetRequiredService(); logService = provider.GetRequiredService(); } @@ -32,8 +35,77 @@ namespace DS.WMS.Core.TaskInteraction.Method.ActionExecutor.BLConfirm /// public async Task ExecuteAsync(ActionExecutionContext context) { - + //if (await taskService) + //{ + //} + + var bills = await TenantDb.Queryable().Where(x => x.BusinessId == context.TaskInfo.BusinessId) + .Select(x => new + { + x.Id, + x.HBLNO, + x.BillType, + x.Vessel, + x.Voyno, + x.ETD, + }).ToListAsync(); + if (bills.Count == 0) + return; + + DataResult result; + long userId = long.Parse(User.UserId); + var dtNow = DateTime.Now; + await TenantDb.Ado.BeginTranAsync(); + try + { + foreach (var bill in bills) + { + var req = new TaskCreationRequest + { + ParentId = context.TaskInfo.Id, + ParentBusinessId = context.TaskInfo.BusinessId, + BusinessId = bill.Id, + BusinessType = context.TaskInfo.BusinessType, + TaskTypeName = TaskBaseTypeEnum.WAIT_SUB_BILL_CONFIRM.ToString(), + TaskTitle = $"{bill.BillType} {bill.HBLNO} {bill.ETD} {bill.Vessel}|{bill.Voyno}", + Steps = [] + }; + + req.Steps.Add(new TaskStepDto + { + Type = StepType.CustomerConfirm, + Name = StepType.CustomerConfirm.ToString() + }); + req.Steps.Add(new TaskStepDto + { + Type = StepType.ForeignAgentConfirm, + Name = StepType.ForeignAgentConfirm.ToString() + }); + + result = await taskService.CreateTaskAsync(req, false); + if (!result.Succeeded) + { + await logService.WriteLogAsync(new BusinessTask + { + BusinessId = req.BusinessId, + BusinessType = req.BusinessType, + TaskStatus = TaskStatusEnum.Create, + TaskType = req.TaskType, + CreateBy = userId, + CreateTime = dtNow + }, $"创建【{req.TaskType.GetDescription()}】任务时出错:" + result.Message); + return; + } + } + + await TenantDb.Ado.CommitTranAsync(); + } + catch (Exception ex) + { + await TenantDb.Ado.RollbackTranAsync(); + await ex.LogAsync(Db); + } } } diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailGenerator.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailGenerator.cs index 70bb5b89..c40575d4 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailGenerator.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/MailGenerator.cs @@ -433,7 +433,7 @@ namespace DS.WMS.Core.TaskInteraction.Method SendTo = sendTo, Title = title, Body = content, - CCTo = string.Join(",", ccList), + CCTo = string.Join(";", ccList), ShowName = senderConfig.ShowName.IsNullOrEmpty() ? templateModel.Sender.DisplayName : senderConfig.ShowName, Account = senderConfig.MailAccount, senderConfig.Password, diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs index 65a96af4..f12f668f 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs @@ -1,5 +1,4 @@ using System.Text; -using System.Threading.Tasks; using DS.Module.Core; using DS.Module.Core.Data; using DS.Module.Core.Helpers; @@ -245,6 +244,9 @@ namespace DS.WMS.Core.TaskInteraction.Method return result; } + long userId = long.Parse(User.UserId); + DateTime dtNow = DateTime.Now; + if (useTransaction) await TenantDb.Ado.BeginTranAsync(); try @@ -355,20 +357,40 @@ namespace DS.WMS.Core.TaskInteraction.Method task = new BusinessTask { + ParentId = request.ParentId, BusinessId = request.BusinessId, BusinessType = request.BusinessType, + ParentBusinessId = request.ParentBusinessId, TaskType = request.TaskType, TaskStatus = TaskStatusEnum.Create, RecvUsers = string.Join(',', info.Main.RecvUserInfoList.Select(x => x.RecvUserId)) ?? string.Empty, NextType = request.NextType, - CreateBy = long.Parse(User.UserId), - CreateTime = DateTime.Now + CreateBy = userId, + CreateTime = dtNow }; if (IsOrderType(request.TaskType) && !task.NextType.HasValue) task.NextType = await GetNextTypeAsync(task); await TenantDb.Insertable(task).ExecuteCommandAsync(); + if (request.Steps?.Count > 0) + { + if (request.Steps.Where(x => x.Type != StepType.NotSpecified).GroupBy(x => x.Type).Select(x => x.Key).Count() > 1) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.DuplicateStepType)); + + var steps = request.Steps.Select(x => new TaskStep + { + TaskId = task.Id, + IsCompleted = x.IsCompleted, + Name = x.Name, + Type = x.Type, + SortOrder = request.Steps.IndexOf(x), + CreateBy = userId, + CreateTime = dtNow + }).ToList(); + + await TenantDb.Insertable(request.Steps).ExecuteCommandAsync(); + } result = await OnTaskCreated(task); if (!result.Succeeded) @@ -542,8 +564,14 @@ namespace DS.WMS.Core.TaskInteraction.Method return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskNotExists)); if (task.TaskStatus == TaskStatusEnum.Complete) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted)); - //if (task.TaskStatus == TaskStatusEnum.Cancel) - // return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCancelled)); + + //检查是否有未完成的任务步骤 + var steps = await TenantDb.Queryable().Where(x => x.TaskId == task.Id && !x.IsCompleted) + .Select(x => new { x.Type, x.Name }).ToListAsync(); + if (steps.Count > 0) + return DataResult.Failed( + MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.UnfinishedItems)) + ":" + string.Join("|", steps.Select(x => x.Type == StepType.NotSpecified ? x.Name : x.Type.GetDescription())), + nameof(MultiLanguageConst.UnfinishedItems)); //触发任务状态变更通知 if (task.TaskStatus != request.TaskStatus) @@ -616,6 +644,102 @@ namespace DS.WMS.Core.TaskInteraction.Method } } + /// + /// 设置任务步骤状态 + /// + /// + /// 是否使用事务 + /// + public async Task SetStepsAsync(TaskRequest request, bool useTransaction = true) + { + if (!await HasAuthorizedAsync()) + return DataResult.FailedWithDesc(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ModuleUnauthorized))); + + if (request.Steps == null || request.Steps.Count == 0) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.SubTaskCannotNull)); + + if (useTransaction) + await TenantDb.Ado.BeginTranAsync(); + + try + { + BusinessTask task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync(); + if (task == null) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskNotExists)); + if (task.TaskStatus == TaskStatusEnum.Complete) + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted)); + + var stepTypes = request.Steps.Select(x => x.Type); + var steps = await TenantDb.Queryable().Where(x => x.TaskId == task.Id && stepTypes.Contains(x.Type)) + .Select(x => new TaskStep + { + Id = x.Id, + Type = x.Type, + Name = x.Name, + SortOrder = x.SortOrder + }).ToListAsync(); + + long userId = long.Parse(User.UserId); + DateTime dtNow = DateTime.Now; + + foreach (var item in steps) + { + var reqStep = request.Steps.Find(x => x.Type == item.Type); + if (reqStep == null) + continue; + + item.SetValue(reqStep.Value); + item.IsCompleted = reqStep.IsCompleted; + item.UpdateBy = userId; + item.UpdateTime = dtNow; + } + + await TenantDb.Updateable(steps).UpdateColumns(x => new + { + x.Value, + x.IsCompleted, + x.UpdateBy, + x.UpdateTime + }).ExecuteCommandAsync(); + + if (request.AutoSync) + { + var allSteps = await TenantDb.Queryable().Where(x => x.TaskId == task.Id) + .Select(x => new + { + x.Id, + x.IsCompleted + }).ToListAsync(); + if (allSteps.Count > 0 && allSteps.Count == allSteps.Count(x => x.IsCompleted)) + { + var result = await SetTaskStatusAsync(new TaskUpdateRequest + { + BusinessId = task.BusinessId, + BusinessType = task.BusinessType, + TaskTypeName = request.TaskTypeName, + TaskStatus = TaskStatusEnum.Complete + }, false); + + if (!result.Succeeded) + return result; + } + } + + if (useTransaction) + await TenantDb.Ado.CommitTranAsync(); + + return DataResult.Success; + } + catch (Exception ex) + { + if (useTransaction) + await TenantDb.Ado.RollbackTranAsync(); + + await ex.LogAsync(Db); + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); + } + } + /// /// 当任务状态发生变化时调用 /// diff --git a/ds-wms-service/DS.WMS.Core/Utils/ExportFileHelper.cs b/ds-wms-service/DS.WMS.Core/Utils/ExportFileHelper.cs index 10f2003a..b3132120 100644 --- a/ds-wms-service/DS.WMS.Core/Utils/ExportFileHelper.cs +++ b/ds-wms-service/DS.WMS.Core/Utils/ExportFileHelper.cs @@ -1,35 +1,283 @@ -using System; +using LanguageExt; +using Masuit.Tools.Strings; +using Microsoft.AspNetCore.Identity; +using NPOI.HPSF; +using NPOI.HSSF.UserModel; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using static iText.StyledXmlParser.Jsoup.Select.Evaluator; namespace DS.WMS.Core.Utils { public class ExportFileHelper { - /// - /// 导出 - /// - /// - /// - /// - /// - public async Task Export(List dataLiist, Dictionary colDicts) - { - string filePath = string.Empty; + // /// + // /// 导出 + // /// + // /// + // /// + // /// + // /// + // public async Task Export(List dataLiist, Dictionary colDicts) + // { + // string filePath = string.Empty; - try - { + // /* + // 1、生成空Excel文件。 + // 2、根据colDicts提供的key来匹配字段列表的 + // 3、暂存文件,并返回完整文件名 + // */ + // try + // { + // string sheetName = ""; + // XSSFWorkbook workbook = new XSSFWorkbook(); + // ISheet sheet = workbook.CreateSheet(sheetName); - } - catch(Exception ex) - { + // #region Excel模板打印 + // //var opt = App.GetOptions(); + // //var dirAbs = opt.basePath; + // //if (string.IsNullOrEmpty(dirAbs)) + // //{ + // // dirAbs = App.WebHostEnvironment.WebRootPath; + // //} + // var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath); + // //_logger.LogInformation($"准备调用EXCEL生成:id:{id},文件:{printTemplate.FileName}"); - } - return filePath; - } + // var result = new FileStream(fileAbsPath, FileMode.Open); + // var excelwork = new HSSFWorkbook(result); + // var sheet = excelwork.GetSheetAt(0); + + + // var entity = await _bookingExcelTemplateRepository.AsQueryable() + // .Where(x => x.PId == templateId).OrderBy(x => x.Row).ToListAsync(); + // if (entity == null) + // { + + // throw Oops.Bah("当前模板未设置"); + + // } + + + // for (int _row = 1; _row <= entity.Max(x => x.Row); _row++) + // { + + // if (entity.Where(x => x.Row == _row).Count() > 0) + // { + // ////获取行 + // var row = sheet.GetRow(_row - 1); + // if (row != null) + // { + // for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + // { + // if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + // { + // var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + // if (name.Split('.')[0].ToLower() == "order") + // { + + // foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + // { + // var _name = descriptor.Name.ToLower(); + // if (name.Split('.')[0].ToLower() == "order" && name.Split('.')[1].ToLower() == _name) + // { + // var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + // ICell cell = row.GetCell(_cellNum - 1); + // if (descriptor.PropertyType.FullName.Contains("DateTime")) + // { + // value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + // } + // if (cell != null) + // { + // row.Cells[_cellNum - 1].SetCellValue(value); + // } + // else + // { + // row.CreateCell(_cellNum - 1).SetCellValue(value); + // } + // } + // } + // } + + // if (name.Split('.')[0].ToLower() == "edi") + // { + + // foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + // { + // var _name = descriptor.Name.ToLower(); + // if (name.Split('.')[0].ToLower() == "edi" && name.Split('.')[1].ToLower() == _name) + // { + // var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + // ICell cell = row.GetCell(_cellNum - 1); + // if (descriptor.PropertyType.FullName.Contains("DateTime")) + // { + // value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + // } + // if (cell != null) + // { + // row.Cells[_cellNum - 1].SetCellValue(value); + // } + // else + // { + // row.CreateCell(_cellNum - 1).SetCellValue(value); + // } + // } + // } + + + // } + + // if (name.Split('.')[0].ToLower() == "userinfo") + // { + // ICell cell = row.GetCell(_cellNum - 1); + // var value = string.Empty; + // if (name.Split('.')[1].ToLower() == "username") + // { + // value = UserManager.Name; + // } + // if (name.Split('.')[1].ToLower() == "usertel") + // { + // value = UserManager.TEl; + // } + // if (name.Split('.')[1].ToLower() == "usermobile") + // { + // value = UserManager.Phone; + // } + // if (name.Split('.')[1].ToLower() == "useremail") + // { + // value = UserManager.Email; + // } + // if (name.Split('.')[1].ToLower() == "usertenant") + // { + // value = UserManager.TENANT_NAME; + // } + // if (cell != null) + // { + // row.Cells[_cellNum - 1].SetCellValue(value); + // } + // else + // { + // row.CreateCell(_cellNum - 1).SetCellValue(value); + // } + // } + // } + // } + // } + // else + // { + // ////创建行 + // var srow = NpoiExcelExportHelper._.CreateRow(sheet, _row - 1); + + // for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) + // { + // if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) + // { + // var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); + + // if (name.Split('.')[0].ToLower() == "order") + // { + // foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) + // { + // var _name = descriptor.Name.ToLower(); + // if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "order") + // { + // var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; + // if (descriptor.PropertyType.FullName.Contains("DateTime")) + // { + // value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + // } + // srow.CreateCell(_cellNum - 1).SetCellValue(value); + // } + // } + // } + // if (name.Split('.')[0].ToLower() == "edi") + // { + // foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) + // { + // var _name = descriptor.Name.ToLower(); + // if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "edi") + // { + // var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; + // if (descriptor.PropertyType.FullName.Contains("DateTime")) + // { + // value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; + // } + // srow.CreateCell(_cellNum - 1).SetCellValue(value); + // } + // } + // } + + // if (name.Split('.')[0].ToLower() == "userinfo") + // { + + // var value = string.Empty; + // if (name.Split('.')[1].ToLower() == "username") + // { + // value = UserManager.Name; + // } + // if (name.Split('.')[1].ToLower() == "usertel") + // { + // value = UserManager.TEl; + // } + // if (name.Split('.')[1].ToLower() == "usermobile") + // { + // value = UserManager.Phone; + // } + // if (name.Split('.')[1].ToLower() == "useremail") + // { + // value = UserManager.Email; + // } + // if (name.Split('.')[1].ToLower() == "usertenant") + // { + // value = UserManager.TENANT_NAME; + // } + + // srow.CreateCell(_cellNum - 1).SetCellValue(value); + + // } + // } + // } + // } + + // } + // } + // var fileFullPath = Path.Combine(App.WebHostEnvironment.WebRootPath, App.GetOptions().Path);//服务器路径 + // if (!Directory.Exists(fileFullPath)) + // { + // Directory.CreateDirectory(fileFullPath); + // } + + // fileName = $"{DateTime.Now.Ticks}.xls";//名称 + // ////2023-4-3,根据河川操作要求,文件名只带提单号 + // //if (!string.IsNullOrEmpty(order.MBLNO)) + // //{ + // // fileName = $"{order.MBLNO}.xls";//名称 + // //} + // //else + // //{ + // // fileName = $"{order.Id}_{DateTime.Now.Ticks}.xls";//名称 + // //} + // _logger.LogInformation("导出excel:" + Path.Combine(fileFullPath, fileName)); + // var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); + // excelwork.Write(filestream); + + // #endregion + // } + // catch (Exception ex) + // { + + // } + + // return filePath; + // } + //} } } diff --git a/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs b/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs index 776ad27b..dfe2e2c9 100644 --- a/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs +++ b/ds-wms-service/DS.WMS.OpApi/Controllers/SeaExportTaskController.cs @@ -84,7 +84,12 @@ namespace DS.WMS.OpApi.Controllers { var result = await taskService.GetTasks(request.BusinessId, request.BusinessType, request.TaskType); if (result.Data?.Count > 0) - return await actionService.TriggerActionAsync(result.Data[0].Adapt(), false); + { + var task = result.Data[0].Adapt(); + task.BusinessId = request.BusinessId; + task.BusinessType = request.BusinessType; + return await actionService.TriggerActionAsync(task, false); + } return DataResult.FailedWithDesc(MultiLanguageConst.EmptyData); } @@ -159,6 +164,20 @@ namespace DS.WMS.OpApi.Controllers return await taskService.SetTaskStatusAsync(request); } + /// + /// 设置任务步骤 + /// + /// + /// + [HttpPost, Route("SetSteps")] + public async Task SetStepsAsync(TaskRequest request) + { + if (!ModelState.IsValid) + return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest); + + return await taskService.SetStepsAsync(request); + } + /// /// 手动发起任务审核(用于二次审核) /// diff --git a/ds-wms-service/DS.WMS.OpApi/appsettings.json b/ds-wms-service/DS.WMS.OpApi/appsettings.json index 08a5d679..9db7aef6 100644 --- a/ds-wms-service/DS.WMS.OpApi/appsettings.json +++ b/ds-wms-service/DS.WMS.OpApi/appsettings.json @@ -120,7 +120,7 @@ "Port": 465, "UseSSL": true, "Receivers": "candy@sunniness.net", - "CCTo": "yee@sunniness.net,daisusu@dongshengsoft.com", + "CCTo": "yee@sunniness.net;daisusu@dongshengsoft.com", "Title": "WSL Volume Daily Increase Report", "Body": "

Dear WSL Team,

Pls kindly check the daily report for your member's nomination booking: 

 

Thanks & Best regards

Candy SHAO 邵芳

General Manager| SUNNINESS LOGISTICS CO.,LTD.

TEL: +(86) (0532-80688387)1 MB./We chat: +(86)(18866622731) | QQ:2853083553|Email:candy@sunniness. net |WCA ID: 60272

" }