diff --git a/.gitignore b/.gitignore
index 55054247..a8f94cb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -63,3 +63,4 @@ bin-release/
/ds-wms-service/DS.WMS.OpApi/Properties/PublishProfiles/FolderProfile.pubxml.user
/ds-wms-service/DS.WMS.OpApi/Logs/internal-nlog.txt
/ds-wms-service/DS.WMS.OpApi/DS.WMS.OpApi.csproj.user
+LinkAttach
diff --git a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs
index d18aba59..945166ed 100644
--- a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs
+++ b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs
@@ -1454,6 +1454,15 @@ public static class MultiLanguageConst
[Description("未能获取到相应BC业务数据")]
public const string TaskBCInfoEmpty = "TaskBCInfoEmpty";
+
+ [Description("附件分类代码错误,请提供正确的分类代码")]
+ public const string TaskFileCategoryError = "TaskFileCategoryError";
+
+ [Description("任务主键{0}没有可下载的附件")]
+ public const string TaskFileEmpty = "TaskFileEmpty";
+
+ [Description("任务主键{0} 附件下载请求失败,请确认文件是否存在")]
+ public const string TaskFileNotExists = "TaskFileNotExists";
#endregion
#region 邮件解析配置
diff --git a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskFileCategoryEnum.cs b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskFileCategoryEnum.cs
index e7b08004..9fcc85d1 100644
--- a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskFileCategoryEnum.cs
+++ b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskFileCategoryEnum.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
namespace DS.Module.Core
{
diff --git a/ds-wms-service/DS.Module.Core/Filters/OperationLogFilter.cs b/ds-wms-service/DS.Module.Core/Filters/OperationLogFilter.cs
index 6f0eb1a2..601afc36 100644
--- a/ds-wms-service/DS.Module.Core/Filters/OperationLogFilter.cs
+++ b/ds-wms-service/DS.Module.Core/Filters/OperationLogFilter.cs
@@ -16,7 +16,7 @@ namespace DS.Module.Core.Filters;
///
/// 操作日志 过滤器
///
-public class OperationLogFilter: IAsyncActionFilter
+public class OperationLogFilter : IAsyncActionFilter
{
private readonly IServiceProvider _serviceProvider;
private readonly SqlSugarScope db;
@@ -42,7 +42,7 @@ public class OperationLogFilter: IAsyncActionFilter
var headers = httpRequest.Headers;
var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
- var isWriteLog = false;
+ var isWriteLog = false;
//请求异常时记录日志
if (!isRequestSucceed || AppSetting.app("Middleware", "RecordAccessLogs", "Enabled").ObjToBool())
@@ -50,7 +50,7 @@ public class OperationLogFilter: IAsyncActionFilter
isWriteLog = true;
}
- var res = actionContext.Result?.GetType() == typeof(DataResult) ? actionContext.Result.ToJsonString() : "";
+ //var res = actionContext.Result?.GetType() == typeof(DataResult) ? actionContext.Result.ToJsonString() : "";
if (isWriteLog)
{
var log = new SysLogOperation()
@@ -66,11 +66,11 @@ public class OperationLogFilter: IAsyncActionFilter
MethodName = actionDescriptor?.ActionName,
ReqMethod = httpRequest.Method,
Param = context.ActionArguments.Count < 1 ? "" : context.ActionArguments.ToJsonString(),
- Result = actionContext.Result.ToJsonString(),
+ Result = actionContext?.Result is FileResult ? "(FileResult)" : actionContext.Result.ToJsonString(),
ElapsedTime = sw.ElapsedMilliseconds,
OpTime = DateTime.Now,
};
-
+
await db.GetConnection(1288018625843826680).Insertable(log).ExecuteCommandAsync();
httpContext.Response.Headers["CheckTimeActionExecute"] = sw.ElapsedMilliseconds.ToString();
diff --git a/ds-wms-service/DS.Module.MultiLanguage/MultiLanguageMiddleware.cs b/ds-wms-service/DS.Module.MultiLanguage/MultiLanguageMiddleware.cs
index 67ef712b..5d5cc08f 100644
--- a/ds-wms-service/DS.Module.MultiLanguage/MultiLanguageMiddleware.cs
+++ b/ds-wms-service/DS.Module.MultiLanguage/MultiLanguageMiddleware.cs
@@ -50,6 +50,7 @@ public class MultiLanguageMiddleware
|| context.Request.Path.Value.IndexOf("PrintTempFile", StringComparison.InvariantCultureIgnoreCase) > -1
|| context.Request.Path.Value.IndexOf("GetOcrImg", StringComparison.InvariantCultureIgnoreCase) > -1
|| context.Request.Path.Value.IndexOf("DownloadBookingOrClosingEDI", StringComparison.InvariantCultureIgnoreCase) > -1
+ || context.Request.Path.Value.IndexOf("DownloadFile", StringComparison.InvariantCultureIgnoreCase) > -1
)
)
{
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageBaseService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageBaseService.cs
index e28373cb..c9168c0b 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageBaseService.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageBaseService.cs
@@ -22,5 +22,12 @@ namespace DS.WMS.Core.TaskPlat.Interface
/// 任务主键数组
/// 人员信息列表
Task SetTaskOwner(long[] taskIds, List userInfo);
+
+ ///
+ /// 根据任务ID获取附件信息
+ ///
+ /// 任务Id
+ /// 附件分类代码
+ Task<(string fileFullPath, string fileName)> GetTaskFileInfo(long taskId, string fileCategory);
}
}
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs
index 64b73b2b..790dd70e 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs
@@ -58,5 +58,6 @@ namespace DS.WMS.Core.TaskPlat.Interface
/// 业务类型
/// 要转交的人员信息列表
Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos);
+
}
}
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs
index 27d51985..9e7476e0 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs
@@ -25,8 +25,6 @@ namespace DS.WMS.Core.TaskPlat.Method
{
}
-
-
///
/// 通过任务主键获取BC详情
///
@@ -125,9 +123,9 @@ namespace DS.WMS.Core.TaskPlat.Method
return DataResult.Success(result);
}
- public virtual async Task<(bool canCompelete, string? msg)> CompleteAsync(long taskId)
- {
- return (true, null);
- }
+ //public virtual async Task<(bool canCompelete, string? msg)> CompleteAsync(long taskId)
+ //{
+ // return (true, null);
+ //}
}
}
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs
index e49e4896..d08bb6fc 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs
@@ -9,6 +9,8 @@ using Microsoft.Extensions.Logging;
using SqlSugar;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
+using System.Text;
+using System.Web;
namespace DS.WMS.Core.TaskPlat.Method
{
@@ -102,12 +104,14 @@ namespace DS.WMS.Core.TaskPlat.Method
///
/// 保存文件并返回文件完整路径
///
+ /// 追加文件夹
/// 文件二进制流
/// 批次号
+ /// 无拓展名的文件名
/// 文件类型
/// 附件类型 bcfiles-BC文件 sofile-订舱附件
/// 返回文件完整路径
- protected async Task SaveFile(byte[] fileBytes, string batchNo,
+ protected async Task SaveFile(string fileDictKey, byte[] fileBytes, string batchNo, string fileNameNoSuffix,
PrintFileTypeEnum printFileType, string attachFileType = "sofiles")
{
var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
@@ -116,6 +120,9 @@ namespace DS.WMS.Core.TaskPlat.Method
if (!string.IsNullOrWhiteSpace(attachFileType))
relativePath += $"\\{attachFileType}";
+ if (!string.IsNullOrWhiteSpace(fileDictKey))
+ relativePath += $"\\{fileDictKey}";
+
string? dirAbs;
if (string.IsNullOrEmpty(basePath))
{
@@ -151,11 +158,13 @@ namespace DS.WMS.Core.TaskPlat.Method
fileType = ".doc";
}
- var id = SnowFlakeSingle.Instance.NextId();
- var fileSaveName = $"{id}{fileType}".ToLower();
+ string curFileName = fileNameNoSuffix;
+
+ //var id = SnowFlakeSingle.Instance.NextId();
+ var fileSaveName = $"{curFileName}{fileType}";
- string fileRelaPath = Path.Combine(relativePath, fileSaveName).ToLower();
- string fileAbsPath = Path.Combine(dirAbs, fileSaveName).ToLower();
+ string fileRelaPath = Path.Combine(relativePath, fileSaveName);
+ string fileAbsPath = Path.Combine(dirAbs, fileSaveName);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
@@ -214,6 +223,65 @@ namespace DS.WMS.Core.TaskPlat.Method
}
#endregion
+ ///
+ /// 根据任务ID获取附件信息
+ ///
+ /// 任务Id
+ /// 附件分类代码
+ public async Task<(string fileFullPath, string fileName)> GetTaskFileInfo(long taskId, string fileCategory)
+ {
+ var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
+
+ var bcTaskInfo = await tenantDb.Queryable().Where(u => u.Id == taskId).FirstAsync();
+ if (bcTaskInfo == null)
+ {
+ throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
+ }
+
+ TaskFileCategoryEnum fileCategoryEnum = TaskFileCategoryEnum.NONE;
+
+ System.Enum.TryParse(fileCategory, out fileCategoryEnum);
+
+ if (fileCategoryEnum == TaskFileCategoryEnum.NONE)
+ {
+ // 附件分类代码错误,请提供正确的分类代码
+ throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskFileCategoryError)));
+ }
+
+ string name = fileCategoryEnum.ToString();
+
+ var fileInfo = await tenantDb.Queryable().Where(u => u.TASK_PKID == taskId && u.FILE_CATEGORY == name).OrderByDescending(x => x.Id).FirstAsync();
+ if (fileInfo == null)
+ {
+ // 附件分类代码错误,请提供正确的分类代码
+ throw new Exception(
+ string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskFileCategoryError)), taskId)
+ );
+ }
+ var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
+
+ string fileFullPath;
+ if (string.IsNullOrEmpty(basePath))
+ {
+ fileFullPath = Path.Combine(environment.WebRootPath ?? "", fileInfo.FILE_PATH);
+ }
+ else
+ {
+ fileFullPath = Path.Combine(basePath, fileInfo.FILE_PATH);
+
+ }
+ if (!File.Exists(fileFullPath))
+ {
+ //任务主键{0} 附件下载请求失败,请确认文件是否存在
+ throw new Exception(
+ string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskFileNotExists)), taskId)
+ );
+ }
+
+ var fileName = HttpUtility.UrlEncode(fileInfo.FILE_NAME, Encoding.GetEncoding("UTF-8"))!;
+ return (fileFullPath, fileName);
+ //return (new FileStream(fileFullPath, FileMode.Open), fileName);
+ }
}
}
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs
index d207fbef..e6997f58 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs
@@ -1,6 +1,8 @@
using DS.Module.Core;
using DS.Module.Core.Data;
+using DS.Module.Core.Extensions;
using DS.Module.Core.Helpers;
+using DS.Module.DjyServiceStatus;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.TaskPlat.Dtos;
@@ -12,9 +14,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
-using System.Runtime.InteropServices;
-using DS.Module.Core.Extensions;
-using DS.Module.DjyServiceStatus;
namespace DS.WMS.Core.TaskPlat.Method
@@ -371,8 +370,11 @@ namespace DS.WMS.Core.TaskPlat.Method
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
- var fileFullName = await SaveFile(bytes,
+ var noExtensionFileName = Path.GetFileNameWithoutExtension(file.FileName);
+ var fileFullName = await SaveFile(taskInfo.Id.ToString(),
+ bytes,
batchNo,
+ noExtensionFileName,
GetFileType(file.FileName),
attachFileType);
@@ -460,8 +462,10 @@ namespace DS.WMS.Core.TaskPlat.Method
}
var noExtensionFileName = Path.GetFileNameWithoutExtension(modifyFile.FileName);
- var fileFullName = await SaveFile(bytes,
+ var fileFullName = await SaveFile(taskInfo.Id.ToString(),
+ bytes,
batchNo,
+ noExtensionFileName,
GetFileType(modifyFile.FileName),
attachFileType);
@@ -488,7 +492,7 @@ namespace DS.WMS.Core.TaskPlat.Method
//附件
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
{
- info.Main.FileList.ForEach(async file =>
+ var fileList = info.Main.FileList.Select(file =>
{
var fileInfo = new TaskFileInfo();
@@ -536,9 +540,9 @@ namespace DS.WMS.Core.TaskPlat.Method
fileInfo.FILE_NAME = fileModel.Name;
fileInfo.FILE_TYPE = fileModel.Extension?.Replace(".", "");
}
-
- await tenantDb.Insertable(fileInfo).ExecuteCommandAsync();
- });
+ return fileInfo;
+ }).ToList();
+ await tenantDb.Insertable(fileList).ExecuteCommandAsync();
}
#endregion
@@ -546,7 +550,7 @@ namespace DS.WMS.Core.TaskPlat.Method
//邮件
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
{
- info.Main.EmailList.ForEach(async email =>
+ var emailList = info.Main.EmailList.Select(email =>
{
var emailInfo = new TaskEmail();
@@ -558,8 +562,9 @@ namespace DS.WMS.Core.TaskPlat.Method
emailInfo.MAIL_PATH = email.MailPath;
- await tenantDb.Insertable(emailInfo).ExecuteCommandAsync();
- });
+ return emailInfo;
+ }).ToList();
+ await tenantDb.Insertable(emailList).ExecuteCommandAsync();
}
#endregion
diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Other/TaskFlowRuner.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Other/TaskFlowRuner.cs
index c4cbd916..bcb55a32 100644
--- a/ds-wms-service/DS.WMS.Core/TaskPlat/Other/TaskFlowRuner.cs
+++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Other/TaskFlowRuner.cs
@@ -1,6 +1,8 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.TaskPlat.Entity;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
using System.Diagnostics;
@@ -15,7 +17,7 @@ namespace DS.WMS.Core.TaskPlat
{
private readonly SqlSugarScopeProvider tenantDb = null!;
private readonly IServiceProvider serviceProvider = null!;
-
+ private readonly ILogger logger = null!;
private TaskFlowRuner() { }
///
@@ -27,6 +29,7 @@ namespace DS.WMS.Core.TaskPlat
{
this.tenantDb = tenantDb;
this.serviceProvider = serviceProvider;
+ this.logger = serviceProvider.GetRequiredService>();
}
///
/// 执行
@@ -35,7 +38,7 @@ namespace DS.WMS.Core.TaskPlat
/// 任务Id
/// 起始入参数据上下文
/// (执行日志Id,模块是否全部执行完成,模块执行结果是否全部为success)
- public async Task<(long flowLogId, bool isAllComplete, bool isAllSuccess)> Run(TaskBaseTypeEnum taskBaseType, long taskId, TaskFlowDataContext dataContext)
+ public async Task<(long? flowLogId, bool isAllComplete, bool isAllSuccess)> Run(TaskBaseTypeEnum taskBaseType, long taskId, TaskFlowDataContext dataContext)
{
if (dataContext == null)
{
@@ -59,7 +62,9 @@ namespace DS.WMS.Core.TaskPlat
IsSuccess = false,
};
await tenantDb.Insertable(log).ExecuteCommandAsync();
- throw new Exception(msg);
+ logger.LogInformation(msg);
+ return (null, false, false);
+ //throw new Exception(msg);
}
var allConfigIdList = allConfigList.Select(x => x.Id);
diff --git a/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs b/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs
index db9516b9..463abcc6 100644
--- a/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs
+++ b/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs
@@ -183,6 +183,21 @@ public class TaskManageController : ApiController
return DataResult.SuccessedWithDesc(nameof(MultiLanguageConst.OperationSuccess));
}
+
+ ///
+ /// 根据任务ID下载附件
+ ///
+ /// 任务主键
+ /// 附件分类代码
+ /// 返回数据流
+ [HttpGet("DownloadFile")]
+ public async Task DownloadFile([FromQuery] long taskId, [FromQuery] string fileCategory = "BC")
+ {
+ (string fileFullPath, string fileName) = await taskManageService.GetTaskFileInfo(taskId, fileCategory);
+
+ return PhysicalFile(fileFullPath, "application/octet-stream", fileName);
+ }
+
// /TaskManage/CreateBCTaskJob
// /TaskManage/CreateDRAFTTaskJob
// /TaskManage/CreateAdvisoryTaskJob
diff --git a/ds-wms-service/DS.WMS.TaskApi/DS.WMS.TaskApi.csproj b/ds-wms-service/DS.WMS.TaskApi/DS.WMS.TaskApi.csproj
index 83336c04..37958fa0 100644
--- a/ds-wms-service/DS.WMS.TaskApi/DS.WMS.TaskApi.csproj
+++ b/ds-wms-service/DS.WMS.TaskApi/DS.WMS.TaskApi.csproj
@@ -15,6 +15,7 @@
+
@@ -23,4 +24,8 @@
+
+
+
+
diff --git a/ds-wms-service/ds-wms-service.sln b/ds-wms-service/ds-wms-service.sln
index 22e9738c..7fe61eb2 100644
--- a/ds-wms-service/ds-wms-service.sln
+++ b/ds-wms-service/ds-wms-service.sln
@@ -60,14 +60,17 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.WMS.FinanceApi", "DS.WMS.FinanceApi\DS.WMS.FinanceApi.csproj", "{32B97A3A-C361-44F3-B417-5D08E9FD9624}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.WMS.TaskApi", "DS.WMS.TaskApi\DS.WMS.TaskApi.csproj", "{8DAE16A3-E249-4C86-BEEC-DA8429FD837C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B0351554-748F-4DF8-8C22-152646937EFE} = {B0351554-748F-4DF8-8C22-152646937EFE}
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.Module.EmailModule", "DS.Module.EmailModule\DS.Module.EmailModule.csproj", "{4B51DCC1-62A5-49C5-978B-798E6B48F3C0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.WMS.PrintApi", "DS.WMS.PrintApi\DS.WMS.PrintApi.csproj", "{274B1D18-A15A-4917-A567-6FDCD090D5B0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DS.Module.OcrModule", "DS.Module.OcrModule\DS.Module.OcrModule.csproj", "{3EB9CA1E-5910-42A5-A64D-0CB435F6A64A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.Module.OcrModule", "DS.Module.OcrModule\DS.Module.OcrModule.csproj", "{3EB9CA1E-5910-42A5-A64D-0CB435F6A64A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DS.WMS.ContainerManagementApi", "DS.WMS.ContainerManagementApi\DS.WMS.ContainerManagementApi.csproj", "{7C3E248A-DF40-46AC-A8DF-224DD7C4EEF7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DS.WMS.ContainerManagementApi", "DS.WMS.ContainerManagementApi\DS.WMS.ContainerManagementApi.csproj", "{7C3E248A-DF40-46AC-A8DF-224DD7C4EEF7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution