修改任务完成时获取下一任务类型的配置信息

usertest
嵇文龙 3 months ago
parent b4a315a8d7
commit 182b596719

@ -27,11 +27,6 @@ namespace DS.WMS.Core.Op.Dtos.TaskInteraction
/// </summary> /// </summary>
public string? RejectReason { get; set; } public string? RejectReason { get; set; }
/// <summary>
/// 下一任务类型
/// </summary>
public TaskBaseTypeEnum? NextType { get; set; }
/// <summary> /// <summary>
/// 下一任务配置ID /// 下一任务配置ID
/// </summary> /// </summary>

@ -42,7 +42,7 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="useTransaction">是否使用事务</param> /// <param name="useTransaction">是否使用事务</param>
/// <returns></returns> /// <returns></returns>
Task<DataResult<TaskBaseTypeEnum?>> SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true); Task<DataResult> SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true);
/// <summary> /// <summary>
/// 发起任务审核 /// 发起任务审核

@ -1,5 +1,4 @@
using System.Threading.Tasks; using DS.Module.Core;
using DS.Module.Core;
using DS.Module.Core.Data; using DS.Module.Core.Data;
using DS.Module.Core.Helpers; using DS.Module.Core.Helpers;
using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Flow.Dtos;
@ -93,9 +92,9 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// <summary> /// <summary>
/// 获取给定任务的下一任务类型 /// 获取给定任务的下一任务类型
/// </summary> /// </summary>
/// <param name="current"></param> /// <param name="current">当前任务对象</param>
/// <returns></returns> /// <returns></returns>
public async Task<TaskBaseTypeEnum?> GetNextTypeAsync(BusinessTask current) public async Task<Tuple<TaskBaseTypeEnum, long>?> GetNextTypeAsync(BusinessTask current)
{ {
var order = await ActionService.GetBusinessDataAsync(current.BusinessId, current.BusinessType); var order = await ActionService.GetBusinessDataAsync(current.BusinessId, current.BusinessType);
TaskFlowRuner flowRuner = new(TenantDb, ServiceProvider); TaskFlowRuner flowRuner = new(TenantDb, ServiceProvider);
@ -103,181 +102,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
(TaskFlowDataNameConst.Business, order) (TaskFlowDataNameConst.Business, order)
), current.NextId); ), current.NextId);
if (result.HasValue) return result.HasValue ? new Tuple<TaskBaseTypeEnum, long>(result.Value.taskType, result.Value.configId) : null;
{
current.NextId = result.Value.configId;
return result.Value.taskType;
}
return null;
}
/// <summary>
/// 获取业务的任务信息
/// </summary>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="types">任务类型</param>
/// <returns></returns>
public async Task<DataResult<List<BusinessTaskDto>>> GetTasks(long id, BusinessType businessType, params TaskBaseTypeEnum[] types)
{
var list = await TenantDb.Queryable<BusinessTask>().Where(x => x.BusinessId == id && x.BusinessType == businessType)
.WhereIF(types != null && types.Length > 0, x => types.Contains(x.TaskType))
.Select<BusinessTaskDto>().ToListAsync();
var result = DataResult<List<BusinessTaskDto>>.Success(list);
result.Count = list.Count;
return result;
}
/// <summary>
/// 返回指定类型的任务是否已存在
/// </summary>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="type">任务类型</param>
/// <returns></returns>
public async Task<DataResult<bool>> ExistsAsync(long id, BusinessType businessType, TaskBaseTypeEnum type)
{
var value = await TenantDb.Queryable<BusinessTask>().AnyAsync(x =>
x.BusinessId == id && x.BusinessType == businessType && x.TaskType == type);
return DataResult<bool>.Success(value);
}
/// <summary>
/// 确保任务交互模块已授权
/// </summary>
/// <returns></returns>
protected virtual async Task<bool> EnsureModuleAuthorized()
{
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>
/// <returns></returns>
public async Task<DataResult> SubmitAuditAsync(TaskRequest request)
{
var task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
if (task.TaskStatus == TaskStatusEnum.Pending || task.TaskStatus == TaskStatusEnum.Create)
{
await TenantDb.Ado.BeginTranAsync();
try
{
var req = new TaskUpdateRequest
{
AutoCreateNext = false,
BusinessId = request.BusinessId,
BusinessType = request.BusinessType,
TaskStatus = TaskStatusEnum.Create,
TaskTypeName = request.TaskTypeName
};
//重置任务为待处理
var result = await SetTaskStatusAsync(req, false);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
//创建&启动工作流
var result2 = await CreateAndStartWorkflow(task, false);
if (!result2.Succeeded)
return result2;
await TenantDb.Updateable<BusinessTask>().SetColumns(x => x.TaskStatus == TaskStatusEnum.Create)
.Where(x => x.BusinessId == request.BusinessId && x.BusinessType == request.BusinessType && x.TaskType == request.TaskType)
.ExecuteCommandAsync();
//记录日志
await LogService.WriteLogAsync(req, "重新审批");
await TenantDb.Ado.CommitTranAsync();
return result2;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskStatusNotSupported));
}
/// <summary>
/// 撤销审核任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> WithdrawAsync(TaskRequest request)
{
var task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).Select(x => new
{
x.Id,
x.TaskStatus
}).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
return await Delete(request.BusinessId, request.BusinessType, "用户撤销审核", request.TaskType);
}
/// <summary>
/// 任务审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(TaskAuditRequest request)
{
long id = request.Ids[0];
var task = await GetQuery(id, request.BusinessType.GetValueOrDefault(), request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
{
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
}
else if (task.TaskStatus != TaskStatusEnum.Create && task.TaskStatus != TaskStatusEnum.Pending)
{
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskAuditStatusError));
}
if (task.FlowId == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FlowNotFound));
var result = FlowService.AuditFlowInstance(new FlowAuditInfo
{
AuditNote = request.Remark,
Status = request.Result,
Instance = await Db.Queryable<FlowInstance>().FirstAsync(x => x.Id == task.FlowId.Value)
});
var flow = await Db.Queryable<FlowInstance>().Where(x => x.Id == task.FlowId.Value).Select(x => new FlowInstance
{
FlowStatus = x.FlowStatus,
MakerList = x.MakerList,
}).FirstAsync();
result.Data = new { flow.IsCompleted, flow.FlowStatus };
return result;
} }
/// <summary> /// <summary>
@ -375,13 +200,10 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
TaskType = request.TaskType, TaskType = request.TaskType,
TaskStatus = TaskStatusEnum.Create, TaskStatus = TaskStatusEnum.Create,
RecvUsers = string.Join(',', info.Main.RecvUserInfoList.Select(x => x.RecvUserId)), RecvUsers = string.Join(',', info.Main.RecvUserInfoList.Select(x => x.RecvUserId)),
NextId = request.NextId,
CreateBy = long.Parse(User.UserId), CreateBy = long.Parse(User.UserId),
CreateTime = DateTime.Now, CreateTime = DateTime.Now
NextType = request.NextType,
NextId = request.NextId
}; };
if (!task.NextType.HasValue)
task.NextType = await GetNextTypeAsync(task);
await TenantDb.Insertable(task).ExecuteCommandAsync(); await TenantDb.Insertable(task).ExecuteCommandAsync();
@ -477,10 +299,10 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="useTransaction">是否使用事务</param> /// <param name="useTransaction">是否使用事务</param>
/// <returns></returns> /// <returns></returns>
public async Task<DataResult<TaskBaseTypeEnum?>> SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true) public async Task<DataResult> SetTaskStatusAsync(TaskUpdateRequest request, bool useTransaction = true)
{ {
if (!await EnsureModuleAuthorized()) if (!await EnsureModuleAuthorized())
return DataResult<TaskBaseTypeEnum?>.SuccessMsg(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ModuleUnauthorized)), MultiLanguageConst.ModuleUnauthorized); return DataResult.SuccessedWithDesc(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ModuleUnauthorized)));
if (useTransaction) if (useTransaction)
await TenantDb.Ado.BeginTranAsync(); await TenantDb.Ado.BeginTranAsync();
@ -489,15 +311,15 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{ {
BusinessTask task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync(); BusinessTask task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync();
if (task == null) if (task == null)
return DataResult<TaskBaseTypeEnum?>.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete) if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult<TaskBaseTypeEnum?>.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted)); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
if (task.TaskStatus == TaskStatusEnum.Cancel) if (task.TaskStatus == TaskStatusEnum.Cancel)
return DataResult<TaskBaseTypeEnum?>.FailedWithDesc(nameof(MultiLanguageConst.TaskCancelled)); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCancelled));
var result = await ManagerService.SetTaskStatus(request.BusinessId, request.TaskType, request.TaskStatus, DateTime.Now); var result = await ManagerService.SetTaskStatus(request.BusinessId, request.TaskType, request.TaskStatus, DateTime.Now);
if (!result.Succeeded) if (!result.Succeeded)
return DataResult<TaskBaseTypeEnum?>.Failed(result.Message, result.MultiCode); return DataResult.Failed(result.Message, result.MultiCode);
//触发任务状态变更通知 //触发任务状态变更通知
if (task.TaskStatus != request.TaskStatus) if (task.TaskStatus != request.TaskStatus)
@ -509,27 +331,28 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (AuditTaskTypes.Contains(task.TaskType)) if (AuditTaskTypes.Contains(task.TaskType))
task.FlowId = null; task.FlowId = null;
await TenantDb.Updateable(task).UpdateColumns(x => new { x.TaskStatus, x.FlowId, x.RejectReason }).ExecuteCommandAsync(); if (task.TaskStatus == TaskStatusEnum.Complete && request.AutoCreateNext)
if (task.TaskStatus == TaskStatusEnum.Complete)
{ {
//若存在下一任务,则继续创建 var tuple = await GetNextTypeAsync(task);
if (task.NextType.HasValue && request.AutoCreateNext) if (tuple != null)
{ {
task.NextType = tuple.Item1;
var req = new TaskCreationRequest var req = new TaskCreationRequest
{ {
BusinessId = request.BusinessId, BusinessId = request.BusinessId,
BusinessType = request.BusinessType, BusinessType = request.BusinessType,
TaskTypeName = task.NextType.ToString(),
RecvUserIdList = task.RecvUserIdArray, RecvUserIdList = task.RecvUserIdArray,
NextId = task.NextId TaskTypeName = tuple.Item1.ToString(),
NextId = tuple.Item2
}; };
result = await CreateTaskAsync(req, false); result = await CreateTaskAsync(req, false);
if (!result.Succeeded) if (!result.Succeeded)
return DataResult<TaskBaseTypeEnum?>.Failed("创建下一关联任务时返回错误:" + result.Message, result.MultiCode); return DataResult.Failed("创建下一关联任务时返回错误:" + result.Message, result.MultiCode);
} }
} }
await TenantDb.Updateable(task).UpdateColumns(x => new { x.TaskStatus, x.FlowId, x.RejectReason }).ExecuteCommandAsync();
//记录日志 //记录日志
await LogService.WriteLogAsync(request); await LogService.WriteLogAsync(request);
@ -550,7 +373,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
ActionService.TriggerActionAsync(task, additionalData: dic); ActionService.TriggerActionAsync(task, additionalData: dic);
} }
return DataResult<TaskBaseTypeEnum?>.Success(task.TaskStatus == TaskStatusEnum.Complete ? await GetNextTypeAsync(task) : null); return DataResult.Success;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -558,7 +381,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
await TenantDb.Ado.RollbackTranAsync(); await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db); await ex.LogAsync(Db);
return DataResult<TaskBaseTypeEnum?>.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
} }
} }
@ -572,6 +395,174 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
return Task.CompletedTask; return Task.CompletedTask;
} }
/// <summary>
/// 获取业务的任务信息
/// </summary>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="types">任务类型</param>
/// <returns></returns>
public async Task<DataResult<List<BusinessTaskDto>>> GetTasks(long id, BusinessType businessType, params TaskBaseTypeEnum[] types)
{
var list = await TenantDb.Queryable<BusinessTask>().Where(x => x.BusinessId == id && x.BusinessType == businessType)
.WhereIF(types != null && types.Length > 0, x => types.Contains(x.TaskType))
.Select<BusinessTaskDto>().ToListAsync();
var result = DataResult<List<BusinessTaskDto>>.Success(list);
result.Count = list.Count;
return result;
}
/// <summary>
/// 返回指定类型的任务是否已存在
/// </summary>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="type">任务类型</param>
/// <returns></returns>
public async Task<DataResult<bool>> ExistsAsync(long id, BusinessType businessType, TaskBaseTypeEnum type)
{
var value = await TenantDb.Queryable<BusinessTask>().AnyAsync(x =>
x.BusinessId == id && x.BusinessType == businessType && x.TaskType == type);
return DataResult<bool>.Success(value);
}
/// <summary>
/// 确保任务交互模块已授权
/// </summary>
/// <returns></returns>
protected virtual async Task<bool> EnsureModuleAuthorized()
{
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>
/// <returns></returns>
public async Task<DataResult> SubmitAuditAsync(TaskRequest request)
{
var task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
if (task.TaskStatus == TaskStatusEnum.Pending || task.TaskStatus == TaskStatusEnum.Create)
{
await TenantDb.Ado.BeginTranAsync();
try
{
var req = new TaskUpdateRequest
{
AutoCreateNext = false,
BusinessId = request.BusinessId,
BusinessType = request.BusinessType,
TaskStatus = TaskStatusEnum.Create,
TaskTypeName = request.TaskTypeName
};
//重置任务为待处理
var result = await SetTaskStatusAsync(req, false);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
//创建&启动工作流
var result2 = await CreateAndStartWorkflow(task, false);
if (!result2.Succeeded)
return result2;
await TenantDb.Updateable<BusinessTask>().SetColumns(x => x.TaskStatus == TaskStatusEnum.Create)
.Where(x => x.BusinessId == request.BusinessId && x.BusinessType == request.BusinessType && x.TaskType == request.TaskType)
.ExecuteCommandAsync();
//记录日志
await LogService.WriteLogAsync(req, "重新审批");
await TenantDb.Ado.CommitTranAsync();
return result2;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskStatusNotSupported));
}
/// <summary>
/// 撤销审核任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> WithdrawAsync(TaskRequest request)
{
var task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).Select(x => new
{
x.Id,
x.TaskStatus
}).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
return await Delete(request.BusinessId, request.BusinessType, "用户撤销审核", request.TaskType);
}
/// <summary>
/// 任务审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(TaskAuditRequest request)
{
long id = request.Ids[0];
var task = await GetQuery(id, request.BusinessType.GetValueOrDefault(), request.TaskType).FirstAsync();
if (task == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (task.TaskStatus == TaskStatusEnum.Complete)
{
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted));
}
else if (task.TaskStatus != TaskStatusEnum.Create && task.TaskStatus != TaskStatusEnum.Pending)
{
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskAuditStatusError));
}
if (task.FlowId == null)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FlowNotFound));
var result = FlowService.AuditFlowInstance(new FlowAuditInfo
{
AuditNote = request.Remark,
Status = request.Result,
Instance = await Db.Queryable<FlowInstance>().FirstAsync(x => x.Id == task.FlowId.Value)
});
var flow = await Db.Queryable<FlowInstance>().Where(x => x.Id == task.FlowId.Value).Select(x => new FlowInstance
{
FlowStatus = x.FlowStatus,
MakerList = x.MakerList,
}).FirstAsync();
result.Data = new { flow.IsCompleted, flow.FlowStatus };
return result;
}
/// <summary> /// <summary>
/// 通知审批执行人变更 /// 通知审批执行人变更
/// </summary> /// </summary>

@ -78,10 +78,10 @@ namespace DS.WMS.OpApi.Controllers
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("SetTaskStatus")] [HttpPost, Route("SetTaskStatus")]
public async Task<DataResult<TaskBaseTypeEnum?>> SetTaskStatusAsync([FromBody] TaskUpdateRequest request) public async Task<DataResult> SetTaskStatusAsync([FromBody] TaskUpdateRequest request)
{ {
if (!ModelState.IsValid) if (!ModelState.IsValid)
return DataResult<TaskBaseTypeEnum?>.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest); return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await taskService.SetTaskStatusAsync(request); return await taskService.SetTaskStatusAsync(request);
} }

Loading…
Cancel
Save