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.

4420 lines
219 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.Condition;
using DS.Module.Core.Constants;
using DS.Module.Core.Data;
using DS.Module.Core.Enums;
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.Code.Dtos;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Code.Interface;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.Map.Dtos;
using DS.WMS.Core.Map.Interface;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Op.Dtos.Cargoo;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Op.Interface;
using DS.WMS.Core.Sys.Entity;
using DS.WMS.Core.Sys.Interface;
using DS.WMS.Core.TaskInteraction.Entity;
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.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SqlSugar;
using System.Linq.Expressions;
namespace DS.WMS.Core.TaskPlat.Method
{
public class TaskManageService : TaskManageBaseService<TaskManageService>, ITaskManageService
{
// 实例化时构建
private readonly ICodeCtnService codeCtnService;
private readonly ICodePortService codePortService;
private readonly IMappingPortService mappingPortService;
private readonly IMappingCarrierService mappingCarrierService;
private readonly ICodeCarrierService codeCarrierService;
private readonly ICommonService commonService;
// 按需构建
//private readonly Lazy<ISeaExportCommonService> seaExportCommonService;
/// <summary>
/// 上一次进行全局任务匹配的时间
/// </summary>
public static DateTime LastMatchTaskTime = DateTime.Now;
/// <summary>
/// 需要查海运出口表的小写字段名
/// </summary>
static string[] seaExportFields = ["customerid", "saleid", "customerservice", "operatorid"]; //, "portload_code", "portdischarge_code"
public TaskManageService(IUser user,
ILogger<TaskManageService> logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IWebHostEnvironment environment,
ICodeCtnService codeCtnService,
ICodePortService codePortService,
IMappingPortService mappingPortService,
IMappingCarrierService mappingCarrierService,
ICodeCarrierService codeCarrierService,
ICommonService commonService) : base(user, logger, saasDbService, serviceProvider, environment)
{
this.codeCtnService = codeCtnService;
this.codePortService = codePortService;
this.mappingPortService = mappingPortService;
this.mappingCarrierService = mappingCarrierService;
this.codeCarrierService = codeCarrierService;
this.commonService = commonService;
//seaExportCommonService = new Lazy<ISeaExportCommonService>(serviceProvider.GetRequiredService<ISeaExportCommonService>);
}
#region 对工作流提供的接口
/// <summary>
/// 工作流设置任务在个人下的状态
/// </summary>
/// <param name="bsno">主业务主键</param>
/// <param name="taskBaseTypeEnum">主业务类型</param>
/// <param name="taskStatusEnum">业务状态</param>
/// <param name="statusTime">状态发生时间</param>
/// <param name="userInfos">要设置任务状态的人员列表</param>
/// <param name="childBsno">子业务主键[可选,当不为空时表示设置子任务的个人状态]</param>
/// <param name="childTaskBaseTypeEnum">子业务类型</param>
public async Task<DataResult> SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, List<RecvUserInfo> userInfos,
long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null)
{
logger.LogInformation("接收到任务个人状态修改报文 bsno={bsno} 状态设置={status} 人员列表={userList} childBsno={childBsno} childTaskBaseTypeEnum={childTaskBaseTypeEnum}", bsno, taskStatusEnum.ToString(), JsonConvert.SerializeObject(userInfos), childBsno, childTaskBaseTypeEnum);
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskTypeStr = taskBaseTypeEnum.ToString();
var taskId = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.OrderByDescending(a => a.Id)
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr)
.Select(t => new { t.Id })
.FirstAsync();
if (taskId == null)
{
logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskTypeStr}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
long waitSetTaskId = taskId.Id;
if (childBsno != null)
{
var childTypeStr = childTaskBaseTypeEnum.ToString();
var childTaskId = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.OrderByDescending(a => a.Id)
.Where(t => t.CHILD_OUT_BS_NO == childBsno && t.TASK_TYPE == childTypeStr && t.ParentTaskId == taskId.Id)
.Select(t => new { t.Id })
.FirstAsync();
if (childTaskId == null)
{
logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskBaseTypeEnum【{childTypeStr}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
waitSetTaskId = childTaskId.Id;
}
var userIdList = userInfos.Select(x => x.RecvUserId).ToList();
var taskBaseAllocationList = await tenantDb.Queryable<TaskBaseAllocation>()
.Where(x => x.TaskId == waitSetTaskId && userIdList.Contains(x.UserId))
.ToListAsync();
if (taskBaseAllocationList.Any())
{
taskBaseAllocationList.ForEach(x =>
{
x.Status = taskStatusEnum.ToString();
x.StatusName = taskStatusEnum.EnumDescription();
x.StatusTime = statusTime;
});
await tenantDb.Updateable(taskBaseAllocationList).UpdateColumns(x => new
{
x.UpdateBy,
x.UpdateTime,
x.UpdateUserName,
x.Status,
x.StatusName,
x.StatusTime
}).ExecuteCommandAsync();
}
return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess)));
}
/// <summary>
/// 通过业务Id设置任务状态(工作流使用)
/// </summary>
/// <param name="bsno">主任务业务主键</param>
/// <param name="taskBaseTypeEnum">主任务业务类型</param>
/// <param name="taskStatusEnum">业务状态</param>
/// <param name="statusTime">状态发生时间</param>
/// <param name="isCheckAllChildTaskComplete">完成任务前是否检查所有子任务是否完成</param>
/// <param name="taskDesc">任务描述</param>
/// <param name="userIdList">用户Id列表用于筛选指定用户下的任务[可选,当不为空时会设置此用户列表涉及到的相关任务的状态]</param>
/// <param name="childBsno">子任务业务主键[可选,当不为空时表示设置子任务的状态]</param>
/// <param name="childTaskBaseTypeEnum">子任务业务类型</param>
public async Task<DataResult> SetTaskStatusWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, bool isCheckAllChildTaskComplete, string? taskDesc = null, List<long>? userIdList = null,
long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskTypeStr = taskBaseTypeEnum.ToString();
// 表示修改子任务的状态
if (childBsno != null)
{
var taskId = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr)
.OrderByDescending(a => a.Id)
.Select(t => new { t.Id })
.FirstAsync();
if (taskId == null)
{
var log = $"设置子任务状态时未查询到父任务父任务BSNO{bsno}父任务TaskBaseTypeEnum{taskBaseTypeEnum}";
logger.LogInformation(log);
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
var childTaskTypeStr = childTaskBaseTypeEnum.ToString();
var childTask = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => x.IsChild == true
&& x.TASK_TYPE == childTaskTypeStr
&& x.CHILD_OUT_BS_NO == childBsno)
.FirstAsync();
if (childTask == null)
{
var log = $"设置子任务状态时未查询到子任务父任务BSNO{bsno}父任务TaskBaseTypeEnum{taskBaseTypeEnum}子任务childBsno{childBsno}子任务childTaskBaseTypeEnum{childTaskBaseTypeEnum}";
logger.LogInformation(log);
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
return await SetTaskStatus(childTask, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc);
}
// 表示修改主任务的状态
else
{
// 表示修改主任务的状态
if (userIdList == null || userIdList.Count() == 0)
{
TaskBaseInfo taskInfo = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.OrderByDescending(t => t.Id)
.FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr);
if (taskInfo == null)
{
logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskBaseTypeEnum}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
return await SetTaskStatus(taskInfo, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc);
}
// 表示修改主任务的状态,但是通过用户列表做进一步筛选
else
{
var taskIdList = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.OrderByDescending(t => t.Id)
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr)
.Select(x => x.Id)
.ToListAsync();
if (taskIdList.Count() == 0)
{
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
var waitSetStatusTaskIdList = await tenantDb.Queryable<TaskBaseAllocation>()
.Where(x => taskIdList.Contains(x.TaskId) && userIdList.Contains(x.UserId))
.Select(x => x.TaskId)
.Distinct()
.ToListAsync();
var taskInfoList = await tenantDb.Queryable<TaskBaseInfo>()
.ClearFilter(typeof(IOrgId))
.Where(x => waitSetStatusTaskIdList.Contains(x.Id))
.ToListAsync();
var resultList = new List<bool>();
foreach (var item in taskInfoList)
{
var itemResult = await SetTaskStatus(item, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc);
resultList.Add(itemResult.Succeeded);
}
if (resultList.Any(x => !x))
{
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
else
{
return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess)));
}
}
}
}
/// <summary>
/// 工作流任务转交
/// </summary>
/// <param name="bsno">主任务业务主键</param>
/// <param name="taskBaseTypeEnum">主任务业务类型</param>
/// <param name="userInfos">要转交的人员信息列表</param>
/// <param name="childBsno">子任务业务主键[可选,当不为空时表示设置子任务的状态]</param>
/// <param name="childTaskBaseTypeEnum">子任务业务类型</param>
public async Task<DataResult> TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List<RecvUserInfo> userInfos, SqlSugarScopeProvider? tenantDb = null,
long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null)
{
tenantDb ??= saasDbService.GetBizDbScopeById(user.TenantId);
logger.LogInformation("接收到任务转交报文 bsno={bsno} taskBaseTypeEnum={taskBaseTypeEnum} 转交人员列表={userinfo} childBsno={childBsno} childTaskBaseTypeEnum={childTaskBaseTypeEnum}",
bsno,
taskBaseTypeEnum,
JsonConvert.SerializeObject(userInfos),
childBsno,
childTaskBaseTypeEnum);
try
{
var taskTypeStr = taskBaseTypeEnum.ToString();
var childTaskTypeStr = childTaskBaseTypeEnum.ToString();
var task = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr)
.OrderByDescending(a => a.Id)
.Select(t => new { t.Id, t.IS_PUBLIC })
.FirstAsync();
if (task == null)
{
logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskBaseTypeEnum}】未查询到父任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
string? completedBusinessStatusCode = "";
if (childBsno != null)
{
var childTask = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => x.IsChild == true
&& x.TASK_TYPE == childTaskTypeStr
&& x.CHILD_OUT_BS_NO == childBsno)
.Select(t => new { t.Id, t.IS_PUBLIC })
.FirstAsync();
if (childTask == null)
{
logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskTypeStr【{childTaskTypeStr}】未查询到子任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
task = childTask;
}
else
{
completedBusinessStatusCode = await tenantDb.Queryable<TaskFlowModule>()
.Where(x => x.ModuleType == 2 && x.TaskType == taskTypeStr)
.Select(x => x.CompletedBusinessStatusCode)
.FirstAsync();
}
await tenantDb.Ado.BeginTranAsync();
// 删除旧的
var ids = await tenantDb.Queryable<TaskBaseAllocation>().Where(x => x.TaskId == task.Id).Select(x => x.Id).ToListAsync();
if (ids.Count > 0)
{
await tenantDb.Deleteable<TaskBaseAllocation>().Where(x => ids.Contains(x.Id)).ExecuteCommandAsync();
}
// 插入新的
if (userInfos.Count > 0)
{
var userIdList = userInfos.Select(x => x.RecvUserId).Distinct().ToList();
var userWithOrgMap = await db.Queryable<SysUser>().Where(x => userIdList.Contains(x.Id)).Select(x => new { x.Id, x.DefaultOrgId }).ToListAsync();
var allocationList = userInfos.Select(x => new TaskBaseAllocation
{
TaskId = task.Id,
UserId = x.RecvUserId,
UserName = x.RecvUserName,
Status = TaskStatusEnum.Create.ToString(),
StatusName = TaskStatusEnum.Create.EnumDescription(),
StatusTime = DateTime.Now,
BusinessId = bsno,
GoodStatusCode = completedBusinessStatusCode,
OrgId = userWithOrgMap.FirstOrDefault(m => m.Id == x.RecvUserId)?.DefaultOrgId ?? 0
}).ToList();
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
}
if ((task.IS_PUBLIC == 1 && userInfos.Count > 0) ||
(task.IS_PUBLIC == 0 && userInfos.Count == 0))
{
var isPublic = userInfos.Count == 0 ? 1 : 0;
await tenantDb.Updateable<TaskBaseInfo>()
.SetColumns(x => x.IS_PUBLIC == isPublic)
.Where(x => x.Id == task.Id)
.ExecuteCommandAsync();
}
await tenantDb.Ado.CommitTranAsync();
return DataResult.Successed("操作成功!", MultiLanguageConst.DataUpdateSuccess);
}
catch (Exception)
{
await tenantDb.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 工作流设置任务对象属性
/// </summary>
/// <param name="bsno">主任务业务主键</param>
/// <param name="taskBaseTypeEnum">主任务业务类型</param>
/// <param name="childBsno">子任务业务主键[可选,当不为空时表示设置子任务的状态]</param>
/// <param name="childTaskBaseTypeEnum">子任务业务类型</param>
/// <param name="columns">要修改的列</param>
public async Task<DataResult> SetTaskBaseInfoPropertyWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum,
long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null,
params Expression<Func<TaskBaseInfo, bool>>[] columns)
{
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var taskTypeStr = taskBaseTypeEnum.ToString();
var childTaskTypeStr = childTaskBaseTypeEnum.ToString();
long? taskInfoId = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.OrderByDescending(a => a.Id)
.Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr)
.Select(t => t.Id)
.FirstAsync();
if (taskInfoId == null || taskInfoId == 0)
{
logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum【{taskBaseTypeEnum}】未查询到任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
else
{
logger.LogInformation($"根据bsno:【{bsno}】,查询出taskInfoId=【{taskInfoId}】");
}
if (childBsno != null)
{
long? childTaskId = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => x.IsChild == true
&& x.TASK_TYPE == childTaskTypeStr
&& x.CHILD_OUT_BS_NO == childBsno)
.Select(t => t.Id)
.FirstAsync();
if (childTaskId == null || childTaskId == 0)
{
logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskTypeStr【{childTaskTypeStr}】未查询到子任务");
return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData)));
}
taskInfoId = childTaskId;
}
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 => taskInfoId == x.Id)
.ExecuteCommandAsync();
return DataResult.Successed("操作成功");
}
#endregion
private static object ImportLockObj = new object();
/// <summary>
/// 创建任务公共方法
/// </summary>
/// <param name="info"></param>
/// <param name="file"></param>
/// <param name="modifyFile"></param>
/// <returns></returns>
public async Task<DataResult> InitTaskJob(TaskManageOrderMessageInfo info, IFormFile file = null, IFormFile modifyFile = null)
{
string batchNo = Guid.NewGuid().ToString();
try
{
//Monitor.Enter(ImportLockObj);
logger.LogInformation("批次={no} 接收到创建任务报文 报文={msg}", batchNo, JsonConvert.SerializeObject(info));
if (info.Head.IsChild && info.Head.ChildBSNO == 0)
{
throw new Exception("创建子任务需要指定子任务的业务主键[info.Head.ChildBSNO]");
}
SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
// 人员信息测试用
//var a1 = user.UserId;
//var b1 = user.UserName;
//var c1 = user.TenantId;
//var d1 = user.TenantName;
//var e1 = user.OrgId;
//var sql = tenantDb.Queryable<SeaExport>().Where(x => x.Id > 232).ToSqlString();
TaskBaseInfo taskInfo = null;
var taskTypeStr = info.Main.TaskType.ToString();
var childTaskTypeStr = info.Main.ChildTaskType.ToString();
var createStatusStr = TaskStatusEnum.Create.ToString();
var pendingStatusStr = TaskStatusEnum.Pending.ToString();
long parentTaskId = 0;
if (info.Head.IsChild)
{
// 根据BSNO查现有任务的主键
var parentTask = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => x.OUT_BS_NO == info.Head.BSNO && x.TASK_TYPE == taskTypeStr && x.IsChild == false)
.OrderByDescending(x => x.Id)
.Select(x => new { x.Id })
.FirstAsync();
if (parentTask == null)
{
throw new Exception($"创建子任务时根据未查询到父任务父任务BSNO{info.Head.BSNO}父任务TaskBaseTypeEnum{taskTypeStr}");
}
parentTaskId = parentTask.Id;
// 判断子任务是否重复
var existsChildTask = await tenantDb.Queryable<TaskBaseInfo>()
.Where(x => x.IsChild == true
//&& x.ParentTaskId == parentTask.Id
&& x.TASK_TYPE == childTaskTypeStr
&& x.CHILD_OUT_BS_NO == info.Head.ChildBSNO
&& (x.STATUS == createStatusStr || x.STATUS == pendingStatusStr))
.Select(x => new { x.Id, x.TASK_NO })
.FirstAsync();
if (existsChildTask != null)
{
var allotUserList = await allocationService.Value.GetAllotUserList(tenantDb, existsChildTask.Id);
var allotUserName = allotUserList.Select(x => x.userName);
var log = $"同一业务下已存在同任务类型的指定状态(待处理或挂起中)的子任务,不能重复创建(任务流水号:{existsChildTask.TASK_NO},接收人:{string.Join("", allotUserName)}";
throw new Exception(log);
}
}
else
{
// 特殊处理:费用审核、修改、删除(明细)相关的审核,同一单子可以有多条费用审核及特殊费用审核任务,所属人
if ((info.Main.TaskType
is TaskBaseTypeEnum.FEE_AUDIT
or TaskBaseTypeEnum.FEE_REJECTED
or TaskBaseTypeEnum.FEE_MODIFY_AUDIT
or TaskBaseTypeEnum.FEE_MODIFY_REJECTED
or TaskBaseTypeEnum.FEE_DELETE_AUDIT
or TaskBaseTypeEnum.FEE_DELETE_REJECTED)
&& info.Main.RecvUserInfoList?.Count > 0)
{
// 先查此订单在任务台账是否有指定类型的待处理的任务,如果有,查这些任务的归属人里是否已经包含了任务接收人
var existsTaskList = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.Where(t => t.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString()
&& t.OUT_BS_NO == info.Head.BSNO
&& t.TASK_TYPE == taskTypeStr
&& (t.STATUS == createStatusStr || t.STATUS == pendingStatusStr))
.Select(x => new { x.Id, x.TASK_NO })
.ToListAsync();
if (existsTaskList.Count > 0)
{
var existsTaskIdList = existsTaskList.Select(x => x.Id);
var recvUser = info.Main.RecvUserInfoList.First();
var existsRecvUser = await tenantDb.Queryable<TaskBaseAllocation>().Where(x => existsTaskIdList.Contains(x.TaskId) && x.UserId == recvUser.RecvUserId).AnyAsync();
if (existsRecvUser)
{
string log = $"订单Id{info.Head.BSNO}业务类型:{taskTypeStr}已有接收人:{recvUser.RecvUserId}/{recvUser.RecvUserName},跳过创建";
// 回写任务号
return await Task.FromResult(new DataResult(ResultCode.Success, log, data: existsTaskList.Select(x => x.TASK_NO)));
}
}
}
else
{
// 如果业务主键不为空,则通过业务主键进行重复判断
if (info.Head.BSNO is not (null or 0))
{
taskInfo = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.Where(t => t.OUT_BS_NO == info.Head.BSNO)
.WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr)
.OrderByDescending(a => a.Id)
.Select(x => new TaskBaseInfo()
{
Id = x.Id,
STATUS = x.STATUS
})
.FirstAsync();
}
// 否则通过Head.GID进行判断
else
{
taskInfo = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.Where(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}")
.WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr)
.OrderByDescending(a => a.Id)
.Select(x => new TaskBaseInfo()
{
Id = x.Id,
STATUS = x.STATUS
})
.FirstAsync();
}
}
}
// 只要任务最后一次处理任务的状态是已取消、已完成,就可以重入新的任务
if (taskInfo != null
&& taskInfo.STATUS != TaskStatusEnum.Cancel.ToString()
&& taskInfo.STATUS != TaskStatusEnum.Complete.ToString())
{
var allotUserList = await allocationService.Value.GetAllotUserList(tenantDb, taskInfo.Id);
var allotUserName = allotUserList.Select(x => x.userName);
var log = $"同一业务下已存在同任务类型的指定状态(待处理或挂起中)的任务,不能重复创建(任务流水号:{taskInfo.TASK_NO},接收人:{string.Join("", allotUserName)}";
throw new Exception(log);
}
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));
}
// 获取任务流水号
DataResult<string> sequence = commonService.GetSequenceNext<TaskBaseInfo>(tenantDb, user);
string taskNo = sequence.Data ?? "";
if (string.IsNullOrEmpty(taskNo))
{
taskNo = Guid.NewGuid().ToString();
}
//if (!sequence.Succeeded || sequence.Data is null)
//{
// return await Task.FromResult(DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist));
//}
taskInfo = new TaskBaseInfo
{
Id = SnowFlakeSingle.Instance.NextId(),
TASK_NO = taskNo,
STATUS = TaskStatusEnum.Create.ToString(),
STATUS_NAME = TaskStatusEnum.Create.EnumDescription(),
IS_EXCEPT = 0,
IS_COMPLETE = 0,
MBL_NO = info.Main.MBlNo,
TASK_TYPE = taskTypeStr,
//TASK_BASE_TYPE = taskTypeStr,
//CARRIER_ID = info.Main.CarrierId?.Trim(),
//IS_PUBLIC = string.IsNullOrWhiteSpace(info.Main.TaskUserId) ? 1 : 0,
IS_PUBLIC = info.Main.RecvUserInfoList?.Count > 0 ? 0 : 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_SOURCE_NAME = info.Main.TaskSource.EnumDescription(),
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,
CUSTOMER_NO = info.Main.CustomerNo,
//CUSTOMER_NUM = info.Main.CustomsNum,
//HBL_NO = info.Main.HBLNO,
//BOOKING_NO = info.Main.BookingNo,
//PORTDISCHARGE = info.Main.PortDischarge,
//PORTDISCHARGE_CODE = info.Main.PortDischargeCode,
//PORTDISCHARGE_ID = info.Main.PortDischargeId,
//PORTLOAD = info.Main.PortLoad,
//PORTLOAD_ID = info.Main.PortLoadId,
//PORTLOAD_CODE = info.Main.PortLoadCode,
CARRIER_ID = info.Main.CarrierPK,
CARRIER_CODE = info.Main.CarrierId,
CARRIER_NAME = info.Main.CarrierName,
CreateTime = DateTime.Now,
};
if (info.Head.IsChild)
{
taskInfo.IsChild = true;
taskInfo.ParentTaskId = parentTaskId;
taskInfo.CHILD_OUT_BS_NO = info.Head.ChildBSNO;
taskInfo.TASK_TYPE = childTaskTypeStr;
}
if (Enum.TryParse(typeof(TaskBaseTypeEnum), taskInfo.TASK_TYPE, out object? taskTypeTemp))
{
taskInfo.TASK_TYPE_NAME = ((TaskBaseTypeEnum)taskTypeTemp).EnumDescription();
}
if (info.Main.ExtData != null)
{
taskInfo.ExtData = info.Main.ExtData.ToJson();
}
// 如果船公司主键不为空则直接保存船公司主键、Code、Name等信息如果Name为空查询一下再赋值
if (taskInfo.CARRIER_ID != null)
{
if (string.IsNullOrEmpty(taskInfo.CARRIER_NAME))
{
var carrierShortName = await tenantDb.Queryable<CodeCarrier>().Where(x => x.Id == taskInfo.CARRIER_ID).Select(x => x.CnShortName).FirstAsync();
taskInfo.CARRIER_NAME = carrierShortName;
}
}
else
{
// 如果船公司主键为空但是Code不为空则通过映射查出船公司信息并保存
if (!string.IsNullOrEmpty(taskInfo.CARRIER_CODE))
{
// 船公司转换
var allMapCarrierList = (await mappingCarrierService.GetAllList())?.Data ?? new List<MappingCarrierRes>();
MappingCarrierRes? carrierInfo = allMapCarrierList.Where(t => t.MapCode.Equals(taskInfo.CARRIER_CODE, StringComparison.OrdinalIgnoreCase) && t.Module == MappingModuleConst.CONST_MAPPING_CARRIER_MODULE).FirstOrDefault();
if (carrierInfo != null)
{
taskInfo.CARRIER_ID = carrierInfo.LinkId;
taskInfo.CARRIER_CODE = carrierInfo.MapCode;
taskInfo.CARRIER_NAME = carrierInfo.MapName;
}
}
}
// 人员字段说明:
// 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);
// 否则判断任务关联订单,如果能关联到,则判断任务设置的角色;如果有设置,则将任务挂载到订单的指定角色上;如果没关联到或者没有设置,则作为公共任务
//else
//{
// // 1.查找任务的匹配设置
// var allotSet = await tenantDb.Queryable<TaskAllotSet>().Where(x => x.TaskType == taskTypeStr).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;
}
if (string.IsNullOrWhiteSpace(info.Main.TaskBatchNo))
{
info.Main.TaskBatchNo = SnowFlakeSingle.Instance.NextId().ToString();
}
await tenantDb.Insertable(taskInfo).ExecuteCommandAsync();
// 任务完成时要设置的业务状态编码
string? completedBusinessStatusCode = null;
if (info.Main.TaskSource == TaskSourceEnum.WORK_FLOW
&& info.Head.BSNO is not (null or 0))
{
var statusCodes = await tenantDb.Queryable<TaskFlowModule>()
.Where(x => x.ModuleType == 2 && x.TaskType == taskTypeStr)
.Select(x => new { x.CreatedBusinessStatusCode, x.CompletedBusinessStatusCode })
.FirstAsync();
if (!string.IsNullOrEmpty(statusCodes?.CreatedBusinessStatusCode))
{
try
{
// 1.设置相关订单的业务状态
await seaExportCommonService.Value.SetGoodsStatus(statusCodes.CreatedBusinessStatusCode, (long)info.Head.BSNO, tenantDb);
}
catch (Exception ex)
{
logger.LogError(ex, "任务创建时设置订单业务状态的过程中发生异常orderId={0}taskType={1}", (long)info.Head.BSNO, taskInfo.TASK_TYPE);
//throw;
}
try
{
// 2.设置货物状态为已完成
await djyServiceStatusService.Value.SaveServiceStatus(new EmbedServiceProjectStatusDto()
{
businessId = info.Head.BSNO.ToString()!,
SourceType = 1,
StatusCodes = [new() { StatusCode = statusCodes.CreatedBusinessStatusCode }]
});
}
catch (Exception ex)
{
logger.LogError(ex, "任务创建时设置订单的货物状态时发生异常orderId={0}taskType={1}", (long)info.Head.BSNO, taskInfo.TASK_TYPE);
//throw;
}
}
completedBusinessStatusCode = statusCodes?.CompletedBusinessStatusCode;
}
// 任务所属人员列表
// 如果明确指出接收人(接收人列表),则将任务作为个人任务
if (info.Main.RecvUserInfoList?.Count > 0)
{
logger.LogInformation("批次={no} 接收人列表 recvUserList={recvUserList} ", batchNo,
JsonConvert.SerializeObject(info.Main.RecvUserInfoList));
var userIdList = info.Main.RecvUserInfoList.Select(x => x.RecvUserId).ToList();
var userWithOrgMap = await db.Queryable<SysUser>().Where(x => userIdList.Contains(x.Id)).Select(x => new { x.Id, x.DefaultOrgId }).ToListAsync();
var allocationList = info.Main.RecvUserInfoList.Select(x =>
{
var alloc = new TaskBaseAllocation()
{
TaskId = taskInfo.Id,
UserId = x.RecvUserId,
UserName = x.RecvUserName,
Status = TaskStatusEnum.Create.ToString(),
StatusName = TaskStatusEnum.Create.EnumDescription(),
StatusTime = DateTime.Now,
BusinessId = info.Head.IsChild ? taskInfo.CHILD_OUT_BS_NO : taskInfo.OUT_BS_NO,
GoodStatusCode = completedBusinessStatusCode,
OrgId = userWithOrgMap.FirstOrDefault(m => m.Id == x.RecvUserId)?.DefaultOrgId ?? 0
};
return alloc;
}).ToList();
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
}
if (!string.IsNullOrWhiteSpace(info.Main.FilePath))
{
string attachFileType = string.Empty;
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_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_TYPE)
{
attachFileType = "bcfiles";
fileCategory = TaskFileCategoryEnum.BC.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bcmodifyfiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bccancelfiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "draftfiles";
fileCategory = TaskFileCategoryEnum.DRAFT.ToString();
}
else if (TaskBaseTypeEnum.SI_FEEDBACK.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "sisubmittedfiles";
fileCategory = TaskFileCategoryEnum.SI_SUBMITTED.ToString();
}
else if (TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "advisoryfiles";
fileCategory = TaskFileCategoryEnum.ADVISORY.ToString();
}
var noExtensionFileName = Path.GetFileNameWithoutExtension(file.FileName);
var relativePath = await SaveFile(taskInfo.Id.ToString(),
bytes,
batchNo,
noExtensionFileName,
GetFileType(file.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(relativePath))
{
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 = relativePath,
FileCategory = fileCategory
});
}
}
}
if (!string.IsNullOrWhiteSpace(info.Main.ModifyFile))
{
string fileCategory = string.Empty;
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_TYPE)
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_TYPE)
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_TYPE)
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_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_TYPE)
{
attachFileType = "bcnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bcmodifynoticefiles";
fileCategory = TaskFileCategoryEnum.BC_MODIFY_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.CANCELLATION.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "bccancelnoticefiles";
fileCategory = TaskFileCategoryEnum.BC_CANCEL_NOTICE.ToString();
}
else if (TaskBaseTypeEnum.DRAFT.ToString() == taskInfo.TASK_TYPE)
{
attachFileType = "draftnoticefiles";
fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString();
}
var noExtensionFileName = Path.GetFileNameWithoutExtension(modifyFile.FileName);
var relativePath = await SaveFile(taskInfo.Id.ToString(),
bytes,
batchNo,
noExtensionFileName,
GetFileType(modifyFile.FileName),
attachFileType);
if (!string.IsNullOrWhiteSpace(relativePath))
{
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 = relativePath,
FileCategory = fileCategory
});
}
}
}
#region 附件
//附件
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
{
var fileList = info.Main.FileList.Select(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_TYPE)
{
fileInfo.FILE_CATEGORY = TaskFileCategoryEnum.BC.ToString();
fileInfo.FILE_CATEGORY_NAME = TaskFileCategoryEnum.BC.EnumDescription();
}
else if (TaskBaseTypeEnum.BC_MODIFY.ToString() == taskInfo.TASK_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(".", "");
}
return fileInfo;
}).ToList();
await tenantDb.Insertable(fileList).ExecuteCommandAsync();
}
#endregion
#region 邮件
//邮件
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
{
var emailList = info.Main.EmailList.Select(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;
return emailInfo;
}).ToList();
await tenantDb.Insertable(emailList).ExecuteCommandAsync();
}
#endregion
#region SI反馈入库
//SI反馈入库
if (info.Main.TaskType == TaskBaseTypeEnum.SI_FEEDBACK)
{
if (info.Main.SIFeedBack == null)
throw new Exception($"任务类型={taskTypeStr} 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>(taskSISubmitted).ExecuteReturnEntityAsync();
//SI反馈箱信息入库
if (info.Main.SIFeedBack.ContaList != null && info.Main.SIFeedBack.ContaList.Count > 0)
{
var codeCtnCache = (await codeCtnService.GetAllList())?.Data ?? new List<Code.Dtos.CodeCtnRes>();
var list = info.Main.SIFeedBack.ContaList.Select(ctn =>
{
var contaInfo = ctn.Adapt<TaskSiSubmittedCtn>();
contaInfo.P_PKID = taskSISubmitted.Id;
if (string.IsNullOrWhiteSpace(contaInfo.CTNCODE) && !string.IsNullOrWhiteSpace(contaInfo.CTNALL))
{
if (codeCtnCache != null && codeCtnCache.Count > 0)
{
var ctnCodeInfo = codeCtnCache.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.CtnName)
&& x.CtnName.Equals(contaInfo.CTNALL, StringComparison.OrdinalIgnoreCase));
if (ctnCodeInfo != null)
{
contaInfo.CTNCODE = ctnCodeInfo.EdiCode;
}
}
}
return contaInfo;
}).ToList();
await tenantDb.Insertable<TaskSiSubmittedCtn>(list).ExecuteCommandAsync();
}
// 执行自动化操作
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.TaskBCId, taskInfo.Id)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType, taskInfo.Id, dataContext);
}
#endregion
#region 费用明细
//费用明细
if (info.Main.TaskType == TaskBaseTypeEnum.INVOICE_BILL_MAIL)
{
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
{
var list = info.Main.FeeList.Select(fee =>
{
var feeInfo = fee.Adapt<TaskBillFeeDetail>();
feeInfo.TASK_PKID = taskInfo.Id;
feeInfo.CreateTime = taskInfo.CreateTime;
feeInfo.CreateBy = taskInfo.CreateBy;
return feeInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
}
#endregion
#region 单票账单
if (info.Main.TaskType == TaskBaseTypeEnum.PER_BILL)
{
TaskPerBillBase taskPerBillBaseInfo = info.Main.PerBillInfo.Adapt<TaskPerBillBase>();
//写入
await tenantDb.Insertable(taskPerBillBaseInfo).ExecuteCommandAsync();
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
{
var list = info.Main.FeeList.Select(fee =>
{
var feeInfo = fee.Adapt<TaskBillFeeDetail>();
feeInfo.TASK_PKID = taskInfo.Id;
feeInfo.CreateTime = taskInfo.CreateTime;
feeInfo.CreateBy = taskInfo.CreateBy;
return feeInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
}
#endregion
#region 派车任务
if (info.Main.TaskType == TaskBaseTypeEnum.TRUCK_DISPATCH)
{
//派车任务
if (info.Main.TruckInfo == null)
{
throw new Exception($"派车任务主信息不能为空,请查看请求报文");
}
var truckInfo = info.Main.TruckInfo.Adapt<TaskTruck>();
truckInfo.TASK_ID = taskInfo.Id;
truckInfo.BookingTruckId = info.Main.TruckInfo.Id;
truckInfo.CreateTime = taskInfo.CreateTime;
truckInfo.CreateBy = taskInfo.CreateBy;
truckInfo.Status = BookingTruckStatus.TEMP.ToString();
//异步写入
await tenantDb.Insertable(truckInfo).ExecuteCommandAsync();
if (info.Main.TruckInfo.ContaList != null && info.Main.TruckInfo.ContaList.Count > 0)
{
var contaList = info.Main.TruckInfo.ContaList.Adapt<List<TaskTruckCtn>>();
var list = contaList.Select(x =>
{
x.P_ID = taskInfo.Id;
x.CreateTime = taskInfo.CreateTime;
x.CreateBy = taskInfo.CreateBy;
return x;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
}
#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;
bcInfo.BATCH_NO = info.Main.TaskBatchNo;
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 ctnCodeList = (await codeCtnService.GetAllList()).Data ?? new List<Code.Dtos.CodeCtnRes>();
var ctnList = info.Main.BCInfo.CtnList.Select(ctn =>
{
var bcCtnInfo = ctn.Adapt<TaskBCCTNInfo>();
bcCtnInfo.Id = SnowFlakeSingle.Instance.NextId();
bcCtnInfo.P_ID = bcInfo.Id;
if (string.IsNullOrEmpty(bcCtnInfo.CTNCODE))
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.CtnName) && a.CtnName.Equals(bcCtnInfo.CTNALL, StringComparison.OrdinalIgnoreCase));
bcCtnInfo.CTNCODE = ctnCode != null ? ctnCode.EdiCode : "";
}
bcCtnInfo.CreateBy = taskInfo.CreateBy;
bcCtnInfo.CreateTime = taskInfo.CreateTime;
return bcCtnInfo;
}).ToList();
await tenantDb.Insertable(ctnList).ExecuteCommandAsync();
/*
BC_MODIFY
1、检索对应舱位提取比对差异结果
2、检索舱位对应的订舱信息如果有则生成用户通知邮件
3、推送钉钉消息@操作人 通知收到变更
CANCELLATION
1、检索舱位对应的订舱信息如果有则生成用户通知邮件
2、推送钉钉消息@操作人 通知收到变更
*/
// 执行自动化操作
var bcFileInfo =
file == null ? null : new DynameFileInfo
{
FileBytes = file.ToByteArray(),
FileName = file.FileName
};
var bcNoticeFileInfo =
modifyFile == null ? null : new DynameFileInfo
{
FileBytes = modifyFile.ToByteArray(),
FileName = modifyFile.FileName
};
TaskFlowDataContext dataContext = new(
// 固定
(TaskFlowDataNameConst.TaskBaseInfo, taskInfo),
// 邮件接收任务特有
(TaskFlowDataNameConst.TaskManageOrderMessageInfo, info),
// BC任务特有
(TaskFlowDataNameConst.BCFileInfo, bcFileInfo),
(TaskFlowDataNameConst.BCNotifyFileInfo, bcNoticeFileInfo),
(TaskFlowDataNameConst.TaskBCInfo, bcInfo),
(TaskFlowDataNameConst.TaskBCCtnList, ctnList)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType, taskInfo.Id, dataContext);
}
#endregion
#region 截止时间变更通知
if (info.Main.TaskType == TaskBaseTypeEnum.CUT_MODIFY)
{
var cutInfo = info.Main.CutDateChange.Adapt<TaskCutDateChangeInfo>();
cutInfo.TASK_ID = taskInfo.Id;
cutInfo.CreateTime = taskInfo.CreateTime;
cutInfo.CreateBy = taskInfo.CreateBy;
await tenantDb.Insertable(cutInfo).ExecuteCommandAsync();
if (info.Main.CutDateChange.Details != null && info.Main.CutDateChange.Details.Count > 0)
{
//异步写入明细
var list = info.Main.CutDateChange.Details.Select(detail =>
{
var cutDetail = detail.Adapt<TaskCutDateChangeDetailInfo>();
cutDetail.P_ID = cutInfo.Id;
cutDetail.CreateTime = taskInfo.CreateTime;
cutDetail.CreateBy = taskInfo.CreateBy;
return cutDetail;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
////触发推送消息
//var name = _namedTaskManageCutDateChangeServiceProvider
// .GetService<ITransient>(nameof(TaskManageCutDateChangeService));
//await name.AutoTransferNotice(taskInfo.PK_ID);
}
#endregion
#region VGM回执或VGM未提交提醒
if (info.Main.TaskType == TaskBaseTypeEnum.VGM_FEEDBACK
|| info.Main.TaskType == TaskBaseTypeEnum.VGM_MISSING)
{
List<TaskVgmInfo> vgmList = new List<TaskVgmInfo>();
foreach (var p in info.Main.VGMFeedBack)
{
//异步写入
var vgmInfo = p.Adapt<TaskVgmInfo>();
vgmInfo.TASK_ID = taskInfo.Id;
vgmInfo.CreateTime = taskInfo.CreateTime;
vgmInfo.CreateBy = taskInfo.CreateBy;
vgmInfo.TASK_TYPE = taskTypeStr;
await tenantDb.Insertable(vgmInfo).ExecuteCommandAsync();
vgmList.Add(vgmInfo);
var ctnList = p.CtnList.Select(ctn =>
{
var vgmCtnInfo = ctn.Adapt<TaskVgmCtnInfo>();
vgmCtnInfo.P_ID = vgmInfo.Id;
vgmCtnInfo.CreateTime = taskInfo.CreateTime;
vgmCtnInfo.CreateBy = taskInfo.CreateBy;
return vgmCtnInfo;
}).ToList();
await tenantDb.Insertable(ctnList).ExecuteCommandAsync();
}
//var mblNoList = info.Main.VGMFeedBack.Select(p => p.MBlNo).Distinct().ToList();
/* 1、入库完检索对应的订舱信息。
2、推送订舱相关的状态。
//var bookingList = _bookingOrderRepository.AsQueryable().Filter(null, true)
// .Where(x => mblNoList.Contains(x.MBLNO) && (x.ParentId == 0 || x.ParentId == null)
// && x.IsDeleted == false && x.TenantId == taskInfo.TenantId).ToList();
//if (bookingList.Count > 0)
//{
// vgmList.ForEach(vgmInfo =>
// {
// var bookingInfo = bookingList.FirstOrDefault(a =>
// a.MBLNO.Equals(vgmInfo.MBL_NO, StringComparison.OrdinalIgnoreCase));
// if (bookingInfo != null)
// {
// var vgmEntity = _taskVGMInfoRepository.AsQueryable().Filter(null, true)
// .First(x => x.PK_ID == vgmInfo.PK_ID && x.IsDeleted == false && x.TenantId == taskInfo.TenantId);
// vgmEntity.BOOKING_ID = bookingInfo.Id;
// _taskVGMInfoRepository.AsUpdateable(vgmEntity).UpdateColumns(x => x.BOOKING_ID).ExecuteCommandAsync();
// var ctnVGMList = _bookingCtnVGMRepository.AsQueryable().Filter(null, true)
// .Where(x => x.BILLID == bookingInfo.Id && x.IsDeleted == false && x.TenantId == taskInfo.TenantId).ToList();
// var bookCtnList = _bookingOrderContaRepository.AsQueryable().Filter(null, true)
// .Where(x => x.BILLID == bookingInfo.Id && x.IsDeleted == false && x.TenantId == taskInfo.TenantId).ToList();
// var ctnList = info.Main.VGMFeedBack
// .FirstOrDefault(x => x.MBlNo.Equals(vgmInfo.MBL_NO, StringComparison.OrdinalIgnoreCase)).CtnList;
// if (info.Main.TaskType == TaskBaseTypeEnum.VGM_FEEDBACK)
// {
// //推送状态
// var pushModel = new ModifyServiceProjectStatusDto
// {
// BookingId = bookingInfo.Id,
// SourceType = TrackingSourceTypeEnum.AUTO,
// StatusCodes = new List<ModifyServiceProjectStatusDetailDto> {
// new ModifyServiceProjectStatusDetailDto { StatusCode = "VGMCG" } }
// };
// var saveStatusRlt = _bookingValueAddedService.SaveServiceStatus(pushModel).GetAwaiter().GetResult();
// _logger.LogInformation("请求JSON={json} 异步推送服务状态完成,结果={rlt}", JSON.Serialize(pushModel), JSON.Serialize(saveStatusRlt));
// foreach (var ctn in ctnList)
// {
// var bookCtnVGM = ctnVGMList.FirstOrDefault(t => t.CNTRNO.Equals(ctn.CntrNo, StringComparison.OrdinalIgnoreCase));
// var bookCtn = bookCtnList.FirstOrDefault(t => t.CNTRNO.Equals(ctn.CntrNo, StringComparison.OrdinalIgnoreCase));
// if (bookCtnVGM != null)
// {
// //更新
// bookCtnVGM.UpdatedTime = taskInfo.CreatedTime;
// bookCtnVGM.UpdatedUserId = taskInfo.CreatedUserId;
// bookCtnVGM.UpdatedUserName = taskInfo.CreatedUserName;
// bookCtnVGM.IS_MISSING = false;
// bookCtnVGM.SUBMISSION_DEADLINE = null;
// _bookingCtnVGMRepository.AsUpdateable(bookCtnVGM).UpdateColumns(x => new
// {
// x.VGM_WEIGHT,
// x.VGM_WEIGHT_UNIT,
// x.VGM_METHOD,
// x.IS_MATCH,
// x.UpdatedTime,
// x.UpdatedUserId,
// x.UpdatedUserName
// }).ExecuteCommand();
// }
// else
// {
// //写入
// var bookingCtnVGM = new BookingCtnVGM
// {
// CNTRNO = ctn.CntrNo,
// BILLID = bookingInfo.Id,
// VGM_WEIGHT = ctn.VGMWeight,
// VGM_WEIGHT_UNIT = ctn.VGMWeightUnit,
// VGM_METHOD = ctn.VGMWeightMethod,
// IS_MATCH = bookCtn != null,
// CreatedTime = taskInfo.CreatedTime,
// UpdatedTime = taskInfo.CreatedTime,
// CreatedUserId = taskInfo.CreatedUserId,
// CreatedUserName = taskInfo.CreatedUserName,
// TenantId = taskInfo.TenantId,
// REC_TIME = vgmInfo.NOTICE_DATE
// };
// _bookingCtnVGMRepository.Insert(bookingCtnVGM);
// }
// }
// }
// else
// {
// if (ctnList.Count > 0)
// {
// foreach (var ctn in ctnList)
// {
// var bookCtnVGM = ctnVGMList.FirstOrDefault(t => t.CNTRNO.Equals(ctn.CntrNo, StringComparison.OrdinalIgnoreCase));
// var bookCtn = bookCtnList.FirstOrDefault(t => t.CNTRNO.Equals(ctn.CntrNo, StringComparison.OrdinalIgnoreCase));
// if (bookCtnVGM == null)
// {
// //写入
// var bookingCtnVGM = new BookingCtnVGM
// {
// CNTRNO = ctn.CntrNo,
// BILLID = bookingInfo.Id,
// VGM_WEIGHT = ctn.VGMWeight,
// VGM_WEIGHT_UNIT = ctn.VGMWeightUnit,
// VGM_METHOD = ctn.VGMWeightMethod,
// IS_MATCH = bookCtn != null,
// CreatedTime = taskInfo.CreatedTime,
// UpdatedTime = taskInfo.CreatedTime,
// CreatedUserId = taskInfo.CreatedUserId,
// CreatedUserName = taskInfo.CreatedUserName,
// TenantId = taskInfo.TenantId,
// REC_TIME = vgmInfo.NOTICE_DATE,
// IS_MISSING = true,
// SUBMISSION_DEADLINE = vgmInfo.VGM_SUBMISSION_DEADLINE
// };
// _bookingCtnVGMRepository.Insert(bookingCtnVGM);
// }
// }
// }
// }
// }
// });
//}
////触发推送消息
//var name = _namedVGMServiceProvider
// .GetService<ITransient>(nameof(TaskManageVGMService));
//await name.SendVGMMissingNotice(taskInfo.PK_ID);
*/
}
#endregion
#region Rolling Nomination(预甩货通知)
if (info.Main.TaskType == TaskBaseTypeEnum.ROLLING_NOMINATION || info.Main.TaskType == TaskBaseTypeEnum.TRANSFER_NOMINATION)
{
var rollingNomination = info.Main.RollingNomination.Adapt<TaskRollingNomination>();
rollingNomination.TASK_ID = taskInfo.Id;
rollingNomination.CreateTime = taskInfo.CreateTime;
rollingNomination.CreateBy = taskInfo.CreateBy;
//这里把多条的预甩计划列表合并保存,展示时只需要用\n拆分返回给前端
if (info.Main.RollingNomination.RollingPlanList != null && info.Main.RollingNomination.RollingPlanList.Count > 0)
{
rollingNomination.PLAN_TXT = string.Join("\\n", info.Main.RollingNomination.RollingPlanList.ToArray());
}
await tenantDb.Insertable(rollingNomination).ExecuteCommandAsync();
if (info.Main.RollingNomination.From != null && info.Main.RollingNomination.From.Count > 0)
{
var list = info.Main.RollingNomination.From.Select(k =>
{
var rollingNominationShip = k.Adapt<TaskRollingNominationShip>();
rollingNominationShip.TASK_ID = taskInfo.Id;
rollingNominationShip.NOM_ID = rollingNomination.Id;
rollingNominationShip.CreateTime = taskInfo.CreateTime;
rollingNominationShip.CreateBy = taskInfo.CreateBy;
return rollingNominationShip;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
if (info.Main.RollingNomination.ToDetail != null && info.Main.RollingNomination.ToDetail.Count > 0)
{
var ctnCodeList = (await codeCtnService.GetAllList()).Data ?? new List<Code.Dtos.CodeCtnRes>();
foreach (var t in info.Main.RollingNomination.ToDetail)
{
var rollingNominationShip = t.Adapt<TaskRollingNominationShip>();
rollingNominationShip.TASK_ID = taskInfo.Id;
rollingNominationShip.NOM_ID = rollingNomination.Id;
rollingNominationShip.CreateTime = taskInfo.CreateTime;
await tenantDb.Insertable(rollingNominationShip).ExecuteCommandAsync();
if (t.NominationList != null && t.NominationList.Count > 0)
{
//这里直接批量检索订舱信息,如果有对应的提单号直接写入订舱主键
var billNoList = t.NominationList.Select(x => x.Shipment.ToUpper())
.Distinct().ToArray();
var bookList = await tenantDb.Queryable<SeaExport>().Where(x => billNoList.Contains(x.MBLNO)).ToListAsync();
foreach (var x in t.NominationList)
{
var rollingNominationDetail = x.Adapt<TaskRollingNominationDetail>();
if (!string.IsNullOrWhiteSpace(rollingNominationDetail.CTNALL))
{
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.CtnName) && a.CtnName.Equals(rollingNominationDetail.CTNALL, StringComparison.OrdinalIgnoreCase));
rollingNominationDetail.CTNCODE = ctnCode != null ? ctnCode.EdiCode : "(箱型未收录)";
}
rollingNominationDetail.NOM_SHIP_ID = rollingNominationShip.Id;
rollingNominationDetail.NOM_ID = rollingNomination.Id;
rollingNominationDetail.CreateTime = taskInfo.CreateTime;
var bookingInfo = bookList.FirstOrDefault(x =>
x.MBLNO.Equals(rollingNominationDetail.SHIPMENT, StringComparison.OrdinalIgnoreCase));
if (bookingInfo != null)
{
rollingNominationDetail.BOOKING_ID = bookingInfo.Id;
rollingNominationDetail.CUSTOMERID = bookingInfo.CustomerId;
rollingNominationDetail.CUSTOMERNAME = bookingInfo.CustomerName;
}
await tenantDb.Insertable(rollingNominationDetail).ExecuteCommandAsync();
};
}
}
}
//异步生成调度
//var rollNominationService = _namedRollingNominationServiceProvider
// .GetService<ITransient>(nameof(TaskManageRollingNominationService));
//var dispatchRlt = await rollNominationService.DispatchRollingNomination(new RollingNominationDispatchRequestDto
//{
// isAdd = true,
// nominationId = rollingNomination.PK_ID
//});
}
#endregion
#region DRAFT转发客户
if (info.Main.TaskType == TaskBaseTypeEnum.DRAFT)
{
TaskDraftInfo taskDraftInfo = info.Main.DraftInfo.Adapt<TaskDraftInfo>();
taskDraftInfo.TASK_ID = taskInfo.Id;
taskDraftInfo.CreateTime = taskInfo.CreateTime;
await tenantDb.Insertable(taskDraftInfo).ExecuteCommandAsync();
}
#endregion
#region 任务目的港未提货/任务目的港提货未返空
if (info.Main.TaskType == TaskBaseTypeEnum.POD_DISCHARGE_FULL || info.Main.TaskType == TaskBaseTypeEnum.POD_GATEOUT_FULL)
{
TaskPodDischargeGateoutFull dischargeGateout = info.Main.PODDischargeGateoutFull.Adapt<TaskPodDischargeGateoutFull>();
dischargeGateout.TASK_ID = taskInfo.Id;
dischargeGateout.CreateTime = taskInfo.CreateTime;
await tenantDb.Insertable(dischargeGateout).ExecuteCommandAsync();
//明细入库
if (info.Main.PODDischargeGateoutFull.DetailList != null
&& info.Main.PODDischargeGateoutFull.DetailList.Count > 0)
{
var list = info.Main.PODDischargeGateoutFull.DetailList.Select(ctn =>
{
var detailInfo = ctn.Adapt<TaskPodDischargeGateoutFullDetail>();
detailInfo.P_ID = dischargeGateout.Id;
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
////触发推送消息
//var name = _namedPODDischargeGateoutFullProvider
// .GetService<ITransient>(nameof(TaskManagePODDischargeGateoutFullService));
//await name.AutoTransferNotice(taskInfo.PK_ID);
}
#endregion
#region 重要提醒
if (info.Main.TaskType == TaskBaseTypeEnum.CAUTION_NOTICE)
{
TaskCautionNotice taskCautionNoticeInfo = info.Main.CautionNoticeInfo.Adapt<TaskCautionNotice>();
taskCautionNoticeInfo.TASK_ID = taskInfo.Id;
taskCautionNoticeInfo.CreateTime = taskInfo.CreateTime;
taskCautionNoticeInfo.CAUTION_NOTICE_TYPE = info.Main.CautionNoticeInfo.CautionNoticeType.ToString();
await tenantDb.Insertable(taskCautionNoticeInfo).ExecuteCommandAsync();
var list = info.Main.CautionNoticeInfo.NoticeList.Select(notice =>
{
var noticeInfo = notice.Adapt<TaskCautionNoticeDetail>();
noticeInfo.NOTIFY_METHOD = notice.CautionNoticeType.ToString();
noticeInfo.P_ID = taskCautionNoticeInfo.Id;
noticeInfo.CreateTime = taskInfo.CreateTime;
noticeInfo.STATUS = TaskCautionNoticeStatusEnum.TEMP.ToString();
noticeInfo.STATUS_NAME = TaskCautionNoticeStatusEnum.TEMP.EnumDescription();
return noticeInfo;
}).ToList();
//异步写入集装箱
await tenantDb.Insertable(list).ExecuteCommandAsync();
////这里加了个判断如果没有标记自动发送消息就不触发转发功能
//if (info.Main.CautionNoticeInfo.IsAutoSendNotice == true)
//{
// //触发推送消息
// var name = _namedTaskCautionNoticeServiceProvider
// .GetService<ITransient>(nameof(TaskCautionNoticeService));
// await name.TriggerSendNotice(taskInfo.PK_ID, taskInfo.TenantId.Value);
//}
}
#endregion
#region 航线船舶截止时间调整的通知
if (info.Main.TaskType == TaskBaseTypeEnum.ROUTE_CUT_CHANGE)
{
TaskRouteChangeAdvisory taskRouteChangeAdvisoryInfo = info.Main.RouteChangeAdvisoryInfo.Adapt<TaskRouteChangeAdvisory>();
taskRouteChangeAdvisoryInfo.TASK_ID = taskInfo.Id;
taskRouteChangeAdvisoryInfo.CreateTime = taskInfo.CreateTime;
List<CodePortRes> portCodeList = new List<CodePortRes>();
if (!string.IsNullOrWhiteSpace(taskRouteChangeAdvisoryInfo.READ_PORTLOAD))
{
var portList = (await codePortService.GetAllList()).Data ?? new List<Code.Dtos.CodePortRes>();
var allPortCodeList = await codePortService.GetAllList();
if (allPortCodeList.Succeeded)
{
portCodeList = allPortCodeList.Data;
}
var portInfo = await PlaceReceiptToPortload(taskRouteChangeAdvisoryInfo.READ_PORTLOAD, portCodeList, () => mappingPortService.GetAllList());
if (!portInfo.Succeeded || portInfo.Data == null)
{
logger.LogInformation($"通过收货地城市名称未匹配到港口信息航线船舶截止时间调整的通知Id{taskRouteChangeAdvisoryInfo.Id}");
}
else
{
taskRouteChangeAdvisoryInfo.PORTLOADID = portInfo.Data.EdiCode;
taskRouteChangeAdvisoryInfo.PORTLOAD = portInfo.Data.PortName;
}
}
await tenantDb.Insertable(taskRouteChangeAdvisoryInfo).ExecuteCommandAsync();
////触发推送消息
//var name = _namedRouteChangeAdvisoryServiceServiceProvider
// .GetService<ITransient>(nameof(RouteChangeAdvisoryService));
//await name.AutoTransferNotice(taskInfo.PK_ID);
}
#endregion
#region 货物运输计划已变更
if (info.Main.TaskType == TaskBaseTypeEnum.TRNAS_PLAN_HAS_CHANGE)
{
TaskTransPlanHasChange taskTransPlanHasChangeInfo = info.Main.TransportPlanHasChangeInfo.Adapt<TaskTransPlanHasChange>();
taskTransPlanHasChangeInfo.TASK_ID = taskInfo.Id;
taskTransPlanHasChangeInfo.CreateTime = taskInfo.CreateTime;
await tenantDb.Insertable(taskTransPlanHasChangeInfo).ExecuteCommandAsync();
if (info.Main.TransportPlanHasChangeInfo.From != null)
{
if (info.Main.TransportPlanHasChangeInfo.From.portList != null
&& info.Main.TransportPlanHasChangeInfo.From.portList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.From.portList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
PORTLOAD = p.PortName,
PORTLOAD_COUNTRY = p.CountryCode,
PORTLOAD_TERMINAL = p.TerminalName,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "FROM";
detailInfo.COLUMN_TYPE = "PORT";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
if (info.Main.TransportPlanHasChangeInfo.From.dateList != null
&& info.Main.TransportPlanHasChangeInfo.From.dateList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.From.dateList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
ETD = p.DateVal,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "FROM";
detailInfo.COLUMN_TYPE = "EATD";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
if (info.Main.TransportPlanHasChangeInfo.From.vesselList != null
&& info.Main.TransportPlanHasChangeInfo.From.vesselList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.From.vesselList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
VESSEL = p.Vessel,
VOYNO = p.Voyno,
SHIP_FLAG = p.Flag,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "FROM";
detailInfo.COLUMN_TYPE = "VESSEL";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
}
if (info.Main.TransportPlanHasChangeInfo.To != null)
{
if (info.Main.TransportPlanHasChangeInfo.To.portList != null
&& info.Main.TransportPlanHasChangeInfo.To.portList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.To.portList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
PORTDISCHARGE = p.PortName,
PORTDISCHARGE_COUNTRY = p.CountryCode,
PORTDISCHARGE_TERMINAL = p.TerminalName,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "TO";
detailInfo.COLUMN_TYPE = "PORT";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
if (info.Main.TransportPlanHasChangeInfo.To.dateList != null
&& info.Main.TransportPlanHasChangeInfo.To.dateList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.To.dateList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
ETA = p.DateVal,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "TO";
detailInfo.COLUMN_TYPE = "EATD";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
if (info.Main.TransportPlanHasChangeInfo.To.vesselList != null
&& info.Main.TransportPlanHasChangeInfo.To.vesselList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.To.vesselList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
VESSEL = p.Vessel,
VOYNO = p.Voyno,
SHIP_FLAG = p.Flag,
SORT_NO = p.Indx,
IS_REMOVED = p.IsRemoved
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.PLAN_TYPE = "TO";
detailInfo.COLUMN_TYPE = "VESSEL";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
}
if (info.Main.TransportPlanHasChangeInfo.ContaNoList != null && info.Main.TransportPlanHasChangeInfo.ContaNoList.Count > 0)
{
var list = info.Main.TransportPlanHasChangeInfo.ContaNoList.Select(p =>
{
TaskTransPlanHasChangeDetail detailInfo = new TaskTransPlanHasChangeDetail
{
CONTA_NO = p,
};
detailInfo.P_ID = taskTransPlanHasChangeInfo.Id;
detailInfo.COLUMN_TYPE = "CTN";
detailInfo.CreateTime = taskInfo.CreateTime;
return detailInfo;
}).ToList();
await tenantDb.Insertable(list).ExecuteCommandAsync();
}
////触发推送消息
//var name = _namedTaskTransPlanHasChangeServiceProvider
// .GetService<ITransient>(nameof(TaskTransPlanHasChangeService));
//await name.AutoTransferNotice(taskInfo.PK_ID);
}
#endregion
#region 装货港未提箱通知
if (info.Main.TaskType == TaskBaseTypeEnum.POL_CTN_NOT_PICKUP)
{
TaskPolContainerNotPickup taskPOLContainerNotPickUpInfo = info.Main.POLContainerNotPickupInfo.Adapt<TaskPolContainerNotPickup>();
taskPOLContainerNotPickUpInfo.TASK_ID = taskInfo.Id;
taskPOLContainerNotPickUpInfo.CreateTime = taskInfo.CreateTime;
await tenantDb.Insertable(taskPOLContainerNotPickUpInfo).ExecuteCommandAsync();
//出发任务流程
TaskFlowDataContext dataContext = new(
// 固定
(TaskFlowDataNameConst.TaskPKId, taskInfo.Id)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType, taskInfo.Id, dataContext);
}
#endregion
#region 黑名单
#endregion
#region 截单补料异常提醒
#endregion
#region 启运港箱使费通知
#endregion
//回写任务号
var result = new DataResult(ResultCode.Success, "新增任务成功", data: taskInfo.TASK_NO);
return await Task.FromResult(result);
}
catch (Exception ex)
{
logger.LogError(ex, "任务台:初始化任务的过程中发生未知异常,批次号={no}", batchNo);
return DataResult.Failed(ex.Message);
}
//finally
//{
// Monitor.Exit(ImportLockObj);
//}
}
/// <summary>
/// 任务台台账列表查询
/// </summary>
public async Task<DataResult<List<dynamic>>> GetPageAsync(PageRequest<QueryTaskManageDto> querySearch)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear();
if (querySearch.OtherQueryCondition == null)
{
throw new ArgumentNullException(nameof(querySearch.OtherQueryCondition));
}
//序列化查询条件
List<IConditionalModel>? whereList = null;
if (!string.IsNullOrEmpty(querySearch.QueryCondition))
{
whereList = tenantDb.Utilities.JsonToConditionalModels(querySearch.QueryCondition);
if (whereList != null)
{
foreach (var item in whereList)
{
if (item is ConditionalModel model)
{
string lowerFieldName = model.FieldName.ToLower();
if (seaExportFields.Contains(lowerFieldName))
{
model.FieldName = "s." + model.FieldName;
}
else
{
model.FieldName = "t." + model.FieldName;
}
}
}
}
}
// 格式化参数
TaskBaseTypeEnum? taskType = null;
if (Enum.TryParse(typeof(TaskBaseTypeEnum), querySearch.OtherQueryCondition.TaskType, out object? temp))
{
taskType = (TaskBaseTypeEnum)temp;
};
TaskStatLevelEnum? taskStatLevel = null;
//TaskStatLevelEnum? taskStatLevel = TaskStatLevelEnum.PUBLIC;
if (Enum.TryParse(typeof(TaskStatLevelEnum), querySearch.OtherQueryCondition.TaskCategory, out object? tempStat))
{
taskStatLevel = (TaskStatLevelEnum)tempStat;
}
else
{
//throw new ArgumentException("TaskCategory");
}
var userId = long.Parse(user.UserId);
DataResult<List<dynamic>> result = new();
try
{
switch (taskType)
{
case TaskBaseTypeEnum.BC:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>()
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskBCInfo>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
// POL、POD关联查询
queryable.WhereIF(!string.IsNullOrEmpty(querySearch.OtherQueryCondition.PortLoadCode), (t, a, bc, s) => querySearch.OtherQueryCondition.PortLoadCode == bc.PORTLOAD_CODE || querySearch.OtherQueryCondition.PortLoadCode == bc.PORTLOAD_CODE);
queryable.WhereIF(!string.IsNullOrEmpty(querySearch.OtherQueryCondition.PortDischargeCode), (t, a, bc, s) => querySearch.OtherQueryCondition.PortDischargeCode == bc.PORTDISCHARGE_CODE || querySearch.OtherQueryCondition.PortDischargeCode == bc.PORTDISCHARGE_CODE);
var queryableTemp = queryable.Select<dynamic>((t, a, bc, s) => new
{
Id = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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
}).Distinct();
#if DEBUG
var sql = queryableTemp.ToSqlString();
#endif
result = await queryableTemp.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.SI_FEEDBACK:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskSiSubmitted>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
var queryableTemp = queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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
}).Distinct();
result = await queryableTemp.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.INVOICE_BILL_MAIL:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskPerBillBase>((t, a, bc) => t.Id == bc.TASK_PKID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
var queryableTemp = queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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
}).Distinct();
result = await queryableTemp.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.TRUCK_DISPATCH:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskTruck>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
var queryableTemp = queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
//s.CntrTotal,
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
}).Distinct();
result = await queryableTemp.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.CUT_MODIFY:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskCutDateChangeInfo>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
bc.TASK_ID,
bc.CARRIER,
bc.VESSEL,
bc.VOYNO,
bc.NOTICE_DATE
})
.Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.ROLLING_NOMINATION:
case TaskBaseTypeEnum.TRANSFER_NOMINATION:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskRollingNomination>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.DRAFT:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskDraftInfo>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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,
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.POD_DISCHARGE_FULL:
case TaskBaseTypeEnum.POD_GATEOUT_FULL:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskPodDischargeGateoutFull>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
bc.TASK_ID,
bc.CARRIER,
bc.NOTICE_TYPE,
bc.NOTICE_TYPE_NAME,
//bc.MBL_NO,
bc.NOTICE_DATE
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.CAUTION_NOTICE:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskCautionNotice>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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,
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.ROUTE_CUT_CHANGE:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<TaskRouteChangeAdvisory>((t, a, bc) => t.Id == bc.TASK_ID && bc.Deleted == false)
.LeftJoin<SeaExport>((t, a, bc, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
result = await queryable.Select<dynamic>((t, a, bc, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
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
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
default:
{
var queryable = tenantDb.Queryable<TaskBaseInfo>()
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<SeaExport>((t, a, s) => t.OUT_BS_NO == s.Id);
await SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, user);
ISugarQueryable<dynamic> queryableTemp = queryable.Select<dynamic>((t, a, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
}).Distinct();
#if DEBUG
var sql = queryableTemp.ToSqlString();
#endif
result = await queryableTemp.ToQueryPageAsync(querySearch.PageCondition);
return result;
}
}
}
finally
{
if (result.Data?.Count > 0)
{
// 查询任务接收人列表
var taskIdList = result.Data.Select(x => (long)x.Id).ToList();
var allRecvUserList = await tenantDb.Queryable<TaskBaseAllocation>()
.Where(x => taskIdList.Contains(x.TaskId))
.Select(x => new RecvUserInfo()
{
TaskId = x.TaskId,
RecvUserId = x.UserId,
RecvUserName = x.UserName,
RecvUserStatus = x.Status,
RecvUserStatusName = x.StatusName,
RecvUserStatusTime = x.StatusTime
}).ToListAsync();
// 一些特殊处理
foreach (var item in result.Data)
{
// 1.任务接收人赋值
if (allRecvUserList.Count > 0)
{
var recvUserList = allRecvUserList.Where(x => x.TaskId == item.Id).ToList();
var currentUserStatus = recvUserList.FirstOrDefault(x => x.RecvUserId == userId);
if (currentUserStatus != null)
{
var n = recvUserList.IndexOf(currentUserStatus);
if (n != 0)
{
recvUserList.RemoveAt(n);
recvUserList.Insert(0, currentUserStatus);
}
item.TASK_USER_STATUS = currentUserStatus.RecvUserStatus;
item.TASK_USER_STATUS_NAME = currentUserStatus.RecvUserStatusName;
item.TASK_USER_STATUS_TIME = currentUserStatus.RecvUserStatusTime;
}
item.RecvUserList = recvUserList;
}
// 2.部分字段值覆盖提单号、ETD、船公司、委托编号如果订单的号码不为空则采用订单的号码
if (!string.IsNullOrEmpty(item.orderMBLNO))
{
item.MBL_NO = item.orderMBLNO;
}
if (item.orderETD != null)
{
item.ETD = item.orderETD;
}
if (!string.IsNullOrEmpty(item.orderCarrier))
{
item.CARRIER_CODE = item.orderCarrier;
item.CARRIER_ID = item.orderCarrierId;
item.CARRIER_NAME = null;
}
if (!string.IsNullOrEmpty(item.CustomerNo))
{
item.CUSTOMER_NO = item.CustomerNo;
}
// 3.ExtData字段从Data转为对象
if (!string.IsNullOrEmpty(item.ExtData))
{
try
{
item.ExtData = JObject.Parse(item.ExtData);
}
catch
{
item.ExtData = new { ParseError = true, ParseMessage = "ExtData为非标准Json导致解析异常" };
}
}
}
}
}
}
/// <summary>
/// 设置条件的方法,用于<see cref="GetPageAsync(PageRequest{QueryTaskManageDto})"/>
/// </summary>
private async Task SetCondition<T>(ISugarQueryable<TaskBaseInfo, TaskBaseAllocation, T, SeaExport> queryable,
List<IConditionalModel>? whereList,
TaskBaseTypeEnum? taskType,
TaskStatLevelEnum? taskStatLevel,
QueryTaskManageDto queryDto,
IUser user)
{
var userId = long.Parse(user.UserId);
queryable.ClearFilter(typeof(IOrgId));
var taskTypeStr = taskType.ToString();
var taskStatusStr = TaskStatusEnum.Cancel.ToString();
List<long>? orderParentIdList = null;
if (!string.IsNullOrEmpty(queryDto.BusinessNo))
{
orderParentIdList = (await queryable.Context.Queryable<SeaExport>()
.ClearFilter(typeof(IOrgId))
.Where(x => x.ParentId != 0 && x.HBLNO.Contains(queryDto.BusinessNo))
.Select(x => x.ParentId)
.ToListAsync())
.Distinct().ToList(); ;
}
var isHasOrderParentIdList = orderParentIdList != null;
queryable.Where(whereList)
.Where((t, a) => t.STATUS != taskStatusStr && t.Deleted == false)
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskTypeStr)
.WhereIF(!string.IsNullOrEmpty(queryDto.BusinessNo), (t, a, bc, s) => ((!string.IsNullOrEmpty(s.MBLNO) && s.MBLNO.Contains(queryDto.BusinessNo)) || (string.IsNullOrEmpty(s.MBLNO) && t.MBL_NO.Contains(queryDto.BusinessNo))) // 如果订单提单号不为空使用订单提单号查询,否则使用任务上的提单号查询
|| s.CustomerNo.Contains(queryDto.BusinessNo)
|| s.BookingNo.Contains(queryDto.BusinessNo)
|| s.CustomerNum.Contains(queryDto.BusinessNo)
|| t.TASK_NO.Contains(queryDto.BusinessNo)
|| (isHasOrderParentIdList == true && orderParentIdList!.Contains(s.Id)))
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == queryDto.Status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (a.UserId == userId) // 2024-8-14 只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == queryDto.Status);
if (taskStatLevel == TaskStatLevelEnum.UNDERLING)
{
if (queryDto.UnderlingTaskScope is null or "none")
{
queryable.Where((t, a) => true == false);
}
else if (queryDto.UnderlingTaskScope == "self_org")
{
queryable.Where((t, a) => a.OrgId == user.OrgId);
}
else if (queryDto.UnderlingTaskScope == "self_org_with_child")
{
var db = serviceProvider.GetRequiredService<ISqlSugarClient>();
List<SysOrg> orgList = await db.Queryable<SysOrg>().ToChildListAsync(s => s.ParentId, user.OrgId);
IEnumerable<long> orgIdList = orgList.Select(x => x.Id);
queryable.Where((t, a) => orgIdList.Contains(a.OrgId));
}
else if (queryDto.UnderlingTaskScope == "self")
{
queryable.Where((t, a) => a.CreateBy == userId);
}
else if (queryDto.UnderlingTaskScope == "self_dept")
{
var db = serviceProvider.GetRequiredService<ISqlSugarClient>();
var deptUsers = db.Queryable<SysUser>().Where(x => x.DeptId != 0 && x.DeptId == SqlFunc.Subqueryable<SysUser>().Where(s => s.Id == userId).Select(s => s.DeptId)).Select(x => x.Id).ToList();
queryable.Where((t, a) => deptUsers.Contains(a.UserId));
}
}
queryable.OrderByDescending(t => t.Id);
}
/// <summary>
/// 设置条件的方法,用于<see cref="GetPageAsync(PageRequest{QueryTaskManageDto})"/>
/// </summary>
private async Task SetCondition(ISugarQueryable<TaskBaseInfo, TaskBaseAllocation, SeaExport> queryable,
List<IConditionalModel>? whereList,
TaskBaseTypeEnum? taskType,
TaskStatLevelEnum? taskStatLevel,
QueryTaskManageDto queryDto,
IUser user)
{
var userId = long.Parse(user.UserId);
queryable.ClearFilter(typeof(IOrgId));
List<long>? orderParentIdList = null;
var taskTypeStr = taskType.ToString();
var taskStatusStr = TaskStatusEnum.Cancel.ToString();
if (!string.IsNullOrEmpty(queryDto.BusinessNo))
{
orderParentIdList = (await queryable.Context.Queryable<SeaExport>()
.ClearFilter(typeof(IOrgId))
.Where(x => x.ParentId != 0 && x.HBLNO.Contains(queryDto.BusinessNo))
.Select(x => x.ParentId)
.ToListAsync())
.Distinct().ToList();
}
var isHasOrderParentIdList = orderParentIdList != null;
queryable.Where(whereList)
.Where((t, a) => t.STATUS != taskStatusStr && t.Deleted == false)
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskTypeStr)
.WhereIF(!string.IsNullOrEmpty(queryDto.BusinessNo), (t, a, s) => ((!string.IsNullOrEmpty(s.MBLNO) && s.MBLNO.Contains(queryDto.BusinessNo)) || (string.IsNullOrEmpty(s.MBLNO) && t.MBL_NO.Contains(queryDto.BusinessNo))) // 如果订单提单号不为空使用订单提单号查询,否则使用任务上的提单号查询
|| s.CustomerNo.Contains(queryDto.BusinessNo)
|| s.CustomerNum.Contains(queryDto.BusinessNo)
|| s.BookingNo.Contains(queryDto.BusinessNo)
|| t.TASK_NO.Contains(queryDto.BusinessNo)
|| (isHasOrderParentIdList == true && orderParentIdList!.Contains(s.Id)))
.WhereIF(!string.IsNullOrEmpty(queryDto.PortLoadCode), (t, a, s) => queryDto.PortLoadCode == s.LoadPortCode)
.WhereIF(!string.IsNullOrEmpty(queryDto.PortDischargeCode), (t, a, s) => queryDto.PortDischargeCode == s.DischargePortCode)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == queryDto.Status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (a.UserId == userId) // 2024-8-14 只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == queryDto.Status);
if (taskStatLevel == TaskStatLevelEnum.UNDERLING)
{
queryable.Where((t, a) => a.Status == queryDto.Status && t.IS_PUBLIC == 0);
if (queryDto.UnderlingTaskScope is null or "none")
{
queryable.Where((t, a) => true == false);
}
else if (queryDto.UnderlingTaskScope == "self_org")
{
queryable.Where((t, a) => a.OrgId == user.OrgId);
}
else if (queryDto.UnderlingTaskScope == "self_org_with_child")
{
var db = serviceProvider.GetRequiredService<ISqlSugarClient>();
List<SysOrg> orgList = await db.Queryable<SysOrg>().ToChildListAsync(s => s.ParentId, user.OrgId);
IEnumerable<long> orgIdList = orgList.Select(x => x.Id);
queryable.Where((t, a) => orgIdList.Contains(a.OrgId));
}
else if (queryDto.UnderlingTaskScope == "self")
{
queryable.Where((t, a) => a.CreateBy == userId);
}
else if (queryDto.UnderlingTaskScope == "self_dept")
{
var db = serviceProvider.GetRequiredService<ISqlSugarClient>();
var deptUsers = db.Queryable<SysUser>().Where(x => x.DeptId != 0 && x.DeptId == SqlFunc.Subqueryable<SysUser>().Where(s => s.Id == userId).Select(s => s.DeptId)).Select(x => x.Id).ToList();
queryable.Where((t, a) => deptUsers.Contains(a.UserId));
}
else if (queryDto.UnderlingTaskScope == "all")
{
// 不做限制
}
}
queryable.OrderByDescending(t => t.Id);
}
/// <summary>
/// 获取登陆人相关的任务统计信息
/// </summary>
/// <returns>返回回执</returns>
public async Task<DataResult<TaskUserStatResultInfo>> GetCurrentTotalStat(GetCurrentTotalStatQueryDto queryDto)
{
TaskUserStatResultInfo resultInfo = new TaskUserStatResultInfo
{
LevelTop = new List<TaskUserStatItem>(),
LevelNext = new List<TaskUserStatItemNext>(),
LevelTree = new List<TaskUserStatItemTree>()
};
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear(typeof(IDeleted));
// 人员信息测试用
//var sql = tenantDb.Queryable<SeaExport>().Where(x => x.Id > 232).ToSqlString();
//var a = user.UserId;
//var aa = user.TenantId;
//var a343 = user.GetTenantId();
//var sfdfd = user.TenantName;
//var b = user.GetOrgId();
//var b232 = user.OrgId;
//if (LastMatchTaskTime < DateTime.Now.AddSeconds(-5)) // 效果距上一次全局任务匹配执行如果超过5秒才进行匹配
//{
//LastMatchTaskTime = DateTime.Now;
//}
if (queryDto.IsReCalc)
{
await MatchTask();
}
//序列化查询条件
List<IConditionalModel>? whereList = null;
if (!string.IsNullOrEmpty(queryDto.QueryCondition))
{
whereList = tenantDb.Utilities.JsonToConditionalModels(queryDto.QueryCondition);
if (whereList != null)
{
foreach (var item in whereList)
{
if (item is ConditionalModel model)
{
string lowerFieldName = model.FieldName.ToLower();
if (seaExportFields.Contains(lowerFieldName))
{
model.FieldName = "s." + model.FieldName;
}
else
{
model.FieldName = "t." + model.FieldName;
}
}
}
}
}
var userId = long.Parse(user.UserId);
var cancelStr = TaskStatusEnum.Cancel.ToString();
List<long>? orderParentIdList = null;
if (!string.IsNullOrEmpty(queryDto.OtherQueryCondition.BusinessNo))
{
orderParentIdList = (await tenantDb.Queryable<SeaExport>()
.ClearFilter(typeof(IOrgId))
.Where(x => x.ParentId != 0 && x.HBLNO.Contains(queryDto.OtherQueryCondition.BusinessNo))
.Select(x => x.ParentId)
.ToListAsync())
.Distinct().ToList();
}
var isHasOrderParentIdList = orderParentIdList != null;
long[]? portLoadTaskIdList = [];
if (!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortLoadCode))
{
var q1 = tenantDb.Queryable<TaskBCInfo>().Where(x => x.PORTLOAD_CODE == queryDto.OtherQueryCondition.PortLoadCode).Select(x => new { x.TASK_ID });
var temp = await q1.ToListAsync();
if (temp.Count > 0)
{
portLoadTaskIdList = temp.Select(x => x.TASK_ID).ToArray();
}
}
long[]? portDischargeTaskIdList = [];
if (!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortDischargeCode))
{
var q1 = tenantDb.Queryable<TaskBCInfo>().Where(x => x.PORTDISCHARGE_CODE == queryDto.OtherQueryCondition.PortDischargeCode).Select(x => new { x.TASK_ID });
var temp = await q1.ToListAsync();
if (temp.Count > 0)
{
portLoadTaskIdList = temp.Select(x => x.TASK_ID).ToArray();
}
}
//任务列表分组统计
// 下属任务统计
/* 备注:在之前已经清除了删除过滤器
* 未配置的情况: 登陆人所属机构下的人员【接收】的任务(需要调整为“无权限查询”)
* 超级管理员: 登陆人所属机构下的人员【接收】的任务带了机构筛选与self_org相同
* all全部 登陆人所属租户下的全部数据
* none未配置 无权限查询
* self_org本机构 登陆人所属机构下的人员【接收】的任务(与超级管理员相同)
* self_org_with_child当前机构及下属机构 登陆人所属机构及子机构下的人员【接收】的任务
* self本人 登陆人【创建】的任务
* self_dept本部门 登陆人所属部门的人【创建】的任务
* select_org本公司 查询指定机构下的人员所【创建或接收】的任务
* select_user选择人员 查询指定人员所【创建或接收】的任务
* customize自定义 根据自定义配置查询
*/
(ISugarQueryable<TaskBaseAllocation> underlingQueryable1, string? ruleScope) = await commonService.GetVisibleDataRuleFilter<TaskBaseAllocation>(tenantDb);
resultInfo.UnderlingTaskScope = ruleScope;
List<TaskGroupTotal>? underlingGroupList = null;
// 如果ruleScope为空或"none",说明没有查询下属任务的权限,则直接跳过查询
if (ruleScope != "none" && ruleScope != null)
{
// ruleScope如果为其它情况则按照权限配置来
var underlingQueryable = underlingQueryable1.InnerJoin<TaskBaseInfo>((a, t) => t.Id == a.TaskId
&& a.Deleted == false
&& t.Deleted == false
&& t.STATUS != cancelStr
&& t.IS_PUBLIC == 0)
.LeftJoin<SeaExport>((a, t, s) => t.OUT_BS_NO == s.Id)
.Where(whereList)
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.BusinessNo),
(a, t, s) => ((!string.IsNullOrEmpty(s.MBLNO) && s.MBLNO.Contains(queryDto.OtherQueryCondition.BusinessNo)) || (string.IsNullOrEmpty(s.MBLNO) && t.MBL_NO.Contains(queryDto.OtherQueryCondition.BusinessNo))) // 如果订单提单号不为空使用订单提单号查询,否则使用任务上的提单号查询
|| s.CustomerNo.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| s.BookingNo.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| s.CustomerNum.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| t.TASK_NO.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| (isHasOrderParentIdList == true && orderParentIdList!.Contains(s.Id)))
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortLoadCode), (t, a, s) => queryDto.OtherQueryCondition.PortLoadCode == s.LoadPortCode || portLoadTaskIdList.Contains(t.Id))
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortDischargeCode), (t, a, s) => queryDto.OtherQueryCondition.PortDischargeCode == s.DischargePortCode || portDischargeTaskIdList.Contains(t.Id))
.GroupBy((a, t) => new { t.TASK_TYPE, t.STATUS, a.Status, })
.Select((a, t) => new TaskGroupTotal()
{
Total = SqlFunc.AggregateDistinctCount(t.Id),
TaskType = t.TASK_TYPE,
TStatus = t.STATUS,
AStatus = a.Status
});
#if DEBUG
var sql2 = underlingQueryable.ToSqlString();
#endif
underlingGroupList = await underlingQueryable.ToListAsync();
#region 下属
if (underlingGroupList != null && underlingGroupList.Count > 0)
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.UNDERLING.ToString(),
Name = "下属",
Total = underlingGroupList.Sum(t => t.Total),
SortNo = 2,
ActionKey = TaskStatLevelEnum.UNDERLING.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
underlingGroupList.GroupBy(t => t.TStatus)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key, out TaskStatusEnum currEnum))
{
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.UNDERLING.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.UNDERLING}#{currEnum}"
});
}
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
underlingGroupList.GroupBy(t => new { t.TStatus, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key.TaskType, out TaskBaseTypeEnum currEnum))
{
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.UNDERLING.ToString(),
NextKey = t.Key.TStatus,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.UNDERLING}#{t.Key.TStatus}#{currEnum}"
});
}
});
}
else
{
// 走到这里说明有权限但是数据为空则返回一条数量为0的统计记录
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.UNDERLING.ToString(),
Name = "下属",
Total = 0,
SortNo = 2,
ActionKey = TaskStatLevelEnum.UNDERLING.ToString()
});
}
#endregion
}
tenantDb.QueryFilter.Clear();
// 个人及公共任务统计
var queryable = tenantDb.Queryable<TaskBaseInfo>()
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<SeaExport>((t, a, s) => t.OUT_BS_NO == s.Id)
.Where(whereList)
.Where((t, a) => t.STATUS != cancelStr && t.Deleted == false)
.Where((t, a) => t.IS_PUBLIC == 1 || (t.IS_PUBLIC == 0 && a.UserId == userId)) // 2024-8-14 只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.BusinessNo),
(t, a, s) => ((!string.IsNullOrEmpty(s.MBLNO) && s.MBLNO.Contains(queryDto.OtherQueryCondition.BusinessNo)) || (string.IsNullOrEmpty(s.MBLNO) && t.MBL_NO.Contains(queryDto.OtherQueryCondition.BusinessNo))) // 如果订单提单号不为空使用订单提单号查询,否则使用任务上的提单号查询
|| s.CustomerNo.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| s.BookingNo.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| s.CustomerNum.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| t.TASK_NO.Contains(queryDto.OtherQueryCondition.BusinessNo)
|| (isHasOrderParentIdList == true && orderParentIdList!.Contains(s.Id)))
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortLoadCode), (t, a, s) => queryDto.OtherQueryCondition.PortLoadCode == s.LoadPortCode || portLoadTaskIdList.Contains(t.Id))
.WhereIF(!string.IsNullOrEmpty(queryDto.OtherQueryCondition.PortDischargeCode), (t, a, s) => queryDto.OtherQueryCondition.PortDischargeCode == s.DischargePortCode || portDischargeTaskIdList.Contains(t.Id))
.GroupBy((t, a) => new { t.TASK_TYPE, t.STATUS, a.Status, t.IS_PUBLIC })
.Select((t, a) => new TaskGroupTotal()
{
Total = SqlFunc.AggregateDistinctCount(t.Id),
TaskType = t.TASK_TYPE,
TStatus = t.STATUS,
AStatus = a.Status,
//IsExcept = t.IS_EXCEPT,
IsPublic = t.IS_PUBLIC
});
#if DEBUG
var sql = queryable.ToSqlString();
#endif
var groupList = await queryable.ToListAsync();
//var exceptList = groupList
// .Where(t => t.IsExcept == 1).ToList();
var personList = groupList
.Where(t => t.IsPublic == 0).ToList();
var publicList = groupList
.Where(t => 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 = "个人",
Total = personList.Sum(t => t.Total),
SortNo = 1,
ActionKey = TaskStatLevelEnum.PERSON.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
personList.GroupBy(t => t.AStatus)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key, out TaskStatusEnum currEnum))
{
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.PERSON.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PERSON}#{currEnum}"
});
}
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
personList.GroupBy(t => new { t.AStatus, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key.TaskType, out TaskBaseTypeEnum currEnum))
{
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.PERSON.ToString(),
NextKey = t.Key.AStatus,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PERSON}#{t.Key.AStatus}#{currEnum}"
});
}
});
}
else
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.PERSON.ToString(),
Name = TaskStatLevelEnum.PERSON.EnumDescription(),
Total = 0,
SortNo = 1,
ActionKey = TaskStatLevelEnum.PERSON.ToString()
});
}
#endregion
#region 公共
if (publicList.Count > 0)
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.PUBLIC.ToString(),
Name = "公共",
Total = publicList.Sum(t => t.Total),
SortNo = 3,
ActionKey = TaskStatLevelEnum.PUBLIC.ToString()
});
var nextList = new List<TaskUserStatItemNext>();
publicList.GroupBy(t => t.TStatus)
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key, out TaskStatusEnum currEnum))
{
nextList.Add(new TaskUserStatItemNext
{
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PUBLIC}#{currEnum}"
});
}
});
if (nextList.Count > 0)
resultInfo.LevelNext.AddRange(nextList.OrderBy(t => t.SortNo).ToList());
publicList.GroupBy(t => new { t.TStatus, t.TaskType })
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
.ToList().ForEach(t =>
{
if (Enum.TryParse(t.Key.TaskType, out TaskBaseTypeEnum currEnum))
{
resultInfo.LevelTree.Add(new TaskUserStatItemTree
{
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
NextKey = t.Key.TStatus,
Key = currEnum.ToString(),
Name = currEnum.EnumDescription(),
Total = t.Total,
SortNo = (int)currEnum,
ActionKey = $"{TaskStatLevelEnum.PUBLIC}#{t.Key.TStatus}#{currEnum}"
});
}
});
}
else
{
resultInfo.LevelTop.Add(new TaskUserStatItem
{
Key = TaskStatLevelEnum.PUBLIC.ToString(),
Name = TaskStatLevelEnum.PUBLIC.EnumDescription(),
Total = 0,
SortNo = 3,
ActionKey = TaskStatLevelEnum.PUBLIC.ToString()
});
}
#endregion
if (resultInfo.LevelTree != null && resultInfo.LevelTree.Count > 0)
{
resultInfo.LevelTree = resultInfo.LevelTree.OrderBy(x => x.SortNo).ToList();
}
return DataResult<TaskUserStatResultInfo>.Success(resultInfo);
}
/// <summary>
/// 任务台台账子任务列表查询
/// </summary>
public async Task<DataResult<List<dynamic>>> GetChildTaskList(long taskId)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear();
var userId = long.Parse(user.UserId);
var queryable = tenantDb.Queryable<TaskBaseInfo>()
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId && a.Deleted == false)
.LeftJoin<SeaExport>((t, a, s) => t.OUT_BS_NO == s.Id)
.Where(t => t.IsChild == true && t.ParentTaskId == taskId);
ISugarQueryable<dynamic> queryableTemp = queryable.Select<dynamic>((t, a, s) => new
{
PK_ID = t.Id.SelectAll(),
orderMBLNO = s.MBLNO,
orderETD = s.ETD,
orderCarrier = s.Carrier,
orderCarrierId = s.CarrierId,
s.CustomerNo,
s.CustomerNum,
s.BookingNo,
s.HBLNO,
s.CustomerName,
s.Sale,
s.CustomerServiceName,
s.OperatorName,
s.LoadPortCode,
s.LoadPort,
s.DischargePortCode,
s.DischargePort,
s.CntrTotal,
}).Distinct();
List<dynamic> data = await queryableTemp.ToListAsync();
var result = DataResult<List<dynamic>>.Success(data);
if (result.Data?.Count > 0)
{
// 查询任务接收人列表
var taskIdList = result.Data.Select(x => (long)x.Id).ToList();
var allRecvUserList = await tenantDb.Queryable<TaskBaseAllocation>()
.Where(x => taskIdList.Contains(x.TaskId))
.Select(x => new RecvUserInfo()
{
TaskId = x.TaskId,
RecvUserId = x.UserId,
RecvUserName = x.UserName,
RecvUserStatus = x.Status,
RecvUserStatusName = x.StatusName,
RecvUserStatusTime = x.StatusTime
}).ToListAsync();
// 一些特殊处理
foreach (var item in result.Data)
{
// 1.任务接收人赋值
if (allRecvUserList.Count > 0)
{
var recvUserList = allRecvUserList.Where(x => x.TaskId == item.Id).ToList();
var currentUserStatus = recvUserList.FirstOrDefault(x => x.RecvUserId == userId);
if (currentUserStatus != null)
{
var n = recvUserList.IndexOf(currentUserStatus);
if (n != 0)
{
recvUserList.RemoveAt(n);
recvUserList.Insert(0, currentUserStatus);
}
item.TASK_USER_STATUS = currentUserStatus.RecvUserStatus;
item.TASK_USER_STATUS_NAME = currentUserStatus.RecvUserStatusName;
item.TASK_USER_STATUS_TIME = currentUserStatus.RecvUserStatusTime;
}
item.RecvUserList = recvUserList;
}
// 2.部分字段值覆盖提单号、ETD、船公司、委托编号如果订单的号码不为空则采用订单的号码
if (!string.IsNullOrEmpty(item.orderMBLNO))
{
item.MBL_NO = item.orderMBLNO;
}
if (item.orderETD != null)
{
item.ETD = item.orderETD;
}
if (!string.IsNullOrEmpty(item.orderCarrier))
{
item.CARRIER_CODE = item.orderCarrier;
item.CARRIER_ID = item.orderCarrierId;
item.CARRIER_NAME = null;
}
if (!string.IsNullOrEmpty(item.CustomerNo))
{
item.CUSTOMER_NO = item.CustomerNo;
}
// 3.ExtData字段从Data转为对象
if (!string.IsNullOrEmpty(item.ExtData))
{
try
{
item.ExtData = JObject.Parse(item.ExtData);
}
catch
{
item.ExtData = new { ParseError = true, ParseMessage = "ExtData为非标准Json导致解析异常" };
}
}
}
}
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 hasAuthor = await HasTaskHandleAuthority(ids);
if (!hasAuthor.Succeeded && hasAuthor.Data?.Count > 0)
{
if (ids.Length == 1)
{
result.succ = false;
result.msg = string.Format(MultiLanguageConst.GetDescription(MultiLanguageConst.TaskNotHaveAuthorSingle), string.Join("、", hasAuthor.Data));
}
else
{
result.succ = false;
result.msg = string.Format(MultiLanguageConst.GetDescription(MultiLanguageConst.TaskNotHaveAuthor), string.Join("、", hasAuthor.Data!));
}
return DataResult<TaskManageOrderResultDto>.FailedData(result);
}
var taskList = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.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 += " -";
}
if (result.succ)
{
return DataResult<TaskManageOrderResultDto>.Success(result);
}
else
{
return DataResult<TaskManageOrderResultDto>.FailedData(result);
}
}
/// <summary>
/// 取消任务(可批量)
/// </summary>
/// <param name="ids">任务主键数组</param>
/// <returns>返回结果</returns>
public async Task<DataResult<TaskManageOrderResultDto>> CancelTask(long[] ids)
{
ArgumentNullException.ThrowIfNull(ids);
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var userId = long.Parse(user.UserId);
string batchNo = Guid.NewGuid().ToString();
var hasAuthor = await HasTaskHandleAuthority(ids);
if (!hasAuthor.Succeeded && hasAuthor.Data?.Count > 0)
{
if (ids.Length == 1)
{
result.succ = false;
result.msg = string.Format(MultiLanguageConst.GetDescription(MultiLanguageConst.TaskNotHaveAuthorSingle), string.Join("、", hasAuthor.Data));
}
else
{
result.succ = false;
result.msg = string.Format(MultiLanguageConst.GetDescription(MultiLanguageConst.TaskNotHaveAuthor), string.Join("、", hasAuthor.Data!));
}
return DataResult<TaskManageOrderResultDto>.FailedData(result);
}
var taskList = await tenantDb.Queryable<TaskBaseInfo>().ClearFilter(typeof(IOrgId))
.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();
//serviceProvider.GetRequiredService<ISqlSugarClient>();
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);
}
/// <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);
var taskType = (TaskBaseTypeEnum)Enum.Parse(typeof(TaskBaseTypeEnum), model.TASK_TYPE);
if (taskOperTypeEnum == TaskOperTypeEnum.COMPLETE_TASK)
{
// 2024-10-29 只允许工作流退舱确认任务
string[] allowCompleteTaskType = [TaskBaseTypeEnum.RETURN_CABIN.ToString()];
if (model.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() && !allowCompleteTaskType.Contains(model.TASK_TYPE))
{
result.succ = false;
result.msg = "请在任务详情页进行操作";
return result;
}
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();
try
{
var allotIdList = await tenantDb.Queryable<TaskBaseAllocation>().Where(x => x.TaskId == model.Id).Select(x => x.Id).ToListAsync();
await tenantDb.AsTenant().BeginTranAsync();
await tenantDb.Updateable<TaskBaseAllocation>()
.SetColumns(x => new TaskBaseAllocation()
{
Status = TaskStatusEnum.Complete.ToString(),
StatusName = TaskStatusEnum.Complete.EnumDescription(),
StatusTime = DateTime.Now
}, true)
.Where(x => allotIdList.Contains(x.Id))
.ExecuteCommandAsync();
// 工作流相关逻辑:
if (model.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() && model.OUT_BS_NO is not (null or 0))
{
var orderId = model.OUT_BS_NO;
string? statusCode = await tenantDb.Queryable<TaskFlowModule>().Where(x => x.ModuleType == 2 && x.TaskType == model.TASK_TYPE).Select(x => x.CompletedBusinessStatusCode).FirstAsync();
if (!string.IsNullOrEmpty(statusCode))
{
// 1.设置相关订单的业务状态
try
{
await seaExportCommonService.Value.SetGoodsStatus(statusCode, (long)orderId, tenantDb);
}
catch (Exception ex)
{
logger.LogError(ex, "任务完成时设置订单业务状态的过程中发生异常orderId={0}taskType={1}", orderId, model.TASK_TYPE);
throw;
}
// 2.设置货物状态为已完成
try
{
await djyServiceStatusService.Value.SaveServiceStatus(new EmbedServiceProjectStatusDto()
{
businessId = orderId.ToString()!,
SourceType = 1,
StatusCodes = [new() { StatusCode = statusCode }]
});
}
catch (Exception ex)
{
logger.LogError(ex, "任务完成时设置订单的货物状态时发生异常orderId={0}taskType={1}", orderId, model.TASK_TYPE);
throw;
}
}
// 3.设置工作流的两个相关的表的状态
var waitUpdateBusinessTaskIdList = await tenantDb.Queryable<BusinessTask>()
.Where(x => x.BusinessId == orderId && x.TaskType == taskType)
.Select(x => x.Id)
.ToListAsync();
if (waitUpdateBusinessTaskIdList.Count > 0)
{
await tenantDb.Updateable<BusinessTask>()
.SetColumns(x => x.TaskStatus == TaskStatusEnum.Complete)
.Where(x => waitUpdateBusinessTaskIdList.Contains(x.Id))
.ExecuteCommandAsync();
}
var waitUpdateFlowInstanceId = await db.Queryable<FlowInstance>()
.ClearFilter(typeof(ITenantId))
.Where(y => y.BusinessId == orderId && y.AuditType == taskType)
.OrderByDescending(y => y.Id)
.Select(y => y.Id)
.FirstAsync();
if (waitUpdateFlowInstanceId != 0)
{
await db.Updateable<FlowInstance>()
.SetColumns(x => x.FlowStatus == FlowStatusEnum.Approve)
.Where(x => x.Id == waitUpdateFlowInstanceId)
.ExecuteCommandAsync();
}
// 4. 如果任务类型为退舱确认当任务完成时需要发送Cargoo
if (model.TASK_TYPE == TaskBaseTypeEnum.RETURN_CABIN.ToString())
{
try
{
// 退舱完成后推送Cargoo
var cargooService = serviceProvider.GetRequiredService<ICargooService>();
await cargooService.SendCargoo(new CargooShipmentReqDto()
{
bookingId = (long)model.OUT_BS_NO,
cargooStatusEnum = CargooStatusEnum.Cancelled
});
}
catch (Exception ex)
{
logger.LogError(ex, "退舱确认任务完成时推送Cargoo的过程中发生异常");
}
}
}
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();
await tenantDb.AsTenant().CommitTranAsync();
}
catch (Exception)
{
await tenantDb.AsTenant().RollbackTranAsync();
throw;
}
}
else if (taskOperTypeEnum == TaskOperTypeEnum.CANCEL_TASK)
{
//if (model.STATUS == TaskStatusEnum.Complete.ToString())
//{
// result.succ = false;
// result.msg = "当前任务为已完状态成,无法取消";
// return result;
//}
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();
var allotIdList = await tenantDb.Queryable<TaskBaseAllocation>().Where(x => x.TaskId == model.Id).Select(x => x.Id).ToListAsync();
try
{
await tenantDb.AsTenant().BeginTranAsync();
// 工作流相关逻辑:
if (model.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() && model.OUT_BS_NO is not (null or 0))
{
var orderId = model.OUT_BS_NO;
// 3.设置工作流的两个相关的表的状态
var waitUpdateBusinessTaskIdList = await tenantDb.Queryable<BusinessTask>().Where(x => x.BusinessId == orderId && x.TaskType == taskType).Select(x => x.Id).ToListAsync();
if (waitUpdateBusinessTaskIdList.Count > 0)
{
await tenantDb.Updateable<BusinessTask>()
.SetColumns(x => x.TaskStatus == TaskStatusEnum.Cancel)
.Where(x => waitUpdateBusinessTaskIdList.Contains(x.Id))
.ExecuteCommandAsync();
}
var waitUpdateFlowInstanceId = await db.Queryable<FlowInstance>()
.ClearFilter(typeof(ITenantId))
.Where(y => y.BusinessId == orderId && y.AuditType == taskType)
.OrderByDescending(y => y.Id)
.Select(y => y.Id)
.FirstAsync();
if (waitUpdateFlowInstanceId != 0)
{
await db.Updateable<FlowInstance>()
.SetColumns(x => x.FlowStatus == FlowStatusEnum.Draft)
.Where(x => x.Id == waitUpdateFlowInstanceId)
.ExecuteCommandAsync();
}
}
await tenantDb.Updateable<TaskBaseAllocation>()
.SetColumns(x => new TaskBaseAllocation()
{
Status = TaskStatusEnum.Cancel.ToString(),
StatusName = TaskStatusEnum.Cancel.EnumDescription(),
StatusTime = DateTime.Now,
}, true)
.Where(x => allotIdList.Contains(x.Id))
.ExecuteCommandAsync();
await tenantDb.Updateable(model).UpdateColumns(it => new
{
it.STATUS,
it.STATUS_NAME,
it.UpdateBy,
it.UpdateTime,
it.UpdateUserName
}).ExecuteCommandAsync();
await tenantDb.AsTenant().CommitTranAsync();
}
catch (Exception)
{
await tenantDb.AsTenant().RollbackTranAsync();
throw;
}
}
}
result.succ = true;
result.msg = "执行成功";
}
catch (Exception ex)
{
result.succ = false;
result.msg = ex.Message;
}
return result;
}
/// <summary>
/// 领取任务到当前登陆人(可批量)
/// </summary>
public async Task<DataResult> PullTask(long[] ids)
{
if (ids == null || ids.Length == 0)
{
throw new ArgumentNullException(nameof(ids));
}
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear<IOrgId>();
var userId = long.Parse(user.UserId);
try
{
var taskList = await tenantDb.Queryable<TaskBaseInfo>().Where(x => ids.Contains(x.Id)).ToListAsync(x => new
{
x.Id,
x.STATUS,
x.STATUS_NAME,
x.TASK_TYPE,
x.OUT_BS_NO,
x.TASK_SOURCE
});
var taskIdList = taskList.Select(x => x.Id).ToList();
var taskTypeList = taskList.Where(x => x.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() && x.OUT_BS_NO != null).Select(x => x.TASK_TYPE).Distinct().ToList();
var taskCompleteStatusCodeList = taskTypeList.Count > 0 ? await tenantDb.Queryable<TaskFlowModule>()
.Where(x => x.ModuleType == 2 && taskTypeList.Contains(x.TaskType))
.Select(x => new { x.TaskType, x.CompletedBusinessStatusCode })
.ToListAsync()
: [];
var userOrgId = await db.Queryable<SysUser>().Where(x => x.Id == userId).Select(x => x.DefaultOrgId).FirstAsync();
List<TaskBaseAllocation> allocationList = new();
foreach (var item in taskList)
{
allocationList.Add(new TaskBaseAllocation()
{
TaskId = item.Id,
UserId = userId,
UserName = user.UserName,
Status = item.STATUS,
StatusName = item.STATUS_NAME,
StatusTime = DateTime.Now,
BusinessId = item.OUT_BS_NO,
GoodStatusCode = taskCompleteStatusCodeList.FirstOrDefault(x => x.TaskType == item.TASK_TYPE)?.CompletedBusinessStatusCode,
OrgId = userOrgId
});
}
await tenantDb.AsTenant().BeginTranAsync();
var idList = await tenantDb.Queryable<TaskBaseAllocation>().Where(x => taskIdList.Contains(x.TaskId)).Select(x => x.Id).ToListAsync();
await tenantDb.Deleteable<TaskBaseAllocation>(x => idList.Contains(x.Id)).ExecuteCommandAsync();
await tenantDb.Insertable(allocationList).ExecuteCommandAsync();
await tenantDb.Updateable<TaskBaseInfo>()
.SetColumns(x => x.IS_PUBLIC == 0)
.Where(x => taskIdList.Contains(x.Id))
.ExecuteCommandAsync();
foreach (var item in taskList)
{
if (item.OUT_BS_NO is not (null or 0) && Enum.TryParse(typeof(TaskBaseTypeEnum), item.TASK_TYPE, out object? taskType))
{
await tenantDb.Updateable<BusinessTask>()
.SetColumns(x => x.RecvUsers == user.UserId)
.Where(x => x.BusinessId == item.OUT_BS_NO && x.TaskType == (TaskBaseTypeEnum)taskType)
.ExecuteCommandAsync();
var flowInstanceId = await db.Queryable<FlowInstance>()
.ClearFilter(typeof(ITenantId))
.Where(y => y.BusinessId == item.OUT_BS_NO && y.AuditType == (TaskBaseTypeEnum)taskType)
.OrderByDescending(y => y.Id)
.Select(y => y.Id)
.FirstAsync();
if (flowInstanceId != 0)
{
await db.Updateable<FlowInstance>()
.SetColumns(x => x.MakerList == user.UserId)
.Where(x => x.Id == flowInstanceId)
.ExecuteCommandAsync();
}
}
}
await tenantDb.AsTenant().CommitTranAsync();
return DataResult.Successed("操作成功", MultiLanguageConst.OperationSuccess);
}
catch (Exception ex)
{
await tenantDb.AsTenant().RollbackTranAsync();
return DataResult.Failed("任务领取失败,原因:" + ex.Message);
}
}
/// <summary>
/// 测试用
/// </summary>
public async Task<DataResult> TestTaskFlow(string taskType, long taskId, int testType)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
// 人员信息测试用
var a1 = user.UserId;
var b1 = user.UserName;
var c1 = user.TenantId;
var d1 = user.TenantName;
var e1 = user.OrgId;
var sql = tenantDb.Queryable<SeaExport>().Where(x => x.Id > 232).ToSqlString();
var t11 = tenantDb.ContextID;
switch (testType)
{
// 事务测试
case 0:
{
try
{
await tenantDb.Ado.BeginTranAsync();
await tenantDb.Deleteable<SeaExport>().Where(x => x.BusinessStatus == "0123123").ExecuteCommandAsync();
//var t1 = tenantDb.ContextID;
//var t2 = await tenantDb.Queryable<TaskFlowLogDetail>().Where(x => x.Id == taskId).ToListAsync();
//var m = new TaskFlowLogDetail()
//{
// ModuleName = taskId.ToString()
//};
//var t3 = await tenantDb.Insertable(m).ExecuteCommandAsync();
//var service = serviceProvider.GetRequiredService<ITaskManageBCService>();
//await service.TestDelete(taskId);
await tenantDb.Ado.CommitTranAsync();
}
catch (Exception)
{
await tenantDb.Ado.RollbackTranAsync();
throw;
}
break;
}
// 任务编排执行测试
case 1:
{
var taskTypeEnum = (TaskBaseTypeEnum)Enum.Parse(typeof(TaskBaseTypeEnum), taskType);
TaskManageOrderMessageInfo p1 = new TaskManageOrderMessageInfo()
{
Main = new TaskManageOrderMessageMainInfo()
{
BCInfo = new TaskManageOrderBCInfo()
{
Vessel = "TESTVESSEL"
}
}
};
TaskFlowDataContext dataContext = new(
((TaskFlowDataNameConst.TaskManageOrderMessageInfo), p1),
(("Name"), "QD-ZXF"),
(("Age"), 19),
(("Height"), 160)
);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(taskTypeEnum, taskId, dataContext);
break;
}
// 分配测试
case 2:
{
var order = await tenantDb.Queryable<SeaExport>().Select<Core.Op.Dtos.SeaExportRes>().FirstAsync(x => x.Id == 1816649497120477184);
TaskFlowDataContext dataContext2 = new(
(TaskFlowDataNameConst.Business, order)
);
var taskAllocationService = serviceProvider.GetRequiredService<ITaskAllocationService>();
var result = await taskAllocationService.GetAllotUserBySeaExportId(new List<TaskBaseTypeEnum>() {
TaskBaseTypeEnum.INVOICE_BILL_MAIL,
TaskBaseTypeEnum.NOT_LOADED,
TaskBaseTypeEnum.NOT_SHIPMENG,
}, 1816649497120477184, dataContext2);
break;
}
// 工作流获取下一节点测试
case 3:
{
var order = await tenantDb.Queryable<SeaExport>().Select<Core.Op.Dtos.SeaExportRes>().FirstAsync(x => x.Id == 1816649497120477184);
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.Business, order)
//("hasCabin", "false")
);
TaskFlowRuner runer = new TaskFlowRuner(tenantDb, serviceProvider);
var result22 = await runer.GetWorkFlowNextConfigByTaskType(TaskBaseTypeEnum.WORK_FLOW_MAIN, dataContext, TaskBaseTypeEnum.WAIT_BOOKING); // 正常
break;
}
// 判断条件测试
case 4:
{
var condition = await tenantDb.Queryable<TaskFlowCondition>().FirstAsync(x => x.Id == 4001);
if (condition != null)
{
var conditionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content!);
TaskManageOrderMessageInfo p1 = new TaskManageOrderMessageInfo()
{
Main = new TaskManageOrderMessageMainInfo()
{
BCInfo = new TaskManageOrderBCInfo()
{
Vessel = "ZXF"
}
}
};
int? A3 = 19;
long? A4 = 19;
long A5 = 19;
bool? B3 = true;
TaskFlowDataContext dataContext = new(
(("A1"), 19),
(("A2"), null),
(("A3"), A3),
(("A4"), A4),
(("A5"), A5),
(("B1"), true),
(("B2"), "true"),
(("B3"), B3),
(("B4"), null),
(("C1"), DateTime.Now),
(("C2"), new DateTime(2022, 2, 2, 2, 2, 2)),
(("C3"), "2022-2-2 2:2:2"),
(("C4"), "2022-2-2"),
(("C5"), null),
(("D1"), "ZXF"),
(("D2"), ""),
(("D3"), null),
((TaskFlowDataNameConst.TaskManageOrderMessageInfo), p1)
);
var a = ConditionHelper.IsPass(conditionContent, dataContext);
}
break;
}
// 任务处理权限判断
case 6:
{
var bstask = new List<(long, TaskBaseTypeEnum)>()
{
(1780891904372772864,TaskBaseTypeEnum.WAIT_ORDER_AUDIT),
(1821406672657190912,TaskBaseTypeEnum.BC),
};
var a = await HasTaskHandleAuthorityWithBsno(bstask);
break;
}
case 7:
{
var temp = tenantDb.Ado.SqlQuery<dynamic>("select * from task_flow_module where id in(@ids)", new { ids = new int[] { 2001, 2002 } });
var p = new SugarParameter("@id", "2001,2002");
var temp2 = tenantDb.Ado.SqlQuery<dynamic>("select * from task_flow_module where id in(@id)", p);
break;
}
}
return DataResult.Successed("测试成功");
}
}
/// <summary>
/// 任务分组统计类
/// </summary>
internal class TaskGroupTotal
{
public int Total { get; set; }
public string TaskType { get; set; }
public string TStatus { get; set; }
public string AStatus { get; set; }
public int? IsPublic { get; set; }
}
}