You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

289 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.TaskPlat.Dtos;
using DS.WMS.Core.TaskPlat.Entity;
using DS.WMS.Core.TaskPlat.Interface;
using Microsoft.AspNetCore.Hosting;
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
{
/// <summary>
/// 任务模块业务类的基类,封装了一些常用的方法
/// </summary>
public class TaskManageBaseService<T> : ITaskManageBaseService
{
protected readonly IUser user;
protected readonly ILogger<T> logger;
protected readonly ISaasDbService saasDbService;
protected readonly IServiceProvider serviceProvider;
protected readonly IWebHostEnvironment environment;
public TaskManageBaseService(IUser user,
ILogger<T> logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IWebHostEnvironment environment)
{
this.user = user;
this.logger = logger;
this.saasDbService = saasDbService;
this.serviceProvider = serviceProvider;
this.environment = environment;
}
/// <summary>
/// 更新任务主表状态
/// </summary>
/// <param name="taskIds">任务主键数组</param>
/// <param name="columns">需要更新状态的列</param>
public async Task SetTaskStatus(long[] taskIds, params Expression<Func<TaskBaseInfo, bool>>[] columns)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var updateable = tenantDb.Updateable<TaskBaseInfo>();
foreach (var item in columns)
{
updateable.SetColumns(item);
}
updateable.SetColumns(x => x.UpdateBy == long.Parse(user.UserId))
.SetColumns(x => x.UpdateTime == DateTime.Now)
.SetColumns(x => x.UpdateUserName == user.UserName);
await updateable.Where(x => taskIds.Contains(x.Id))
.ExecuteCommandAsync();
// 后面可以记录日志
}
/// <summary>
/// 设置任务处理人
/// </summary>
/// <param name="taskIds">任务主键数组</param>
/// <param name="userInfo">人员信息列表</param>
public async Task SetTaskOwner(long[] taskIds, List<RecvUserInfo> userInfo)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
try
{
await tenantDb.Ado.BeginTranAsync();
await tenantDb.Deleteable<TaskBaseAllocation>(x => taskIds.Contains(x.TaskId)).ExecuteCommandAsync();
List<TaskBaseAllocation> allocationList = new();
foreach (var item in taskIds)
{
allocationList.AddRange(userInfo.Select(x => new TaskBaseAllocation
{
TaskId = item,
UserId = x.RecvUserId,
UserName = x.RecvUserName
}));
}
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
// 后面可以记录日志
await tenantDb.Ado.CommitTranAsync();
}
catch (Exception)
{
await tenantDb.Ado.RollbackTranAsync();
throw;
}
}
#region Tools
/// <summary>
/// 保存文件并返回文件完整路径
/// </summary>
/// <param name="fileDictKey">追加文件夹</param>
/// <param name="fileBytes">文件二进制流</param>
/// <param name="batchNo">批次号</param>
/// <param name="fileNameNoSuffix">无拓展名的文件名</param>
/// <param name="printFileType">文件类型</param>
/// <param name="attachFileType">附件类型 bcfiles-BC文件 sofile-订舱附件</param>
/// <returns>返回文件完整路径</returns>
protected async Task<string> SaveFile(string fileDictKey, byte[] fileBytes, string batchNo, string fileNameNoSuffix,
PrintFileTypeEnum printFileType, string attachFileType = "sofiles")
{
var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
var relativePath = AppSetting.app(new string[] { "FileSettings", "RelativePath" });
if (!string.IsNullOrWhiteSpace(attachFileType))
relativePath += $"\\{attachFileType}";
if (!string.IsNullOrWhiteSpace(fileDictKey))
relativePath += $"\\{fileDictKey}";
string? dirAbs;
if (string.IsNullOrEmpty(basePath))
{
dirAbs = Path.Combine(environment.WebRootPath ?? "", relativePath);
}
else
{
dirAbs = Path.Combine(basePath, relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
var fileType = string.Empty;
if (printFileType == PrintFileTypeEnum.PDF)
{
fileType = ".pdf";
}
else if (printFileType == PrintFileTypeEnum.XLSX)
{
fileType = ".xlsx";
}
else if (printFileType == PrintFileTypeEnum.DOCX)
{
fileType = ".docx";
}
else if (printFileType == PrintFileTypeEnum.XLS)
{
fileType = ".xls";
}
else if (printFileType == PrintFileTypeEnum.DOC)
{
fileType = ".doc";
}
string curFileName = fileNameNoSuffix;
//var id = SnowFlakeSingle.Instance.NextId();
var fileSaveName = $"{curFileName}{fileType}";
string fileRelaPath = Path.Combine(relativePath, fileSaveName);
string fileAbsPath = Path.Combine(dirAbs, fileSaveName);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
relativePath = relativePath.Replace("\\", "/");
fileRelaPath = fileRelaPath.Replace("\\", "/");
fileAbsPath = fileAbsPath.Replace("\\", "/");
}
//logger.LogInformation("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, fileRelaPath, RuntimeInformation.OSDescription);
await File.WriteAllBytesAsync(fileAbsPath, fileBytes);
//string bookFilePath;
//if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
//{
// bookFilePath = System.Text.RegularExpressions.Regex.Match(fileAbsPath, relativePath.Replace("/", "\\/") + ".*").Value;
//}
//else
//{
// bookFilePath = System.Text.RegularExpressions.Regex.Match(fileAbsPath, relativePath.Replace("\\", "\\\\") + ".*").Value;
//}
return fileAbsPath;
//return bookFilePath;
}
/// <summary>
/// 获取文件类型
/// </summary>
/// <param name="fileName">文件完成路径</param>
/// <returns>返回文件类型枚举</returns>
protected PrintFileTypeEnum GetFileType(string fileName)
{
PrintFileTypeEnum fileType = PrintFileTypeEnum.PDF;
switch (Path.GetExtension(fileName).ToLower())
{
case ".pdf":
fileType = PrintFileTypeEnum.PDF;
break;
case ".xlsx":
fileType = PrintFileTypeEnum.XLSX;
break;
case ".docx":
fileType = PrintFileTypeEnum.DOCX;
break;
case ".xls":
fileType = PrintFileTypeEnum.XLS;
break;
case ".doc":
fileType = PrintFileTypeEnum.DOC;
break;
}
return fileType;
}
#endregion
/// <summary>
/// 根据任务ID获取附件信息
/// </summary>
/// <param name="taskId">任务Id</param>
/// <param name="fileCategory">附件分类代码</param>
public async Task<(string fileFullPath, string fileName)> GetTaskFileInfo(long taskId, string fileCategory)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var bcTaskInfo = await tenantDb.Queryable<TaskBaseInfo>().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<TaskFileInfo>().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))
{
logger.LogError("根据任务主键获取文件信息失败文件不存在fileFullPath={fileFullPath}", 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);
}
}
}