|
|
|
|
using DS.Module.Core;
|
|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using DS.Module.Core.Helpers;
|
|
|
|
|
using DS.WMS.Core.Fee.Method;
|
|
|
|
|
using DS.WMS.Core.Flow.Dtos;
|
|
|
|
|
using DS.WMS.Core.Op.Dtos.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Op.Entity;
|
|
|
|
|
using DS.WMS.Core.Op.Entity.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Op.Interface.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Sys.Entity;
|
|
|
|
|
using DS.WMS.Core.TaskPlat.Dtos;
|
|
|
|
|
using DS.WMS.Core.TaskPlat.Interface;
|
|
|
|
|
using Masuit.Tools.Systems;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
|
|
|
|
|
namespace DS.WMS.Core.Op.Method.TaskInteraction
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 任务交互服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
public abstract class TaskService : FeeServiceBase, ITaskService
|
|
|
|
|
{
|
|
|
|
|
const long PERMISSION_ID = 1815294400855674880;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 任务管理服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected ITaskManageService ManagerService { get; private set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 初始化
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="provider"></param>
|
|
|
|
|
protected TaskService(IServiceProvider provider) : base(provider)
|
|
|
|
|
{
|
|
|
|
|
ManagerService = provider.GetRequiredService<ITaskManageService>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 确保任务交互模块已授权
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual async Task<bool> EnsureModuleAuthorized()
|
|
|
|
|
{
|
|
|
|
|
//if (!await Db.Queryable<SysPermissionTenant>().AnyAsync(x => x.PermissionId == PERMISSION_ID))
|
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
|
|
long tid = long.Parse(User.TenantId);
|
|
|
|
|
var authStr = await Db.Queryable<SysTenantPermissionAuth>().Where(x => x.PermissionId == PERMISSION_ID && x.TenantId == tid &&
|
|
|
|
|
SqlFunc.Subqueryable<SysPermissionTenant>().Where(spt => spt.PermissionId == x.PermissionId).Any())
|
|
|
|
|
.Select(x => x.AuthNum).FirstAsync();
|
|
|
|
|
if (authStr.IsNullOrEmpty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
var appSecret = await Db.Queryable<SysTenant>().Where(x => x.Id == tid).Select(x => x.AppSecret).FirstAsync();
|
|
|
|
|
return int.TryParse(EncrypteHelper.DecryptData(authStr, appSecret), out int authNum) && authNum > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 创建关联任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="request"></param>
|
|
|
|
|
/// <param name="useTransaction">是否使用事务</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult> CreateTaskAsync(TaskCreationRequest request, bool useTransaction = true)
|
|
|
|
|
{
|
|
|
|
|
if (!await EnsureModuleAuthorized())
|
|
|
|
|
return DataResult.SuccessedWithDesc(nameof(MultiLanguageConst.ModuleUnauthorized));
|
|
|
|
|
|
|
|
|
|
var task = await GetTaskAsync(request.BusinessId, request.BusinessType, request.TaskType);
|
|
|
|
|
if (task != null)
|
|
|
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Task_Exists));
|
|
|
|
|
|
|
|
|
|
long tenatId = long.Parse(User.TenantId);
|
|
|
|
|
string tenatName = Db.Queryable<SysTenant>().Where(x => x.Id == tenatId).Select(x => x.Name).First();
|
|
|
|
|
var info = new TaskManageOrderMessageInfo
|
|
|
|
|
{
|
|
|
|
|
Head = new TaskManageOrderMessageHeadInfo
|
|
|
|
|
{
|
|
|
|
|
GID = Guid.NewGuid().ToString(),
|
|
|
|
|
BSNO = request.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 = request.TaskType,
|
|
|
|
|
TaskSource = TaskSourceEnum.WORK_FLOW,
|
|
|
|
|
TaskTitle = request.TaskTitle,
|
|
|
|
|
TaskDesp = request.TaskDescription,
|
|
|
|
|
TaskUserId = User.UserId,
|
|
|
|
|
TaskUserName = User.UserName,
|
|
|
|
|
RecvUserId = User.UserId,
|
|
|
|
|
RecvUserName = User.UserName,
|
|
|
|
|
TaskTenatId = tenatId,
|
|
|
|
|
TaskTenatName = tenatName
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (info.Main.TaskTitle.IsNullOrEmpty())
|
|
|
|
|
{
|
|
|
|
|
var biz = await TenantDb.Queryable<SeaExport>().Select(x => new
|
|
|
|
|
{
|
|
|
|
|
x.Id,
|
|
|
|
|
x.MBLNO,
|
|
|
|
|
x.Vessel,
|
|
|
|
|
x.Voyno,
|
|
|
|
|
x.ETD,
|
|
|
|
|
}).FirstAsync(x => x.Id == request.BusinessId);
|
|
|
|
|
|
|
|
|
|
info.Main.TaskDesp = info.Main.TaskTitle = $"{request.TaskType.GetDescription()} {biz.Vessel} {biz.Voyno} ETD:{biz.ETD?.ToString("yyyy-MM-dd")} BLNo:{biz.MBLNO}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (useTransaction)
|
|
|
|
|
await TenantDb.Ado.BeginTranAsync();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var result = await ManagerService.InitTaskJob(info);
|
|
|
|
|
if (!result.Succeeded)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
task = new BusinessTask
|
|
|
|
|
{
|
|
|
|
|
BusinessId = request.BusinessId,
|
|
|
|
|
BusinessType = request.BusinessType,
|
|
|
|
|
TaskType = request.TaskType,
|
|
|
|
|
TaskStatus = TaskStatusEnum.Create,
|
|
|
|
|
CreateBy = long.Parse(User.UserId),
|
|
|
|
|
CreateTime = DateTime.Now
|
|
|
|
|
};
|
|
|
|
|
task.NextType = GetNextType(task);
|
|
|
|
|
await TenantDb.Insertable(task).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
result = await OnTaskCreated(task);
|
|
|
|
|
if (!result.Succeeded)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
if (useTransaction)
|
|
|
|
|
await TenantDb.Ado.CommitTranAsync();
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (useTransaction)
|
|
|
|
|
await TenantDb.Ado.RollbackTranAsync();
|
|
|
|
|
|
|
|
|
|
await ex.LogAsync(Db);
|
|
|
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当任务创建时调用
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="task"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual Task<DataResult> OnTaskCreated(BusinessTask task)
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(DataResult.Success);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置任务状态
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="request"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult> SetTaskStatusAsync(TaskUpdateRequest request)
|
|
|
|
|
{
|
|
|
|
|
if (!await EnsureModuleAuthorized())
|
|
|
|
|
return DataResult.SuccessedWithDesc(nameof(MultiLanguageConst.ModuleUnauthorized));
|
|
|
|
|
|
|
|
|
|
await TenantDb.Ado.BeginTranAsync();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var result = await ManagerService.SetTaskStatus(request.BusinessId, request.TaskType, request.TaskStatus, DateTime.Now);
|
|
|
|
|
if (!result.Succeeded)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
//更新当前任务状态
|
|
|
|
|
BusinessTask task = await GetTaskAsync(request.BusinessId, request.BusinessType, request.TaskType);
|
|
|
|
|
if (task == null)
|
|
|
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
|
|
|
|
|
|
|
|
|
|
if (task.TaskStatus != request.TaskStatus)
|
|
|
|
|
await OnTaskStatusChanged(request);
|
|
|
|
|
|
|
|
|
|
task.TaskStatus = request.TaskStatus;
|
|
|
|
|
await TenantDb.Updateable(task).UpdateColumns(x => x.TaskStatus).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
if (task.TaskStatus == TaskStatusEnum.Complete)
|
|
|
|
|
{
|
|
|
|
|
//若存在下一任务,则继续创建
|
|
|
|
|
if (task.NextType.HasValue && request.AutoCreateNext)
|
|
|
|
|
{
|
|
|
|
|
var req = new TaskCreationRequest
|
|
|
|
|
{
|
|
|
|
|
BusinessId = request.BusinessId,
|
|
|
|
|
BusinessType = request.BusinessType,
|
|
|
|
|
TaskType = task.NextType.Value
|
|
|
|
|
};
|
|
|
|
|
await CreateTaskAsync(req, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await TenantDb.Ado.CommitTranAsync();
|
|
|
|
|
return DataResult.Success;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
await TenantDb.Ado.RollbackTranAsync();
|
|
|
|
|
await ex.LogAsync(Db);
|
|
|
|
|
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当任务状态发生变化时调用
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="request"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected virtual Task OnTaskStatusChanged(TaskUpdateRequest request)
|
|
|
|
|
{
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 审批完成回调更新
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="callback">回调信息</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="callback"/>为null时引发</exception>
|
|
|
|
|
public virtual async Task UpdateBusinessAsync(FlowCallback callback)
|
|
|
|
|
{
|
|
|
|
|
ArgumentNullException.ThrowIfNull(callback, nameof(callback));
|
|
|
|
|
|
|
|
|
|
//更新任务状态为完成
|
|
|
|
|
await SetTaskStatusAsync(new TaskUpdateRequest
|
|
|
|
|
{
|
|
|
|
|
BusinessId = callback.BusinessId,
|
|
|
|
|
BusinessType = callback.BusinessType.GetValueOrDefault(),
|
|
|
|
|
TaskType = TaskBaseTypeEnum.WAIT_ORDER_AUDIT,
|
|
|
|
|
TaskStatus = TaskStatusEnum.Complete
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取指定类型的业务关联任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">业务ID</param>
|
|
|
|
|
/// <param name="businessType">业务类型</param>
|
|
|
|
|
/// <param name="taskType">任务类型</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
protected internal async Task<BusinessTask> GetTaskAsync(long id, BusinessType businessType, TaskBaseTypeEnum taskType)
|
|
|
|
|
{
|
|
|
|
|
return await TenantDb.Queryable<BusinessTask>().FirstAsync(x =>
|
|
|
|
|
x.BusinessId == id && x.BusinessType == businessType && x.TaskType == taskType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取给定任务的下一任务类型
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="current">任务信息</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static TaskBaseTypeEnum? GetNextType(BusinessTask current)
|
|
|
|
|
{
|
|
|
|
|
if (current.TaskType == TaskBaseTypeEnum.WAIT_CHECKOUT_BILL) //流程的最后一步
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
int currentTypeVal = (int)current.TaskType;
|
|
|
|
|
if (currentTypeVal >= 300) //300开始的枚举值为可选服务项目,不存在前后关联性
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return (TaskBaseTypeEnum)currentTypeVal++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|