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.

1780 lines
98 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.Core.Data;
using DS.Module.Core.Helpers;
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 Mapster;
using Microsoft.AspNetCore.Hosting;
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
{
public class TaskManageService : ITaskManageService
{
private readonly ILogger<TaskManageService> _logger;
private readonly IUser user;
private readonly ISaasDbService saasDbService;
private readonly IServiceProvider serviceProvider;
private readonly IWebHostEnvironment environment;
//private readonly ICodeCtnService _codeCtnService;
public TaskManageService(ILogger<TaskManageService> logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IUser user,
IWebHostEnvironment environment
)
{
_logger = logger;
this.saasDbService = saasDbService;
this.serviceProvider = serviceProvider;
this.user = user;
this.environment = environment;
}
#region 对工作流提供的接口
/// <summary>
/// 设置任务状态
/// </summary>
/// <param name="bsno">业务主键</param>
/// <param name="taskBaseTypeEnum">业务类型</param>
/// <param name="taskStatusEnum">业务状态</param>
/// <param name="statusTime">状态发生时间</param>
public async Task<DataResult> SetTaskStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
TaskBaseInfo taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_BASE_TYPE == taskBaseTypeEnum.ToString());
if (taskInfo == null)
{
_logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskBaseTypeEnum}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
_logger.LogInformation("接收到任务状态修改报文 任务主键={id} 状态设置={status}", taskInfo.Id, taskStatusEnum.ToString());
taskInfo.STATUS = taskStatusEnum.ToString();
taskInfo.RealUserId = long.Parse(user.UserId);
taskInfo.RealUserName = user.UserName;
await tenantDb.Updateable(taskInfo).UpdateColumns(x => new
{
x.UpdateBy,
x.UpdateTime,
x.UpdateUserName,
x.STATUS,
x.RealUserId,
x.RealUserName
}).ExecuteCommandAsync();
return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess)));
}
/// <summary>
/// 工作流任务转交
/// </summary>
/// <param name="bsno">业务主键</param>
/// <param name="taskBaseTypeEnum">业务类型</param>
/// <param name="userInfos">要转交的人员信息列表</param>
public async Task<DataResult> TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List<RecvUserInfo> userInfos)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
try
{
var taskId = await tenantDb.Queryable<TaskBaseInfo>()
.Where(t => t.OUT_BS_NO == bsno && t.TASK_BASE_TYPE == taskBaseTypeEnum.ToString())
.OrderByDescending(a => a.CreateTime)
.Select<long?>(t => t.Id)
.FirstAsync();
if (taskId == null || taskId == 0)
{
_logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskBaseTypeEnum}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
_logger.LogInformation("接收到任务转交报文 任务主键={id} 转交人员列表={userinfo}", taskId, JsonConvert.SerializeObject(userInfos));
await tenantDb.Ado.BeginTranAsync();
await tenantDb.Deleteable<TaskBaseAllocation>(x => x.TaskId == taskId).ExecuteCommandHasChangeAsync();
var allocationList = userInfos.Select(x => new TaskBaseAllocation
{
TaskId = (long)taskId,
UserId = x.RecvUserId,
UserName = x.RecvUserName
}).ToList();
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
await tenantDb.Ado.CommitTranAsync();
return DataResult.Successed("操作成功!", MultiLanguageConst.DataUpdateSuccess);
}
catch (Exception)
{
await tenantDb.Ado.RollbackTranAsync();
throw;
}
}
#endregion
public async Task<DataResult> InitTaskJob(TaskManageOrderMessageInfo info, IFormFile file = null, IFormFile modifyFile = null)
{
string batchNo = Guid.NewGuid().ToString();
//var a = user.UserId;
//var b = user.UserName;
//var c = user.TenantId;
//var d = user.OrgId;
try
{
_logger.LogInformation("批次={no} 接收到创建任务报文 报文={msg}", batchNo, JsonConvert.SerializeObject(info));
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
TaskBaseInfo taskInfo = null;
// 如果业务主键不为空,则通过业务主键进行重复判断
if (info.Head.BSNO is not null or 0)
{
taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.FirstAsync(t => t.OUT_BS_NO == info.Head.BSNO);
}
// 否则通过Head.GID进行判断
else
{
taskInfo = await tenantDb.Queryable<TaskBaseInfo>()
.OrderByDescending(a => a.CreateTime)
.FirstAsync(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}");
}
// 只要任务最后一次处理任务的状态是已取消、已完成,就可以重入新的任务
if (taskInfo != null
&& taskInfo.STATUS != TaskStatusEnum.Cancel.ToString()
&& taskInfo.STATUS != TaskStatusEnum.Complete.ToString())
{
_logger.LogInformation("批次={no} 状态已存在,不能重复创建任务 status={status}", batchNo, taskInfo.STATUS);
throw new Exception($"状态已存在,不能重复创建任务");
}
_logger.LogInformation("批次={no} 接收到创建任务报文 结束查询任务 {msg}", batchNo, taskInfo == null ? "不存在" : "存在");
//如果文件路径不为空 判断文件是否真实存在
if (!string.IsNullOrWhiteSpace(info.Main.FilePath) && !File.Exists(info.Main.FilePath))
{
throw new Exception(string.Format("{0}文件不存在", info.Main.FilePath));
}
//如果文件路径不为空 判断文件是否真实存在
if (!string.IsNullOrWhiteSpace(info.Main.ModifyFile) && !File.Exists(info.Main.ModifyFile))
{
throw new Exception(string.Format("{0}文件不存在", info.Main.ModifyFile));
}
taskInfo = new TaskBaseInfo
{
Id = SnowFlakeSingle.Instance.NextId(),
STATUS = TaskStatusEnum.Create.ToString(),
IS_EXCEPT = 0,
IS_COMPLETE = 0,
MBL_NO = info.Main.MBlNo,
TASK_BASE_TYPE = info.Main.TaskType.ToString(),
CARRIER_ID = info.Main.CarrierId?.Trim(),
//IS_PUBLIC = string.IsNullOrWhiteSpace(info.Main.TaskUserId) ? 1 : 0,
IS_PUBLIC = 1,
BOOK_ORDER_NO = info.Main.BookingOrderNo,
OUT_BUSI_NO = $"{info.Head.SenderId}_{info.Head.GID}",
TASK_TITLE = info.Main.TaskTitle,
TASK_DESP = info.Main.TaskDesp,
TASK_SOURCE = info.Main.TaskSource.ToString(),
TASK_TYPE = info.Main.TaskType.ToString(),
VESSEL_VOYNO = info.Main.VesselVoyno?.Trim(),
CONTA_INFO = info.Main.ContaInfo,
TASK_REQ_USERNAME = info.Main.TaskUserName,
YARD_NAME = info.Main.YardName,
ETD = info.Main.ETD,
CUSTOMER_ID = info.Main.CustomerId,
CUSTOMER_NAME = info.Main.CustomerName,
BATCH_STATIC = info.Main.BatchStatic,
//DJYUserId = info.Head.DJYUserId,
OUT_BS_NO = info.Head.BSNO,
CreateTime = DateTime.Now,
};
// 人员字段说明:
// TaskBaseInfo.CreateBy 创建人:谁创建的,只有一个人(可能是某个租户的管理员,因为任务可以由外部(邮件)创建,无法为每个人创建接口授权信息)
// TaskBaseInfo.TASK_REQ_USERID 制单人只有一个人使用任务创建报文中传入的TaskUserId
// TaskBaseAllocation.UserId 任务关系任务属于谁谁能够查看并处理可能是多个人可能是多个人一起处理取值优先级info.Main.RecvUserInfoList>关联订单
// TaskBaseInfo.RealUserId 实际操作人:谁实际处理的,只有一个人
// 创建人
taskInfo.CreateBy = long.Parse(user.UserId);
taskInfo.CreateUserName = user.UserName;
// 制单人
long taskReqUserId = 0;
if (!string.IsNullOrWhiteSpace(info.Main.TaskUserId))
{
if (long.TryParse(info.Main.TaskUserId, out taskReqUserId))
{
taskInfo.TASK_REQ_USERID = taskReqUserId;
taskInfo.TASK_REQ_USERNAME = info.Main.TaskUserName;
}
}
_logger.LogInformation("批次={no} 获取登录人详情 recvUserId={recvUserId} UserId={UserId}", batchNo,
info.Main.RecvUserId,
user.UserId);
// 任务所属人员列表
// 如果明确指出接收人(接收人列表),则将任务作为个人任务
if (info.Main.RecvUserInfoList?.Count > 0)
{
_logger.LogInformation("批次={no} 接收人列表 recvUserList={recvUserList} ", batchNo,
JsonConvert.SerializeObject(info.Main.RecvUserInfoList));
taskInfo.IS_PUBLIC = 0;
var allocationList = info.Main.RecvUserInfoList.Select(x => new TaskBaseAllocation
{
TaskId = taskInfo.Id,
UserId = x.RecvUserId,
UserName = x.RecvUserName
}).ToList();
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
}
// 否则判断任务关联订单,如果能关联到,则判断任务设置的角色;如果有设置,则将任务挂载到订单的指定角色上;如果没关联到或者没有设置,则作为公共任务
//else
//{
// // 1.查找任务的匹配设置
// var allotSet = await tenantDb.Queryable<TaskAllotSet>().Where(x => x.TaskType == info.Main.TaskType.ToString()).FirstAsync();
// if (allotSet != null)
// {
// // 2. 根据提单号查找订单\根据订舱编号查找订单\...
// // 3. 查找订单之后获取匹配设置参数得到人员Id列表
// // 4. 获取任务Id
// // 5. 存关系
// }
//}
if (info.Main != null && info.Main.TruckInfo != null && info.Main.TruckInfo.NeedArriveTime.HasValue)
{
taskInfo.NeedArriveTime = info.Main.TruckInfo.NeedArriveTime;
}
await tenantDb.Insertable(taskInfo).ExecuteCommandAsync();
if (!string.IsNullOrWhiteSpace(info.Main.FilePath))
{
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "advisoryfiles";
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = Path.GetFileName(info.Main.FilePath),
FileType = Path.GetExtension(info.Main.FilePath).ToLower(),
FilePath = info.Main.FilePath,
FileCategory = fileCategory
});
}
else
{
if (file != null)
{
var bytes = file.ToByteArray();
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "advisoryfiles";
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
var fileFullName = await SaveFile(bytes,
batchNo,
GetFileType(file.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(fileFullName))
{
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = file.FileName,
FileType = Path.GetExtension(file.FileName).ToLower(),
FilePath = fileFullName,
FileCategory = fileCategory
});
}
}
}
if (!string.IsNullOrWhiteSpace(info.Main.ModifyFile))
{
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString();
if (info.Main.FileList == null)
info.Main.FileList = new List<TaskManageOrderFileInfo>();
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = Path.GetFileName(info.Main.ModifyFile),
FileType = Path.GetExtension(info.Main.ModifyFile).ToLower(),
FilePath = info.Main.FilePath,
FileCategory = fileCategory
});
}
else
{
if (modifyFile != null)
{
var bytes = modifyFile.ToByteArray();
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bcmodifynoticefiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "bccancelnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_BASE_TYPE)
{
attachFileType = "draftnoticefiles";
fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString();
}
var noExtensionFileName = Path.GetFileNameWithoutExtension(modifyFile.FileName);
var fileFullName = await SaveFile(bytes,
batchNo,
GetFileType(modifyFile.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(fileFullName))
{
if (info.Main.FileList == null)
{
info.Main.FileList = new List<TaskManageOrderFileInfo>();
}
info.Main.FileList.Add(new TaskManageOrderFileInfo
{
PKId = SnowFlakeSingle.Instance.NextId(),
FileName = modifyFile.FileName,
FileType = Path.GetExtension(modifyFile.FileName).ToLower(),
FilePath = fileFullName,
FileCategory = fileCategory
});
}
}
}
#region 附件
//附件
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
{
info.Main.FileList.ForEach(async file =>
{
var fileInfo = new TaskFileInfo();
fileInfo.Id = SnowFlakeSingle.Instance.NextId();
fileInfo.TASK_PKID = taskInfo.Id;
fileInfo.CreateBy = taskInfo.CreateBy;
fileInfo.CreateTime = taskInfo.CreateTime;
//fileInfo.CreatedUserName = taskInfo.CreatedUserName;
//fileInfo.TenantId = taskInfo.TenantId;
//fileInfo.TenantName = taskInfo.TenantName;
fileInfo.FILE_PATH = file.FilePath;
fileInfo.FILE_NAME = file.FileName;
fileInfo.FILE_TYPE = file.FileType;
if (string.IsNullOrWhiteSpace(file.FileCategory))
{
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
{
fileInfo.FILE_CATEGORY = TaskFileCategoryEnum.BC.ToString();
fileInfo.FILE_CATEGORY_NAME = TaskFileCategoryEnum.BC.EnumDescription();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_BASE_TYPE)
{
fileInfo.FILE_CATEGORY = TaskFileCategoryEnum.BC_MODIFY.ToString();
fileInfo.FILE_CATEGORY_NAME = TaskFileCategoryEnum.BC_MODIFY.EnumDescription();
}
}
else
{
TaskFileCategoryEnum fileCategoryEnum = TaskFileCategoryEnum.NONE;
System.Enum.TryParse(file.FileCategory, out fileCategoryEnum);
fileInfo.FILE_CATEGORY = fileCategoryEnum.ToString();
fileInfo.FILE_CATEGORY_NAME = fileCategoryEnum.EnumDescription();
}
if (string.IsNullOrWhiteSpace(fileInfo.FILE_NAME))
{
var fileModel = new FileInfo(file.FilePath);
fileInfo.FILE_NAME = fileModel.Name;
fileInfo.FILE_TYPE = fileModel.Extension?.Replace(".", "");
}
await tenantDb.Insertable(fileInfo).ExecuteCommandAsync();
});
}
#endregion
#region 邮件
//邮件
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
{
info.Main.EmailList.ForEach(async email =>
{
var emailInfo = new TaskEmail();
emailInfo.Id = SnowFlakeSingle.Instance.NextId();
emailInfo.TASK_PKID = taskInfo.Id;
emailInfo.CreateTime = taskInfo.CreateTime;
emailInfo.CreateBy = taskInfo.CreateBy;
emailInfo.MAIL_PATH = email.MailPath;
await tenantDb.Insertable(emailInfo).ExecuteCommandAsync();
});
}
#endregion
#region SI反馈入库
//SI反馈入库
//if (info.Main.TaskType == TaskBaseTypeEnum.SI_FEEDBACK)
//{
// if (info.Main.SIFeedBack == null)
// throw new Exception($"任务类型={info.Main.TaskType.ToString()} SIFeedBack信息必传");
// TaskSiSubmitted taskSISubmitted = info.Main.SIFeedBack.Adapt<TaskSiSubmitted>();
// taskSISubmitted.Id = SnowFlakeSingle.Instance.NextId();
// taskSISubmitted.TASK_ID = taskInfo.Id;
// taskSISubmitted.CreateTime = taskInfo.CreateTime;
// taskSISubmitted.CreateBy = taskInfo.CreateBy;
// await tenantDb.Insertable(taskSISubmitted).ExecuteCommandAsync();
// //SI反馈箱信息入库
// if (info.Main.SIFeedBack.ContaList != null && info.Main.SIFeedBack.ContaList.Count > 0)
// {
// var codeCtnCache = (await _codeCtnService.GetAllList())?.Data ?? new List<Code.Dtos.CodeCtnRes>();
// info.Main.SIFeedBack.ContaList.ForEach(ctn =>
// {
// var contaInfo = ctn.Adapt<TaskSiSubmittedCtn>();
// //contaInfo.PK_ID = IDGen.NextID().ToString();
// //contaInfo.P_PKID = taskSISubmitted.PK_ID;
// //contaInfo.CreatedTime = taskInfo.CreatedTime;
// //contaInfo.UpdatedTime = taskInfo.CreatedTime;
// //contaInfo.CreatedUserId = taskInfo.CreatedUserId;
// //contaInfo.CreatedUserName = taskInfo.CreatedUserName;
// //contaInfo.TenantId = taskInfo.TenantId;
// //contaInfo.TenantName = taskInfo.TenantName;
// //if (string.IsNullOrWhiteSpace(contaInfo.CTNCODE) && !string.IsNullOrWhiteSpace(contaInfo.CTNALL))
// //{
// // if (ediCtnList != null && ediCtnList.Count > 0)
// // {
// // var ctnCodeInfo = ediCtnList.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.Name)
// // && x.Name.Equals(contaInfo.CTNALL, StringComparison.OrdinalIgnoreCase));
// // if (ctnCodeInfo != null)
// // {
// // contaInfo.CTNCODE = ctnCodeInfo.Code;
// // }
// // }
// //}
// //_taskSISubmittedCtnRepository.Insert(contaInfo);
// });
// }
// var siService = _namedtaskSISubmittedServiceProvider
// .GetService<ITransient>(nameof(TaskManageSISubmittedService));
// await siService.ProcessSISubmitted(taskSISubmitted.TASK_ID);
//}
#endregion
#region BC 任务
if (info.Main.TaskType == TaskBaseTypeEnum.BC
|| info.Main.TaskType == TaskBaseTypeEnum.BC_MODIFY
|| info.Main.TaskType == TaskBaseTypeEnum.CANCELLATION)
{
//异步写入
var bcInfo = info.Main.BCInfo.Adapt<TaskBCInfo>();
bcInfo.Id = SnowFlakeSingle.Instance.NextId();
bcInfo.TASK_ID = taskInfo.Id;
bcInfo.CreateBy = taskInfo.CreateBy;
bcInfo.CreateTime = taskInfo.CreateTime;
if (info.Main.BCInfo.BookingSlotId.HasValue && info.Main.BCInfo.BookingSlotId.Value > 0)
bcInfo.BOOKING_SLOT_ID = info.Main.BCInfo.BookingSlotId.Value;
await tenantDb.Insertable(bcInfo).ExecuteCommandAsync();
//异步写入集装箱
var ctnList = info.Main.BCInfo.CtnList.Select(ctn =>
{
var bcCtnInfo = ctn.Adapt<TaskBCCTNInfo>();
bcCtnInfo.Id = SnowFlakeSingle.Instance.NextId();
bcCtnInfo.P_ID = bcInfo.Id;
bcInfo.CreateBy = taskInfo.CreateBy;
bcInfo.CreateTime = taskInfo.CreateTime;
return bcCtnInfo;
}).ToList();
await tenantDb.Insertable(ctnList).ExecuteCommandAsync();
/*
BC_MODIFY
1、检索对应舱位提取比对差异结果
2、检索舱位对应的订舱信息如果有则生成用户通知邮件
3、推送钉钉消息@操作人 通知收到变更
CANCELLATION
1、检索舱位对应的订舱信息如果有则生成用户通知邮件
2、推送钉钉消息@操作人 通知收到变更
*/
//(TaskFlowDataNameConst.TenantId, long.Parse(user.TenantId)),
// 执行自动化操作
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.TaskManageOrderMessageInfo, info),
(TaskFlowDataNameConst.BCFile, file),
(TaskFlowDataNameConst.AmendmentFile, modifyFile)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType, taskInfo.Id, dataContext);
//if (info.Main.TaskType == TaskBaseTypeEnum.BC)
//{
//}
//else if (info.Main.TaskType == TaskBaseTypeEnum.CANCELLATION)
//{
//}
//else if (info.Main.TaskType == TaskBaseTypeEnum.BC_MODIFY)
//{
//}
}
#endregion
var taskNo = await tenantDb.Queryable<TaskBaseInfo>().Where(a => a.Id == taskInfo.Id).Select(a => a.TASK_NO).FirstAsync();
//回写任务号
var result = new DataResult(ResultCode.Success, "新增任务成功", data: taskNo);
return await Task.FromResult(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "任务台:初始化任务的过程中发生未知异常,批次号={no}", batchNo);
return DataResult.Failed(ex.Message);
}
}
/// <summary>
/// 任务台台账列表查询
/// </summary>
public async Task<DataResult<List<dynamic>>> GetPageAsync(PageRequest<QueryTaskManageDto> querySearch)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
//序列化查询条件
List<IConditionalModel>? whereList = null;
if (!string.IsNullOrEmpty(querySearch.QueryCondition))
{
whereList = tenantDb.Utilities.JsonToConditionalModels(querySearch.QueryCondition);
}
// 格式化参数
TaskBaseTypeEnum? taskType = null;
if (Enum.TryParse(typeof(TaskBaseTypeEnum), querySearch.OtherQueryCondition?.TaskType, out object? temp))
{
taskType = (TaskBaseTypeEnum)temp;
};
TaskStatLevelEnum? taskStatLevel = null;
if (Enum.TryParse(typeof(TaskStatLevelEnum), querySearch.OtherQueryCondition?.TaskCategory, out object? tempStat))
{
taskStatLevel = (TaskStatLevelEnum)tempStat;
};
var userId = long.Parse(user.UserId);
DataResult<List<dynamic>> result;
switch (taskType)
{
case TaskBaseTypeEnum.BC:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskBCInfo>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
Id = t.Id.SelectAll(),
bc.BUSI_TYPE,
bc.SHIPPER,
bc.CONSIGNEE,
bc.NOTIFYPARTY,
bc.BC_MODIFY_TIMES,
bc.BC_MODIFY_DATE,
//bc.MBL_NO,
bc.VESSEL,
bc.VOYNO,
bc.CARRIER,
bc.PLACERECEIPT,
bc.PORTLOAD,
bc.CLOSING_DATE,
bc.VGM_CUTOFF_TIME,
bc.ETA,
//bc.ETD,
bc.POD_ETA,
bc.CUT_SINGLE_TIME,
bc.PORTDISCHARGE,
bc.PLACEDELIVERY,
bc.SHIPPING_METHOD,
bc.SERVICE,
bc.PRETRANS_MODE,
bc.DESCRIPTION,
bc.ISSUEPLACE,
bc.COLLECTION_TERMINAL,
bc.CONTRACTNO,
bc.PREPARDAT,
bc.SHIP_AGENT,
bc.YARD,
bc.YARD_CONTACT_USR,
bc.YARD_CONTACT_TEL,
bc.FST_CUSTOMER_SER_USRNAME,
bc.FST_CUSTOMER_SER_TEL,
bc.FST_CUSTOMER_SER_EMAIL,
bc.REMARK1,
bc.CY_CUTOFF_TIME,
bc.CARRIERID,
bc.LANECODE,
bc.LANENAME,
bc.CARRIAGE_TYPE,
bc.CARRIAGE_TYPE_NAME,
bc.BOOKING_SLOT_TYPE,
bc.BOOKING_SLOT_TYPE_NAME,
bc.CTN_STAT,
bc.WEEK_AT,
bc.DETENSION_FREE_DAYS,
bc.SI_CUT_DATE,
bc.MANIFEST_CUT_DATE,
bc.MDGF_CUT_DATE,
bc.TRANSFER_PORT_1,
bc.TRANSFER_PORT_2,
bc.SECOND_VESSEL,
bc.SECOND_VOYNO,
bc.SECOND_ETD,
bc.SECOND_ETA,
//bc.STATUS,
bc.FILE_MD5,
bc.LAST_TOBOOKING_DATE,
bc.FROM_EMAIL,
bc.RECV_EMAIL,
bc.BOOKING_ORDER_ID,
bc.BOOKING_SLOT_ID,
bc.BOOKING_COMFIRM_DATE,
bc.BATCH_NO,
bc.CUSTOM_SI_CUT_DATE,
bc.IS_SET_AUTO_EMAIL,
bc.IS_SEND_EMAIL,
bc.DIFF_NUM,
bc.AUTO_SEND_USER,
bc.PROCESS_STATUS,
bc.PROCESS_RESULT,
bc.PROCESS_DATE,
bc.PRICE_CALCULATION_DATE
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.SI_FEEDBACK:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskSiSubmitted>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.CARRIER,
//bc.MBL_NO,
bc.TAKE_ISSUETYPE_NAME,
bc.ISSUETYPE,
bc.NOTICE_DATE,
bc.BOOKING_ID,
bc.SUBMITTED_DATE,
bc.BILLOF_NUM,
bc.RELEASE_INSTRUCTION,
bc.SI_SUBTYPE,
bc.SHIPPER,
bc.CONSIGNEE,
bc.NOTIFYPARTY,
bc.NOTIFYPARTY2,
bc.TRANSPORT_RECEIVER,
bc.MARKS,
bc.HSCODE,
bc.DESCRIPTION,
bc.PKGS,
bc.KINDPKGS,
bc.KGS,
bc.CBM,
bc.VESSEL,
bc.VOYNO,
bc.COMMODITY,
bc.PLACERECEIPTID,
bc.PLACERECEIPT,
bc.PORTLOADID,
bc.PORTLOAD,
bc.PORTDISCHARGEID,
bc.PORTDISCHARGE,
bc.PLACEDELIVERYID,
bc.PLACEDELIVERY,
bc.PROCESS_STATUS,
bc.IS_SET_AUTO_UPD_BOOKING,
bc.PROCESS_RESULT,
bc.PROCESS_DATE,
bc.DIFF_NUM,
bc.IS_UPDATE_BOOKING,
bc.UPDATE_BOOKING_DATE
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.INVOICE_BILL_MAIL:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskPerBillBase>((t, a, bc) => t.Id == bc.TASK_PKID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_PKID,
//bc.MBL_NO,
bc.INVOICE_NO,
bc.CANCEL_NO,
bc.TOTAL_AMOUNT,
bc.IS_DONGSH_RECV,
bc.IS_DONGSH_RESULT,
bc.DONGSH_RECV_TIME,
bc.DONGSH_RESULT_TIME,
bc.DONGSH_RECV_REASON
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.TRUCK_DISPATCH:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskTruck>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.BookingTruckId,
bc.BookingId,
bc.TruckId,
bc.TruckCode,
bc.TruckName,
bc.ToName,
bc.Attn,
bc.AttnTel,
bc.AttnMail,
bc.AttnFax,
bc.FromName,
bc.FromTel,
bc.FromMail,
bc.FromMobile,
bc.FromFax,
bc.KGS,
bc.Fee,
bc.PayMethod,
bc.PayMethodName,
bc.TruckTime,
bc.YARDID,
bc.YARD,
bc.YARDCONTRACT,
bc.YARDCONTRACTTEL,
bc.FactoryId,
bc.FactoryCode,
bc.FactoryName,
bc.FactoryContact,
bc.FactoryTel,
bc.ReturnTime,
bc.InYardID,
bc.InYard,
bc.InYardContact,
bc.InYardContractTel,
//bc.NeedArriveTime,
bc.ClosingTime,
bc.PickUpTime,
bc.IsGuaJi,
//bc.Status,
bc.Attention,
bc.Remark,
bc.DispatcherId,
bc.DispatcherName,
bc.TruckFlowNo,
bc.TaskNo,
bc.Vessel,
bc.VoyNo,
bc.MBLNo,
bc.CntrTotal,
bc.FactoryAddr
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.CUT_MODIFY:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskCutDateChangeInfo>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.CARRIER,
bc.VESSEL,
bc.VOYNO,
bc.NOTICE_DATE
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.ROLLING_NOMINATION:
case TaskBaseTypeEnum.TRANSFER_NOMINATION:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskRollingNomination>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.PLAN_TYPE,
bc.BATCH_NO,
bc.CARRIERID,
bc.CARRIER,
bc.CONFIRM_DEAD_LINE,
bc.READ_CREATE_TIME,
bc.ROLL_DOUBLE_REMARK,
bc.PLAN_TXT,
//bc.REMARK,
bc.TASK_BATCH_TOTAL,
bc.TASK_BATCH_PER_TOTAL
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.DRAFT:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskDraftInfo>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.CARRIER,
//bc.MBL_NO,
bc.BOOKING_ID,
bc.IS_CHANGE,
bc.IS_EMAIL_SEND,
bc.SEND_EMAIL_DATE,
bc.NOTICE_DATE,
})
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.POD_DISCHARGE_FULL:
case TaskBaseTypeEnum.POD_GATEOUT_FULL:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskPodDischargeGateoutFull>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.CARRIER,
bc.NOTICE_TYPE,
bc.NOTICE_TYPE_NAME,
//bc.MBL_NO,
bc.NOTICE_DATE
}).ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.CAUTION_NOTICE:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskCautionNotice>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.SOURCE_SYSTEM,
bc.SOURCE_BUSI_TYPE,
bc.SOURCE_BUSI_TYPENAME,
bc.NOTIFY_CONTENT,
//bc.MBL_NO,
bc.CARRIER,
bc.CAUTION_NOTICE_TYPE,
bc.IS_WEEK_DIFF,
bc.IS_PRICE_DATE_DIFF,
bc.IS_TRANSFER,
bc.IS_VESSEL_CHANGE,
bc.IS_CUT_DATE_ADVANCED,
bc.BOOKING_ID,
bc.BOOKING_SLOT_ID,
bc.SOURCE_TASK_ID,
bc.OLD_VAL,
bc.NEW_VAL,
}).ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.ROUTE_CUT_CHANGE:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskRouteChangeAdvisory>((t, a, bc) => t.Id == bc.TASK_ID)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>((t, a, bc) => new
{
PK_ID = t.Id.SelectAll(),
bc.TASK_ID,
bc.VESSEL,
bc.VOYNO,
bc.CARRIER,
bc.READ_PORTLOAD,
bc.ORIG_ETD,
bc.MDGF_CUT_DATE,
bc.ETA,
//bc.ETD,
bc.SI_CUT_DATE,
bc.TM_SHIFT_CUT_DATE,
bc.VGM_CUTOFF_TIME,
bc.CY_CUT_DATE,
bc.ROUTE_CODE,
bc.EMAIL_SUBJECT,
bc.WEEK,
bc.PORTLOADID,
bc.PORTLOAD
}).ToQueryPageAsync(querySearch.PageCondition);
return result;
}
default:
{
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.Where(whereList)
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
.Select<dynamic>(t => t)
.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
}
}
/// <summary>
/// 获取登陆人相关的任务统计信息
/// </summary>
/// <param name="isReCalc">是否强制计算</param>
/// <returns>返回回执</returns>
public async Task<DataResult<TaskUserStatResultInfo>> GetCurrentTotalStat(bool isReCalc)
{
TaskUserStatResultInfo resultInfo = new TaskUserStatResultInfo
{
LevelTop = new List<TaskUserStatItem>(),
LevelNext = new List<TaskUserStatItemNext>(),
LevelTree = new List<TaskUserStatItemTree>()
};
/*
1、首先判断当前登陆人是否有统计记录如果没有触发统计生成统计记录。
2、如果isReCalc=true表示强制重新统计数据并重新更新统计数据。
3、按照统计类型个人/公共)、任务状态、是否异常分组汇总,并写入统计表。
*/
//var userTendInfo = await _sysUserRepository.AsQueryable()
// .LeftJoin<SysTenant>((usr, ten) => usr.TenantId == ten.Id)
// .Where(usr => usr.Id == UserManager.UserId)
// .Select((usr, ten) => new { User = usr, Tend = ten }).FirstAsync();
//if (userTendInfo == null)
// throw Oops.Oh($"当前用户关联租户信息获取失败");
////var statList = _taskStatManageInfoRepository.AsQueryable().Where(t => (t.USER_ID == userTendInfo.User.Id
////&& t.STAT_TYPE == TaskStatLevelEnum.PERSON.ToString()) || (t.COMP_ID == userTendInfo.Tend.Id && t.STAT_TYPE == TaskStatLevelEnum.PUBLIC.ToString())).ToList();
////菜单375504048771141=我的任务台账
//List<long> userlist = await _sysDataUserMenuService.GetDataScopeList(MenuConst.MenuTaskManage);
//bool isAdmin = userlist == null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var userId = long.Parse(user.UserId);
//任务列表分组统计
var groupList = await tenantDb.Queryable<TaskBaseInfo>()
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.Where((t, a) => t.IS_PUBLIC == 1
|| t.CreateBy == userId
|| (t.IS_PUBLIC == 0 && a.UserId == userId))
.GroupBy(t => new { t.TASK_TYPE, t.STATUS, t.IS_EXCEPT, t.IS_PUBLIC })
.Select(t => new
{
Total = SqlFunc.AggregateCount(t.Id),
TaskType = t.TASK_TYPE,
Status = t.STATUS,
IsExcept = t.IS_EXCEPT,
IsPublic = t.IS_PUBLIC
}).ToListAsync();
var exceptList = groupList
.Where(t => t.IsExcept == 1).ToList();
var personList = groupList
.Where(t => t.IsExcept == 0 && t.IsPublic == 0).ToList();
var publicList = groupList
.Where(t => t.IsExcept == 0 && t.IsPublic == 1).ToList();
#region 异常
if (exceptList.Count > 0)
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.EXCPTION.ToString(),
Name = TaskStatLevelEnum.EXCPTION.EnumDescription(),
Total = exceptList.Sum(t => t.Total),
SortNo = (int)TaskStatLevelEnum.EXCPTION,
ActionKey = TaskStatLevelEnum.EXCPTION.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
exceptList.GroupBy(t => t.Status)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{currEnum.ToString()}"
});
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
exceptList.GroupBy(t => new { t.Status, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
//TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
TaskBaseTypeEnum currEnum = (TaskBaseTypeEnum)System.Enum.Parse(typeof(TaskBaseTypeEnum), t.Key.TaskType);
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
NextKey = t.Key.Status,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
});
});
}
#endregion
#region 个人
if (personList.Count > 0)
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.PERSON.ToString(),
Name = TaskStatLevelEnum.PERSON.EnumDescription(),
Total = personList.Sum(t => t.Total),
SortNo = (int)TaskStatLevelEnum.PERSON,
ActionKey = TaskStatLevelEnum.PERSON.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
personList.GroupBy(t => t.Status)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.PERSON.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{currEnum.ToString()}"
});
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
personList.GroupBy(t => new { t.Status, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
//TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
TaskBaseTypeEnum currEnum = (TaskBaseTypeEnum)System.Enum.Parse(typeof(TaskBaseTypeEnum), t.Key.TaskType);
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.PERSON.ToString(),
NextKey = t.Key.Status,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
});
});
}
#endregion
#region 公共
if (publicList.Count > 0)
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.PUBLIC.ToString(),
Name = TaskStatLevelEnum.PUBLIC.EnumDescription(),
Total = publicList.Sum(t => t.Total),
SortNo = (int)TaskStatLevelEnum.PUBLIC,
ActionKey = TaskStatLevelEnum.PUBLIC.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
publicList.GroupBy(t => t.Status)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{currEnum.ToString()}"
});
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
publicList.GroupBy(t => new { t.Status, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
//TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
TaskBaseTypeEnum currEnum = (TaskBaseTypeEnum)System.Enum.Parse(typeof(TaskBaseTypeEnum), t.Key.TaskType);
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
NextKey = t.Key.Status,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
});
});
}
#endregion
if (resultInfo.LevelTree != null && resultInfo.LevelTree.Count > 0)
{
resultInfo.LevelTree = resultInfo.LevelTree.OrderBy(x => x.SortNo).ToList();
}
return DataResult<TaskUserStatResultInfo>.Success(resultInfo);
}
#region 私有方法
/// <summary>
/// 保存文件并返回文件完整路径
/// </summary>
/// <param name="fileBytes">文件二进制流</param>
/// <param name="batchNo">批次号</param>
/// <param name="printFileType">文件类型</param>
/// <param name="attachFileType">附件类型 bcfiles-BC文件 sofile-订舱附件</param>
/// <returns>返回文件完整路径</returns>
private async Task<string> SaveFile(byte[] fileBytes, string batchNo,
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}";
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";
}
var id = SnowFlakeSingle.Instance.NextId();
var fileSaveName = $"{id}{fileType}".ToLower();
string fileRelaPath = Path.Combine(relativePath, fileSaveName).ToLower();
string fileAbsPath = Path.Combine(dirAbs, fileSaveName).ToLower();
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 bookFilePath;
}
/// <summary>
/// 获取文件类型
/// </summary>
/// <param name="fileName">文件完成路径</param>
/// <returns>返回文件类型枚举</returns>
private 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>
/// 取消任务(可批量)
/// </summary>
/// <param name="ids">任务主键数组</param>
/// <returns>返回结果</returns>
public async Task<DataResult<TaskManageOrderResultDto>> CancelTask(long[] ids)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var userId = long.Parse(user.UserId);
string batchNo = Guid.NewGuid().ToString();
var taskList = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => ids.Contains(x.Id)).ToListAsync();
List<TaskManageOrderResultDto> taskRunList = new List<TaskManageOrderResultDto>();
_logger.LogInformation("批次={no} ids={ids} 取消任务开始", batchNo, string.Join(",", ids));
var noList = ids.Select((a, idx) => new { no = idx + 1, id = a }).ToList();
foreach (var bk in taskList)
{
var sortNo = noList.FirstOrDefault(a => a.id == bk.Id).no;
taskRunList.Add(await InnerManualTask(batchNo, bk, TaskOperTypeEnum.CANCEL_TASK, sortNo));
}
result.succ = true;
result.msg = "执行成功";
var downResultList = taskRunList.Select(x => x).ToList();
if (downResultList.Any(x => !x.succ))
{
result.succ = false;
result.msg = "执行失败";
}
else
{
result.succ = true;
result.msg = downResultList.FirstOrDefault().msg;
}
result.ext = downResultList;
var succ = downResultList.Count(x => x.succ);
var fail = downResultList.Count(x => !x.succ);
if (succ > 0)
{
result.batchTotal = succ.ToString();
}
else
{
result.batchTotal = "- ";
}
if (fail > 0)
{
result.batchTotal += "/" + fail.ToString();
}
else
{
result.batchTotal += " -";
}
return DataResult<TaskManageOrderResultDto>.Success(result);
}
#region 单票执行任务
/// <summary>
/// 单票执行任务
/// </summary>
/// <param name="batchNo">批次号</param>
/// <param name="model">任务详情</param>
/// <param name="taskOperTypeEnum">操作类型</param>
/// <param name="sortNo">顺序号</param>
/// <returns>返回回执</returns>
private async Task<TaskManageOrderResultDto> InnerManualTask(string batchNo, TaskBaseInfo model,
TaskOperTypeEnum taskOperTypeEnum, int sortNo)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
result.bno = model.TASK_NO;
try
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var userId = long.Parse(user.UserId);
if (taskOperTypeEnum == TaskOperTypeEnum.COMPLETE_TASK)
{
if (model.TASK_TYPE == TaskBaseTypeEnum.TRUCK_DISPATCH.ToString())
{
if (model.STATUS == TaskStatusEnum.Cancel.ToString())
{
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskCannotCompleteWhenStatusMismatch)), TaskStatusEnum.Cancel.EnumDescription()));
}
}
if (model.TASK_TYPE == TaskBaseTypeEnum.CANCELLATION.ToString())
{
//收到订舱已被取消邮件后生成的任务,如果点击完成,(订舱状态变为【退舱】,注意这里还需要确认)
}
model.COMPLETE_DATE = DateTime.Now;
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.EnumDescription();
model.IS_COMPLETE = 1;
model.STATUS = TaskStatusEnum.Complete.ToString();
model.STATUS_NAME = TaskStatusEnum.Complete.EnumDescription();
await tenantDb.Updateable(model).UpdateColumns(it => new
{
it.COMPLETE_DATE,
it.COMPLETE_DEAL,
it.COMPLETE_DEAL_NAME,
it.IS_COMPLETE,
it.STATUS,
it.STATUS_NAME,
it.UpdateBy,
it.UpdateTime,
it.UpdateUserName
}).ExecuteCommandAsync();
}
else if (taskOperTypeEnum == TaskOperTypeEnum.CANCEL_TASK)
{
if (model.TASK_TYPE == TaskBaseTypeEnum.CHANGE_SHIP.ToString())
{
model.STATUS = TaskStatusEnum.Cancel.ToString();
model.STATUS_NAME = TaskStatusEnum.Cancel.EnumDescription();
await tenantDb.Updateable(model).UpdateColumns(it => new
{
it.COMPLETE_DATE,
it.COMPLETE_DEAL,
it.COMPLETE_DEAL_NAME,
it.IS_COMPLETE,
it.STATUS,
it.STATUS_NAME,
it.UpdateBy,
it.UpdateTime,
it.UpdateUserName
}).ExecuteCommandAsync();
}
else if (model.TASK_TYPE == TaskBaseTypeEnum.ABORT_CHANGE_SHIP.ToString())
{
/*
1.如果原换船通知已经接受,需要把原船名航次恢复并通知客户取消换船。
2.如果原换船通知未作处理,点击接受或者结束任务时提示:本票货存在未处理换船通知,请先结束原换船任务然后结束本任务。
3.如果原换船任务为结束任务,在取消换船任务点接受时,提示未做换船,请点击结束任务。
*/
// 查询同票主单的是否有未处理的换船通知
// _taskBaseInfoRepository.AsQueryable().Where(t=>t.MBL_NO.Equals(taskBaseInfo.MBL_NO) && )
}
else
{
model.STATUS = TaskStatusEnum.Cancel.ToString();
model.STATUS_NAME = TaskStatusEnum.Cancel.EnumDescription();
await tenantDb.Updateable(model).UpdateColumns(it => new
{
it.STATUS,
it.STATUS_NAME,
it.UpdateBy,
it.UpdateTime,
it.UpdateUserName
}).ExecuteCommandAsync();
}
}
result.succ = true;
result.msg = "执行成功";
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.Message;
}
return result;
}
/// <summary>
/// 完成任务(可批量)
/// </summary>
/// <param name="ids">任务主键数组</param>
/// <returns>返回结果</returns>
public async Task<DataResult<TaskManageOrderResultDto>> CompleteTask(long[] ids)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var userId = long.Parse(user.UserId);
string batchNo = Guid.NewGuid().ToString();
var taskList = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => ids.Contains(x.Id)).ToListAsync();
List<TaskManageOrderResultDto> taskRunList = new List<TaskManageOrderResultDto>();
_logger.LogInformation("批次={no} ids={ids} 完成任务开始", batchNo, string.Join(",", ids));
var noList = ids.Select((a, idx) => new { no = idx + 1, id = a }).ToList();
foreach (var bk in taskList)
{
var sortNo = noList.FirstOrDefault(a => a.id == bk.Id).no;
taskRunList.Add(await InnerManualTask(batchNo, bk, TaskOperTypeEnum.COMPLETE_TASK, sortNo));
}
result.succ = true;
result.msg = "执行成功";
var downResultList = taskRunList.Select(x => x).ToList();
if (downResultList.Any(x => !x.succ))
{
result.succ = false;
result.msg = "执行失败";
}
else
{
result.succ = true;
result.msg = downResultList.FirstOrDefault().msg;
}
result.ext = downResultList;
var succ = downResultList.Count(x => x.succ);
var fail = downResultList.Count(x => !x.succ);
if (succ > 0)
{
result.batchTotal = succ.ToString();
}
else
{
result.batchTotal = "- ";
}
if (fail > 0)
{
result.batchTotal += "/" + fail.ToString();
}
else
{
result.batchTotal += " -";
}
return DataResult<TaskManageOrderResultDto>.Success(result);
}
#endregion
}
}