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.

400 lines
17 KiB
C#

using System.Linq.Expressions;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.Module.DjyServiceStatus;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Sys.Entity;
using DS.WMS.Core.TaskInteraction.Dtos;
using DS.WMS.Core.TaskInteraction.Entity;
using DS.WMS.Core.TaskInteraction.Interface;
using DS.WMS.Core.TaskPlat.Dtos;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace DS.WMS.Core.TaskInteraction.Method
{
/// <summary>
/// 海运出口任务交互服务
/// </summary>
public class SeaExportTaskService : TaskService, ISeaExportTaskService
{
const TaskBaseTypeEnum BL_CONFIRM_TASK = TaskBaseTypeEnum.WAIT_BILL_CONFIRM;
readonly Lazy<IDjyServiceStatusService> djyService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public SeaExportTaskService(IServiceProvider provider) : base(provider)
{
djyService = new Lazy<IDjyServiceStatusService>(provider.GetRequiredService<IDjyServiceStatusService>());
}
public override Task<DataResult> CreateTaskAsync(TaskCreationRequest request, bool useTransaction = true)
{
if (request.TaskType == TaskBaseTypeEnum.WAIT_BILL_CONFIRM)
{
request.Steps ??= [];
if (!request.Steps.Exists(x => x.Type == StepType.OPConfirm))
{
request.Steps.Add(new TaskStepDto
{
Type = StepType.OPConfirm,
Name = StepType.OPConfirm.ToString()
});
}
}
return base.CreateTaskAsync(request, useTransaction);
}
/// <summary>
/// 创建关联子任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task CreateSubTaskAsync(IEnumerable<TaskCreationRequest> request)
{
if (request == null || !request.Any())
return;
var first = request.First();
var taskTypes = request.Select(x => x.TaskType).Distinct().ToArray();
var existTypes = await GetQuery(first.BusinessId, first.BusinessType, taskTypes).Select(x => x.TaskType).ToListAsync();
//移除已存在的任务类型
request = request.Where(x => !existTypes.Contains(x.TaskType));
if (!request.Any())
return;
long userId = long.Parse(User.UserId);
long tenatId = long.Parse(User.TenantId);
string tenatName = Db.Queryable<SysTenant>().Where(x => x.Id == tenatId).Select(x => x.Name).First();
var dt = DateTime.Now;
var defaultUsers = await FillInUserInfoAsync(first.RecvUserIdList);
var biz = await TenantDb.Queryable<SeaExport>().Select(x => new
{
x.Id,
x.CustomerNo,
x.MBLNO,
x.Vessel,
x.Voyno,
x.ETD,
x.DischargePortId,
x.DischargePortCode,
x.DischargePort,
x.LoadPortId,
x.LoadPortCode,
x.LoadPort,
x.CarrierId,
x.Carrier,
//x.BookingNo,
//x.HBLNO,
//x.CustomerNum,
}).FirstAsync(x => x.Id == first.BusinessId);
var taskList = new List<BusinessTask>();
var taskLogList = new List<BusinessTaskLog>();
//获取任务接收人
var dic = await GetRecvUsersAsync(first.BusinessId, first.BusinessType, request.Select(x => x.TaskType).ToList());
foreach (var item in request)
{
var recvUsers = dic[item.TaskType];
var info = new TaskManageOrderMessageInfo
{
Head = new TaskManageOrderMessageHeadInfo
{
GID = Guid.NewGuid().ToString(),
BSNO = item.BusinessId,
MessageType = "WORK_FLOW_TASK",
SenderId = "WorkFlow",
SenderName = "工作流平台",
ReceiverId = "TaskManage",
ReceiverName = "任务管理平台",
Version = "1.0",
RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
RequestAction = "Add"
},
Main = new TaskManageOrderMessageMainInfo
{
TaskType = item.TaskType,
TaskSource = TaskSourceEnum.WORK_FLOW,
TaskUserId = User.UserId,
TaskUserName = User.UserName,
RecvUserInfoList = recvUsers ?? defaultUsers,
TaskTenatId = tenatId,
TaskTenatName = tenatName,
IsCheckExistsByTaskType = true
}
};
info.Main.TaskDesp = info.Main.TaskTitle = $"【{item.TaskType.GetDescription()}】{biz?.CustomerNo} {biz?.Vessel} {biz?.Voyno} ETD:{biz?.ETD?.ToString("yyyy-MM-dd")}";
info.Main.CustomerNo = biz?.CustomerNo;
info.Main.MBlNo = biz?.MBLNO;
info.Main.ETD = biz?.ETD;
info.Main.PortDischarge = biz?.DischargePort;
info.Main.PortDischargeCode = biz?.DischargePortCode;
info.Main.PortDischargeId = biz?.DischargePortId;
info.Main.PortLoad = biz?.LoadPort;
info.Main.PortLoadId = biz?.LoadPortId;
info.Main.PortLoadCode = biz?.LoadPortCode;
info.Main.CarrierId = biz?.Carrier;
info.Main.CarrierPK = biz?.CarrierId;
//info.Main.HBLNO = biz?.HBLNO;
//info.Main.BookingNo = biz?.BookingNo;
//info.Main.CustomsNum = biz?.CustomerNum;
var result = await ManagerService.InitTaskJob(info);
if (!result.Succeeded)
continue;
var task = new BusinessTask
{
BusinessId = item.BusinessId,
BusinessType = item.BusinessType,
TaskType = item.TaskType,
TaskStatus = TaskStatusEnum.Create,
RecvUsers = info.Main.RecvUserInfoList == null ? string.Empty : string.Join(",", info.Main.RecvUserInfoList.Select(x => x.RecvUserId)),
CreateBy = userId,
CreateTime = dt
};
taskList.Add(task);
taskLogList.Add(new BusinessTaskLog
{
BusinessId = task.BusinessId,
BusinessType = task.BusinessType,
CreateBy = userId,
CreateTime = dt,
RecvUsers = info.Main.RecvUserInfoList == null ? null : string.Join(",", info.Main.RecvUserInfoList.Select(x => x.RecvUserName)),
TaskStatus = task.TaskStatus,
TaskType = task.TaskType
});
}
await TenantDb.Insertable(taskList).ExecuteCommandAsync();
await TenantDb.Insertable(taskLogList).ExecuteCommandAsync();
}
/// <summary>
/// 创建关联子任务
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public async Task CreateSubTaskAsync(BusinessTask task)
{
var list = await GetSubRequestAsync(task.BusinessId, task.BusinessType.GetValueOrDefault());
await CreateSubTaskAsync(list.FindAll(x => x.TaskType != TaskBaseTypeEnum.NOT_SPECIFIED).OrderBy(x => x.TaskType));
}
/// <summary>
/// 生成关联子任务
/// </summary>
/// <param name="dataContext"></param>
/// <returns></returns>
public async Task GenerateSubTaskAsync(TaskFlowDataContext dataContext)
{
ArgumentNullException.ThrowIfNull(dataContext, nameof(dataContext));
var task = dataContext.GetOrDefault<BusinessTask>(TaskFlowDataNameConst.BusinessTask);
if (task != null)
await CreateSubTaskAsync(task);
}
/// <summary>
/// 获取提单确认信息
/// </summary>
/// <param name="bsId">业务ID</param>
/// <param name="bsType">业务类型</param>
/// <returns></returns>
public async Task<DataResult<TaskGroup>> GetBLConfirmationAsync(long bsId, BusinessType bsType)
{
var confirmation = new TaskGroup
{
BusinessId = bsId,
BusinessType = bsType,
};
var mainTask = await TenantDb.Queryable<BusinessTask>()
.LeftJoin<SeaExport>((t, s) => t.BusinessId == s.Id)
.Where((t, s) => t.TaskType == BL_CONFIRM_TASK && t.BusinessId == bsId && t.BusinessType == bsType)
.OrderByDescending((t, s) => t.CreateTime)
.Select((t, s) => new BLTask
{
BLNumber = s.MBLNO,
Id = t.Id,
BusinessId = t.BusinessId,
BusinessType = t.BusinessType,
ParentBusinessId = t.ParentBusinessId,
ParentId = t.ParentId,
TaskType = t.TaskType,
TaskStatus = t.TaskStatus,
RecvUsers = t.RecvUsers,
IsMainBL = true,
Steps = SqlFunc.Subqueryable<TaskStep>().Where(ts => ts.TaskId == t.Id).ToList(ts => new TaskStepDto
{
}, true)
}).FirstAsync();
if (mainTask == null)
return DataResult<TaskGroup>.Success(confirmation);
var list = await TenantDb.Queryable<BusinessTask>()
.LeftJoin<SeaExportBillManage>((t, b) => t.BusinessId == b.Id)
.Where((t, b) => t.ParentBusinessId == bsId && t.BusinessType == bsType)
.Select((t, b) => new BLTask
{
BLNumber = b.HBLNO,
Id = t.Id,
BusinessId = t.BusinessId,
BusinessType = t.BusinessType,
ParentBusinessId = t.ParentBusinessId,
ParentId = t.ParentId,
TaskType = t.TaskType,
TaskStatus = t.TaskStatus,
RecvUsers = t.RecvUsers,
IsMainBL = false,
Steps = SqlFunc.Subqueryable<TaskStep>().Where(ts => ts.TaskId == t.Id).ToList(ts => new TaskStepDto
{
}, true)
}).ToListAsync();
list.Insert(0, mainTask);
confirmation.Tasks = list;
if (confirmation.Tasks.Count > 0)
{
var ids = confirmation.Tasks.SelectMany(x => x.RecvUserIds).Distinct();
var userList = await Db.Queryable<SysUser>().Where(x => ids.Contains(x.Id))
.Select(x => new { x.Id, x.UserName }).ToListAsync();
foreach (var item in confirmation.Tasks)
{
item.RecvUserList = userList.Where(x => item.RecvUserIds.Contains(x.Id))
.Select(x => x.UserName).ToArray();
}
}
return DataResult<TaskGroup>.Success(confirmation);
}
/// <summary>
/// 获取海运出口查询对象
/// </summary>
/// <param name="expression">查询条件</param>
/// <returns></returns>
public ISugarQueryable<SeaExport> AsQueryable(Expression<Func<SeaExport, bool>>? expression = null)
{
return TenantDb.Queryable<SeaExport>().WhereIF(expression != null, expression);
}
protected override async Task<DataResult> OnTaskCreated(BusinessTask task)
{
if (task.TaskType == TaskBaseTypeEnum.WAIT_BOOKING)
{
var order = await AsQueryable(x => x.Id == task.BusinessId).Select(x => new
{
x.BookingNo,
x.MBLNO
}).FirstAsync();
//订单已有订舱编号或提单号,当前任务直接完成
if (order != null && (!order.BookingNo.IsNullOrEmpty() || !order.MBLNO.IsNullOrEmpty()))
{
string taskDesc = "因订单已存在";
if (!order.BookingNo.IsNullOrEmpty())
{
taskDesc += $"订舱编号({order.BookingNo})、";
}
if (!order.MBLNO.IsNullOrEmpty())
{
taskDesc += $"提单号({order.MBLNO})、";
}
taskDesc = taskDesc.Remove(taskDesc.Length - 1) + "而跳过订舱";
await SetTaskStatusAsync(new TaskUpdateRequest
{
BusinessId = task.BusinessId,
BusinessType = task.BusinessType,
TaskTypeName = task.TaskType.ToString(),
TaskStatus = TaskStatusEnum.Complete,
TaskDesc = taskDesc
}, false);
}
}
return DataResult.Success;
}
internal async Task<List<TaskCreationRequest>> GetSubRequestAsync(long id, BusinessType businessType, params long[]? recvUsers)
{
var svcList = await GetServicesAsync(id);
var list = new List<TaskCreationRequest>(svcList.Length);
for (int i = 0; i < svcList.Length; i++)
{
var dto = new TaskCreationRequest { BusinessId = id, BusinessType = businessType, RecvUserIdList = recvUsers };
var svcName = svcList[i];
if (svcName == "报关")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_BAOGUAN.ToString();
else if (svcName == "订舱")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_CANGDAN.ToString();
else if (svcName.Equals("VGM", StringComparison.OrdinalIgnoreCase))
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_VGM.ToString();
else if (svcName.Equals("AFR", StringComparison.OrdinalIgnoreCase))
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_AFR.ToString();
else if (svcName.Equals("AMS", StringComparison.OrdinalIgnoreCase))
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_AMS.ToString();
else if (svcName.Equals("ISF", StringComparison.OrdinalIgnoreCase))
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_ISF.ToString();
else if (svcName == "熏蒸")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_XUNZHENG.ToString();
else if (svcName == "商检")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_SHANGJIAN.ToString();
else if (svcName.Equals("COA证书", StringComparison.OrdinalIgnoreCase))
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_COA.ToString();
else if (svcName == "产地证")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_CHANDIZHENG.ToString();
else if (svcName == "拖车")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_TUOCHE.ToString();
else if (svcName == "保险")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_INSURANCE.ToString();
else if (svcName == "出号")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_CHUHAO.ToString();
else if (svcName == "内点入货")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_NDRH.ToString();
else if (svcName == "快递")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_DELIVERY.ToString();
else if (svcName == "箱使")
dto.TaskTypeName = TaskBaseTypeEnum.WAIT_XIANGSHI.ToString();
list.Add(dto);
}
return list;
}
internal async Task<string[]> GetServicesAsync(long id)
{
var result = await djyService.Value.GetServiceProjectList(
new EmbedQueryServiceProjectWithStatus { BusinessId = id.ToString() });
if (!result.success)
return [];
if (((JObject)result.data)["ext"] is not JArray extArray || extArray.Count == 0)
return [];
return extArray.Where(x => x["isYield"].Value<bool>()).Select(
x => x["projectName"]?.Value<string>() ?? string.Empty).ToArray();
}
}
}