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.

3162 lines
129 KiB
C#

5 months ago
using ce.autofac.extension;
using Infrastructure;
using Infrastructure.Extensions;
using Infrastructure.Helpers;
using Microsoft.Extensions.Configuration;
using OpenAuth.App.Base;
using OpenAuth.App.BasicQueryService;
using OpenAuth.App.Config;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.Repository;
using OpenAuth.Repository.Core;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System.Data;
using System.Linq;
using Newtonsoft.Json;
using OpenAuth.App.BaseApp.Jobs;
using System.Text;
using DocumentFormat.OpenXml.Spreadsheet;
using Infrastructure.Utilities;
using OpenAuth.App.BaseApp.Base;
using System.Diagnostics;
using NPOI.Util;
namespace OpenAuth.App
{
public partial class WFProcessApp : SqlSugarBaseApp<WFProcess, SugarDbContext>
{
ISqlSugarClient client;
UserManager userManager;
PositionManager positionManager;
IConfiguration _configuration;
OpenJobApp _job;
public WFProcessApp(SqlSugar.ISugarUnitOfWork<SugarDbContext> unitWork,
SqlSugar.ISimpleClient<WFProcess> repository,
IAuth auth,
UserManager userManager,
OpenJobApp job,
PositionManager positionManager,
IConfiguration _configuration
) : base(unitWork, repository, auth)
{
client = base.Repository.AsSugarClient();
this.userManager = userManager;
this.positionManager = positionManager;
this._configuration = _configuration;
_job = job;
}
#region 获取数据
/// <summary>
/// 获取流程列表
/// </summary>
/// <param name="pagination">分页参数</param>
/// <param name="searchParams">查询参数</param>
/// <returns></returns>
public async Task<PageInfo<List<WFProcess>>> GetPageList(PageReq pageReq, WFProcessSearchDto searchParams)
{
RefAsync<int> totalCount = 0;
var exp = Expressionable.Create<WFProcess>()
.AndIF(!string.IsNullOrEmpty(searchParams.Keyword), t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword))
.AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.SchemeCode == searchParams.Code)
.AndIF(searchParams.StartDate != null && searchParams.EndDate != null, t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate);
if (searchParams.Type == 3)
{
exp = exp.And(t => t.EnabledMark == 3);
}
else
{
exp = exp.And(t => t.EnabledMark == 1);
if (searchParams.Type == 1)
{
exp = exp.And(t => t.IsFinished == 1);
}
else
{
exp = exp.And(t => t.IsFinished == 0);
}
}
var list = await client.Queryable<WFProcess>()
.Where(exp.ToExpression())
.OrderByDescending(t => t.CreateDate)
.ToPageListAsync(pageReq.page, pageReq.limit, totalCount);
return new PageInfo<List<WFProcess>>
{
Items = list,
Total = totalCount
};
}
/// <summary>
/// 获取我的流程
/// </summary>
/// <param name="pagination">分页参数</param>
/// <param name="searchParams">查询参数</param>
/// <param name="type"> 1正常2草稿3作废</param>
/// <returns></returns>
public async Task<PageInfo<List<WFProcess>>> GetMyPageList(PageReq pageReq, WFProcessSearchDto searchParams, int type)
{
RefAsync<int> totalCount = 0;
var userId = _auth.GetUserId();
var expression = Expressionable.Create<WFProcess>();
expression = expression.And(t => t.CreateUserId == userId || t.UserId == userId);
if (type == 2)
{
expression = expression.And(t => t.EnabledMark == 2);
}
else
{
expression = expression.And(t => t.EnabledMark != 2);
}
if (!string.IsNullOrEmpty(searchParams.Keyword))
{
expression = expression.And(t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword));
}
if (!string.IsNullOrEmpty(searchParams.Code))
{
expression = expression.And(t => t.SchemeCode == searchParams.Code);
}
if (searchParams.StartDate != null && searchParams.EndDate != null)
{
expression = expression.And(t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate);
}
var list = await client.Queryable<WFProcess>()
.Where(expression.ToExpression())
.OrderByDescending(t => t.CreateDate)
.ToPageListAsync(pageReq.page, pageReq.limit, totalCount);
return new PageInfo<List<WFProcess>>
{
Items = list,
Total = totalCount
};
}
/// <summary>
/// 获取流程进程实体
/// </summary>
/// <param name="keyValue">主键</param>
/// <returns></returns>
public async Task<WFProcess> GetEntity(string keyValue)
{
return await base.Repository.GetByIdAsync(keyValue);
}
#endregion
#region 保存更新删除
/// <summary>
/// 删除流程进程实体
/// </summary>
/// <param name="processId">流程进程主键</param>
public async Task<bool> DeleteEntity(string processId)
{
return await base.Repository.DeleteByIdAsync(processId);
}
#endregion
#region 流程API
/// <summary>
/// 保存草稿
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <param name="schemeCode">流程模板编码</param>
/// <param name="userId">创建人</param>
/// <param name="parentProcessId">父级流程进程主键</param>
/// <param name="parentNodeId">父级流程节点Id</param>
/// <param name="parentTaskId">父级任务id</param>
/// <param name="isChild">是否为子流程</param>
/// <param name="title">流程标题</param>
/// <returns></returns>
public async Task<Response<bool>> SaveDraft(string processId, string schemeCode, string userId, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "")
{
var flag = false;
var currentUser = _auth.GetCurrentUser().User;
// 判断当前流程进程是否有保存过
var processEntity = await GetEntity(processId);
if (processEntity == null)
{
// 创建草稿,已经存在不做处理
var schemeInfo = await client.Queryable<WFSchemeInfo>().FirstAsync(a => a.Code == schemeCode);
WFProcess wfProcessEntity = new WFProcess()
{
Id = processId,
SchemeCode = schemeCode,
SchemeId = schemeInfo.SchemeId,
SchemeName = schemeInfo.Name,
Title = title,
InstanceInfo = JsonConvert.DeserializeObject<WFInstanceInfo>(instanceInfo),
EnabledMark = 2,
IsAgain = 0,
IsFinished = 0,
IsChild = isChild,
IsStart = 0,
ParentNodeId = parentNodeId,
ParentProcessId = parentProcessId,
ParentTaskId = parentTaskId,
CreateUserId = currentUser.Id.ToString(),
CreateUserName = currentUser.Name,
CreateUserAccount = currentUser.Account,
UserId = currentUser.Id.ToString()
};
if (string.IsNullOrEmpty(title))
{
wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name;
}
wfProcessEntity.CreateDate = DateTime.Now;
wfProcessEntity.UserId = currentUser.Id.ToString();
flag = await base.Repository.InsertAsync(wfProcessEntity);
}
else if (!string.IsNullOrEmpty(title) && processEntity.Title != title)
{
processEntity.Title = title;
flag = await base.Repository.UpdateAsync(processEntity);
}
else
{
flag = true;
}
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
/// <summary>
/// 保存草稿-新版用户查询
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <param name="schemeCode">流程模板编码</param>
/// <param name="userId">创建人</param>
/// <param name="parentProcessId">父级流程进程主键</param>
/// <param name="parentNodeId">父级流程节点Id</param>
/// <param name="parentTaskId">父级任务id</param>
/// <param name="isChild">是否为子流程</param>
/// <param name="title">流程标题</param>
/// <returns></returns>
public async Task<Response<bool>> SaveDraftWithUser(string processId, string schemeCode, string userName, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "")
{
var flag = false;
var currentUser = await client.Queryable<SysUser>().FirstAsync(r => r.Name == userName)
?? new SysUser
{
Id = -1,
Account = Define.SYSTEM_USERNAME,
Name = "超级管理员",
};
// 判断当前流程进程是否有保存过
var processEntity = await GetEntity(processId);
if (processEntity == null)
{
// 创建草稿,已经存在不做处理
var schemeInfo = await client.Queryable<WFSchemeInfo>().FirstAsync(a => a.Code == schemeCode);
WFProcess wfProcessEntity = new WFProcess()
{
Id = processId,
SchemeCode = schemeCode,
SchemeId = schemeInfo.SchemeId,
SchemeName = schemeInfo.Name,
Title = title,
InstanceInfo = JsonConvert.DeserializeObject<WFInstanceInfo>(instanceInfo),
EnabledMark = 2,
IsAgain = 0,
IsFinished = 0,
IsChild = isChild,
IsStart = 0,
ParentNodeId = parentNodeId,
ParentProcessId = parentProcessId,
ParentTaskId = parentTaskId,
CreateUserId = currentUser?.Id.ToString(),
CreateUserName = currentUser?.Name,
CreateUserAccount = currentUser?.Account,
UserId = currentUser?.Id.ToString()
};
if (string.IsNullOrEmpty(title))
{
wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name;
}
wfProcessEntity.CreateDate = DateTime.Now;
wfProcessEntity.UserId = currentUser.Id.ToString();
flag = await base.Repository.InsertAsync(wfProcessEntity);
}
else if (!string.IsNullOrEmpty(title) && processEntity.Title != title)
{
processEntity.Title = title;
flag = await base.Repository.UpdateAsync(processEntity);
}
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
/// <summary>
/// 删除草稿
/// </summary>
/// <param name="processId">流程进程主键</param>
public async Task<Response<bool>> DeleteDraft(string processId)
{
var flag = false;
var response = new Response<bool>();
var iWFEngine = await Bootstraper(string.Empty, processId, null);
var scriptResult = await ExecuteScript(processId, "deleteDraft", iWFEngine.CreateUser,
iWFEngine.WFScheme.DeleteDraftType,
iWFEngine.WFScheme.DeleteDraftDbCode,
iWFEngine.WFScheme.DeleteDraftDbSQL,
iWFEngine.WFScheme.DeleteDraftUrl,
iWFEngine.WFScheme.DeleteDraftIOCName);
if (scriptResult)
{
flag = await DeleteEntity(processId);
if (flag)
{
response.Result = true;
response.Message = "success";
}
else
{
response.Result = false;
response.Message = "脚本执行成功,但流程信息删除失败";
}
}
else
{
response.Result = false;
response.Message = "error";
}
return response;
}
/// <summary>
/// 创建流程
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <param name="schemeCode">流程模板编码</param>
/// <param name="userId">创建人</param>
/// <param name="nextUsers">下一个节点审核人</param>
/// <param name="title">流程标题</param>
/// <returns></returns>
public async Task<Response<bool>> Create(string processId, string schemeCode, string userId, Dictionary<string, string> nextUsers, string InstanceInfo, string title = "")
{
var flag = false;
var userInfo = await GetUserInfo(userId);
var iWFEngine = await Bootstraper(schemeCode, processId, userInfo, nextUsers);
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id);
//获取当前流程信息
var process = await GetEntity(processId);
// 处理任务并更新数据
List<WFTask> myTaskList;
using (var uwo = UnitWork.CreateContext())
{
var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title);
processEntity.InstanceInfo = JsonConvert.DeserializeObject<WFInstanceInfo>(InstanceInfo);
if (string.IsNullOrEmpty(processEntity.Title))
{
processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName;
}
processEntity.CreateDate = DateTime.Now;
if (taskList.FindIndex(t => t.Type == 100) != -1)
{
processEntity.IsFinished = 1;
if (process != null && process.IsChild == 1)
{
WFTask ts = new WFTask();
await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, "");
}
}
if (process != null && process.IsChild == 1)
{
var taskEntity = await client.Queryable<WFTask>().Where(a => a.Id == process.ParentTaskId).FirstAsync();
if (taskEntity != null)
{
taskEntity.State = 3;
if (taskEntity.Type == 7)
{
var currentUser = _auth.GetCurrentUser().User;
taskEntity.UserId = currentUser.Id.ToString();
taskEntity.UserName = currentUser.Name;
}
await uwo.WFTask.UpdateAsync(taskEntity);
}
}
if (!string.IsNullOrEmpty(schemeCode))
{
await uwo.WFProcess.InsertAsync(processEntity);
}
else
{
await uwo.WFProcess.UpdateAsync(processEntity);
}
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create");
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
item.ProcessTitle = processEntity.Title;
await Add(item);
}
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
OperationCode = "create",
OperationName = "提交流程",
TaskType = 0,
IsLast = 1,
Des = "提交流程",
ProcessId = processId,
UnitId = iWFEngine.StartNode.Id,
UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name
};
await AddLog(wfTaskLogEntity);
flag = uwo.Commit();
}
var respone = new Response<bool>();
if (flag)
{
var scriptResults = new List<bool>();
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null,"");
scriptResults.Add(result);
}
if (scriptResults.Contains(false))
{
respone.Result = false;
respone.Message = "流程信息存储成功,但脚本执行失败";
}
else
{
respone.Result = true;
respone.Message = "success";
}
}
else
{
respone.Result = false;
respone.Message = "error";
}
return respone;
}
/// <summary>
/// 创建流程
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <param name="schemeCode">流程模板编码</param>
/// <param name="userId">创建人</param>
/// <param name="nextUsers">下一个节点审核人</param>
/// <param name="title">流程标题</param>
/// <returns></returns>
public async Task<Response<bool>> CreateWithUser(string processId, string schemeCode, string userName, Dictionary<string, string> nextUsers, string InstanceInfo, string title = "")
{
var flag = false;
//var userInfo = await client.Queryable<SysUser>().FirstAsync(r => r.Name == userName);
var userInfo = await client.Queryable<SysUser>().FirstAsync(r => r.Name == userName)
?? new SysUser
{
Id = -1,
Account = Define.SYSTEM_USERNAME,
Name = "超级管理员",
};
var iWFEngine = await BootstraperWithUser(schemeCode, processId, userInfo, nextUsers);
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id);
//获取当前流程信息
var process = await GetEntity(processId);
// 处理任务并更新数据
List<WFTask> myTaskList;
using (var uwo = UnitWork.CreateContext())
{
var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title);
processEntity.InstanceInfo = JsonConvert.DeserializeObject<WFInstanceInfo>(InstanceInfo);
if (string.IsNullOrEmpty(processEntity.Title))
{
processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName;
}
processEntity.CreateDate = DateTime.Now;
if (taskList.FindIndex(t => t.Type == 100) != -1)
{
processEntity.IsFinished = 1;
if (process != null && process.IsChild == 1)
{
WFTask ts = new WFTask();
await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, "");
}
}
if (process != null && process.IsChild == 1)
{
var taskEntity = await client.Queryable<WFTask>().Where(a => a.Id == process.ParentTaskId).FirstAsync();
if (taskEntity != null)
{
taskEntity.State = 3;
if (taskEntity.Type == 7)
{
var currentUser = _auth.GetCurrentUser().User;
taskEntity.UserId = currentUser.Id.ToString();
taskEntity.UserName = currentUser.Name;
}
await uwo.WFTask.UpdateAsync(taskEntity);
}
}
if (!string.IsNullOrEmpty(schemeCode))
{
await uwo.WFProcess.InsertAsync(processEntity);
}
else
{
await uwo.WFProcess.UpdateAsync(processEntity);
}
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create");
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
item.ProcessTitle = processEntity.Title;
await Add(item);
}
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
OperationCode = "create",
OperationName = "提交流程",
TaskType = 0,
IsLast = 1,
Des = "提交流程",
ProcessId = processId,
UnitId = iWFEngine.StartNode.Id,
UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name
};
await AddLog(wfTaskLogEntity);
flag = uwo.Commit();
}
var respone = new Response<bool>();
if (flag)
{
var scriptResults = new List<bool>();
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, "");
scriptResults.Add(result);
}
if (scriptResults.Contains(false))
{
respone.Result = false;
respone.Message = "流程信息存储成功,但脚本执行失败";
}
else
{
respone.Result = true;
respone.Message = "success";
}
}
else
{
respone.Result = false;
respone.Message = "error";
}
return respone;
}
/// <summary>
/// 重新创建流程
/// </summary>
/// <param name="processId">流程实例主键</param>
/// <param name="des">备注</param>
/// <returns></returns>
public async Task<Response<bool>> CreateAgain(string processId, string des)
{
var flag = false;
var iWFEngine = await Bootstraper("", processId, null, null);
var unList = (List<WFTask>)await GetUnFinishTaskList(processId);
var taskEntity = unList.Find(t => t.State == 1 && t.UnitId == iWFEngine.StartNode.Id);
if (taskEntity == null)
{
throw (new Exception("找不到重新提交流程任务!"));
}
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id);
// 处理任务并更新数据
List<WFTask> myTaskList;
using (var uwo = UnitWork.CreateContext())
{
await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess() { IsCancel = 1, IsAgain = 0 }, a => a.Id == processId);
await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask() { State = 3 }, a => a.Id == taskEntity.Id);
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId);
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id);
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
await Add(item);
}
await CreateTaskLog(taskEntity, "", "重新提交", des, "");
//await _imMsgIBLL.VirtualDeleteByContentId(taskEntity.Token); // 更新消息
flag = uwo.Commit();
}
var respone = new Response<bool>();
if (flag)
{
var scriptResults = new List<bool>();
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
var result = await ExecuteScript(item, "createAgain", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, "");
scriptResults.Add(result);
}
if (scriptResults.Contains(false))
{
respone.Result = false;
respone.Message = "流程信息存储成功,但脚本执行失败";
}
else
{
respone.Result = true;
respone.Message = "success";
}
}
else
{
respone.Result = false;
respone.Message = "error";
}
return respone;
}
/// <summary>
/// 撤销流程(只有在该流程未被处理的情况下)
/// </summary>
/// <param name="processId">流程进程主键</param>
public async Task<bool> RevokeFlow(string processId)
{
var iWFEngine = await Bootstraper(string.Empty, processId, null, null);
if (iWFEngine.Config.Params.IsStart != 1)
{
// 获取脚本任务
var scriptList = (List<WFTask>)await GetList(processId, 10, "create");
foreach (var item in scriptList)
{
await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine);
}
using (var uwo = UnitWork.CreateContext())
{
await uwo.WFTask.DeleteAsync(a => a.ProcessId == processId);
await uwo.WFTaskLog.DeleteAsync(a => a.ProcessId == processId);
await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 2 }, a => a.Id == processId);
uwo.Commit();
}
await ExecuteScript(processId, "RevokeFlow", iWFEngine.CreateUser,
iWFEngine.WFScheme.UndoType,
iWFEngine.WFScheme.UndoDbCode,
iWFEngine.WFScheme.UndoDbSQL,
iWFEngine.WFScheme.UndoUrl,
iWFEngine.WFScheme.UndoIOCName);
return true;
}
return false;
}
/// <summary>
/// 催办流程
/// </summary>
/// <param name="processId">流程进程主键</param>
public async Task<Response<bool>> UrgeFlow(string processId)
{
// var userInfo = await this.CurrentUser();
var iWFEngine = await Bootstraper(string.Empty, processId, null, null);
// 获取未完成的任务
var taskList = await GetUnFinishTaskList(processId);
using (var uwo = UnitWork.CreateContext())
{
foreach (var item in taskList)
{
if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7)
{
item.IsUrge = 1;
item.UrgeTime = DateTime.Now;
// 发送消息
var msg = $"【审核】【催办】{item.ProcessTitle},{item.UnitName}";
var userList = new List<string>();
// todo 单体任务处理
userList.Add(item.UserId);
var node = iWFEngine.GetNode(item.UnitId);
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token);
await uwo.WFTask.UpdateAsync(item);
}
}
//await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId });
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = "催办审核",
TaskType = 98,
ProcessId = processId,
UnitId = iWFEngine.StartNode.Id,
UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name
};
wfTaskLogEntity.CreateDate = DateTime.Now;
wfTaskLogEntity.UserId = _auth.GetUserId();
wfTaskLogEntity.UserName = _auth.GetUserNickName();
wfTaskLogEntity.Id = Guid.NewGuid().ToString();
await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
/// <summary>
/// 审批流程
/// </summary>
/// <param name="taskId">流程任务主键</param>
/// <param name="code">流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时</param>
/// <param name="name">流程审批操名称</param>
/// <param name="des">审批意见</param>
/// <param name="nextUsers">下一节点指定审核人</param>
/// <param name="stampImg">盖章图片</param>
/// <param name="stampPassWord">盖章图片密码</param>
/// <param name="nextId">下一个审核节点</param>
public async Task AuditFlow(string taskId, string code, string name, string des, Dictionary<string, string> nextUsers, string stampImg, string stampPassWord, string nextId)
{
var taskEntiy = await client.Queryable<WFTask>().Where(a => a.Id == taskId).FirstAsync();
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State != 1)
{
if (taskEntiy.State == 3 || taskEntiy.State == 4)
{
throw (new Exception("该任务已完成!"));
}
else
{
throw (new Exception("该任务未被激活!"));
}
}
//后期改
stampImg = "";
//stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord);
var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers);
// 1.判断任务类型 1 普通任务 5 会签任务
if (taskEntiy.Type == 1||taskEntiy.Type==7)
{
await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId);
}
else if (taskEntiy.Type == 5)
{
await AuditNodeByCountersign(iWFEngine, taskEntiy, code, name, des, stampImg);
}
else
{
throw (new Exception("该任务无法审核!"));
}
//await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息
// 发送消息
var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被处理";
var userList = new List<string>();
userList.Add(iWFEngine.CreateUser.Id);
var node = iWFEngine.StartNode;
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId);
}
/// <summary>
/// 批量审核(只有同意和不同意)
/// </summary>
/// <param name="code">操作码</param>
/// <param name="taskIdList">任务id串</param>
public async Task AuditFlows(string code, List<string> taskIdList)
{
foreach (var taskId in taskIdList)
{
string operationName = code == "agree" ? "同意" : "不同意";
await AuditFlow(taskId, code, operationName, "批量审核", null, "", "", "");
}
}
/// <summary>
/// 撤销审核
/// </summary>
/// <param name="processId"></param>
/// <param name="taskId">流程任务主键</param>
/// <returns></returns>
public async Task<Response<bool>> RevokeAudit(string processId, string taskId)
{
var iWFEngine = await Bootstraper(string.Empty, processId, null, null);
WFTask taskEntity;
WFProcess processEntity;
if (string.IsNullOrEmpty(taskId))
{ //撤销重新提交任务
processEntity = await GetEntity(processId);
if (processEntity.IsCancel != 1)
{
throw (new Exception("当前流程无法撤销!"));
}
var myTaskList = (List<WFTask>)await GetLastTaskList(processId, iWFEngine.StartNode.Id);
taskEntity = myTaskList[0];
processEntity.IsAgain = 1;
processEntity.IsCancel = 0;
}
else
{
taskEntity = await client.Queryable<WFTask>().Where(a => a.Id == taskId).FirstAsync();
if (taskEntity.State == 1)
{
throw (new Exception("当前任务无法撤销!"));
}
var taskLogEntity = await GetLogEntity(taskId);
if (taskLogEntity == null || taskLogEntity.IsCancel != 1)
{
throw (new Exception("当前任务无法撤销!"));
}
processEntity = new WFProcess()
{
Id = processId
};
processEntity.IsFinished = 0;
processEntity.IsAgain = 0;
}
using (var uwo = UnitWork.CreateContext())
{
// 获取脚本任务
var scriptList = await GetList(processId, 10, taskEntity.Id);
foreach (var item in scriptList)
{
await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine);
// 删除脚本任务执行日志
await DeleteLogByTaskId(item.Id);
}
// 删除所有生成的任务
await Delete(processId, taskEntity.Id);
// 如果是加签审核的,关闭最早的任务
if (taskEntity.Type == 6)
{
var myTaskEntiy = await GetTaskEntity(taskEntity.FirstId); // 原始审核任务
myTaskEntiy.State = 5;
await uwo.WFTask.UpdateAsync(myTaskEntiy);
}
// 如果是撤销转移任务
if (taskEntity.State == 6)
{
// 删除转移任务
await DeleteByFirstId(taskEntity.Id);
}
// 删除所有生成的日志
await DeleteLog(processId, taskEntity.Id);
// 更新等待任务状态
await OpenTask(processId, taskEntity.UnitId, 21, taskEntity.Id);
taskEntity.State = 1;
await uwo.WFTask.UpdateAsync(taskEntity);
await uwo.Db.Updateable(processEntity)
.IgnoreColumns(ignoreAllNullColumns: true)
.ExecuteCommandAsync();
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
/// <summary>
/// 流程加签
/// </summary>
/// <param name="taskId">流程任务主键</param>
/// <param name="userId">加签人员</param>
/// <param name="des">加签说明</param>
public async Task<Response<bool>> SignFlow(string taskId, string userId, string des)
{
var taskEntiy = await GetTaskEntity(taskId);
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State != 1)
{
if (taskEntiy.State == 3 || taskEntiy.State == 4)
{
throw (new Exception("该任务已完成!"));
}
else
{
throw (new Exception("该任务未被激活!"));
}
}
using (var uwo = UnitWork.CreateContext())
{
// 更新任务状态
taskEntiy.State = 5;
await uwo.WFTask.UpdateAsync(taskEntiy);
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId);
// 填写日志
await CreateTaskLog(taskEntiy, "sign", "加签", des, "");
if (taskEntiy.Type != 6)
{
taskEntiy.FirstId = taskEntiy.Id;
}
var userInfo = await uwo.User.GetByIdAsync(userId);
// 添加加签任务
taskEntiy.PrevTaskId = taskEntiy.Id;
//taskEntiy.UserCompanyId = userInfo.CompanyId;
//taskEntiy.UserDepartmentId = userInfo.DepartmentId;
taskEntiy.UserId = userInfo.Id.ToString();
taskEntiy.UserName = userInfo.Name;
taskEntiy.Type = 6;
taskEntiy.State = 1;
await uwo.WFTask.InsertAsync(taskEntiy);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
/// <summary>
/// 流程加签审核
/// </summary>
/// <param name="taskId">流程任务主键</param>
/// <param name="code">操作码</param>
/// <param name="name">流程审批操名称</param>
/// <param name="des">审批意见</param>
/// <returns></returns>
public async Task<Response<bool>> SignAudit(string taskId, string code, string name, string des)
{
var taskEntiy = await GetTaskEntity(taskId);
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State != 1)
{
if (taskEntiy.State == 3 || taskEntiy.State == 4)
{
throw (new Exception("该任务已完成!"));
}
else
{
throw (new Exception("该任务未被激活!"));
}
}
using (var uwo = UnitWork.CreateContext())
{
var myTaskEntiy = await GetTaskEntity(taskEntiy.FirstId); // 原始审核任务
myTaskEntiy.IsLast = 0;
await uwo.WFTask.UpdateAsync(myTaskEntiy);
myTaskEntiy.State = 1;
myTaskEntiy.IsLast = 1;
await Add(myTaskEntiy);
// 更新任务状态
taskEntiy.State = 3;
if (taskEntiy.Type == 7)
{
var currentUser = _auth.GetCurrentUser().User;
taskEntiy.UserId = currentUser.Id.ToString();
taskEntiy.UserName = currentUser.Name;
}
await uwo.WFTask.UpdateAsync(taskEntiy);
// 填写日志
await CreateTaskLog(taskEntiy, code, name, des, "");
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
/// <summary>
/// 确认阅读
/// </summary>
/// <param name="taskId">流程任务主键</param>
public async Task<Response<bool>> ReadFlow(string taskId)
{
var taskEntiy = await GetTaskEntity(taskId);
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State == 1)
{
using (var uwo = UnitWork.CreateContext())
{
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
TaskType = taskEntiy.Type,
ProcessId = taskEntiy.ProcessId,
UnitId = taskEntiy.UnitId,
UnitName = taskEntiy.UnitName,
IsAgree = taskEntiy.IsAgree,
OperationCode = "read",
OperationName = "已阅",
Token = taskEntiy.Token,
PrevUnitId = taskEntiy.PrevUnitId,
PrevUnitName = taskEntiy.PrevUnitName,
TaskId = taskEntiy.Id,
IsCancel = 0
};
await AddLog(wfTaskLogEntity);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
else
{
return new Response<bool>
{
Result = false,
Message = "error"
};
}
}
/// <summary>
/// 转移流程
/// </summary>
/// <param name="taskId">任务id</param>
/// <param name="userId">转移人用户id</param>
/// <param name="des">说明</param>
/// <returns></returns>
public async Task<Response<bool>> TransferUser(string taskId, string userId, string des)
{
var taskEntiy = await GetTaskEntity(taskId);
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State == 1)
{
using (var uwo = UnitWork.CreateContext())
{
var userInfo = await uwo.User.GetByIdAsync(userId);
// 更新任务状态
taskEntiy.State = 6;
await uwo.WFTask.UpdateAsync(taskEntiy);
// 更新流程
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
// 填写日志
await CreateTaskLog(taskEntiy, "transfer", "转移", des, "");
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId);
// 新建任务
var newTask = taskEntiy; //.ToJson().ToObject<WFTaskEntity>();
newTask.State = 1;
newTask.PrevTaskId = taskEntiy.Id;
//newTask.UserCompanyId = userInfo.F_CompanyId;
//newTask.UserDepartmentId = userInfo.F_DepartmentId;
newTask.UserId = userInfo.Id.ToString();
newTask.UserName = userInfo.Name;
await uwo.WFTask.InsertAsync(newTask);
// 发送消息
var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null);
var msg = $"【审核】{taskEntiy.ProcessTitle},{taskEntiy.UnitName}";
var userList = new List<string>();
userList.Add(userInfo.Id.ToString());
var node = iWFEngine.GetNode(taskEntiy.UnitId);
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, newTask.F_Token);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
else
{
return new Response<bool>
{
Result = false,
Message = "error"
};
}
}
/// <summary>
/// 获取下一节点审核人
/// </summary>
/// <param name="code">流程模板编码</param>
/// <param name="processId">流程进程主键</param>
/// <param name="nodeId">流程节点Id</param>
/// <param name="operationCode">流程操作代码</param>
/// <param name="userId">创建人</param>
/// <returns></returns>
public async Task<Dictionary<string, List<WFUserInfo>>> GetNextAuditors(string code, string processId, string nodeId, string operationCode, string userId)
{
Dictionary<string, List<WFUserInfo>> res = new Dictionary<string, List<WFUserInfo>>();
var userInfo = await client.Queryable<SysUser>().Where(a => a.Id.ToString() == userId).FirstAsync();
var iWFEngine = await Bootstraper(code, processId, userInfo);
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(nodeId, operationCode);
foreach (var item in taskList)
{
if ((item.Type == 1 || item.Type == 3 || item.Type == 5||item.Type==7) && item.User.IsNew)
{
if (!res.ContainsKey(item.UnitId))
{
res.Add(item.UnitId, new List<WFUserInfo>());
}
res[item.UnitId].Add(item.User);
}
}
return res;
}
/// <summary>
/// 作废流程
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <returns></returns>
public async Task<Response<bool>> DeleteProcess(string processId)
{
var flag = false;
var iWFEngine = await Bootstraper(string.Empty, processId, null);
using (var uwo = UnitWork.CreateContext())
{
// 更新流程状态
WFProcess processEntity = new WFProcess()
{
Id = processId,
};
await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 3 }, a => a.Id == processId);
await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 7 }, a => a.ProcessId == processId && a.State == 1);
flag = uwo.Commit();
}
var response = new Response<bool>();
if (flag)
{
var scriptResult = await ExecuteScript(processId, "delete", iWFEngine.CreateUser,
iWFEngine.WFScheme.DeleteType,
iWFEngine.WFScheme.DeleteDbCode,
iWFEngine.WFScheme.DeleteDbSQL,
iWFEngine.WFScheme.DeleteUrl,
iWFEngine.WFScheme.DeleteIOCName);
if (scriptResult)
{
response.Result = true;
response.Message = "success";
}
else
{
response.Result = false;
response.Message = "流程状态更新成功,但脚本执行失败";
}
}
else
{
response.Result = false;
response.Message = "error";
}
return response;
}
/// <summary>
/// 流程还原
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <returns></returns>
public async Task<Response<bool>> RecoverProcess(string processId)
{
var flag = false;
var iWFEngine = await Bootstraper(string.Empty, processId, null);
using (var uwo = UnitWork.CreateContext())
{
// 更新流程状态
WFProcess processEntity = new WFProcess()
{
Id = processId,
};
await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 1 }, a => a.Id == processId);
await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 1 }, a => a.ProcessId == processId && a.State == 7);
flag = uwo.Commit();
}
var response = new Response<bool>();
if (flag)
{
response.Result = true;
response.Message = "success";
}
else {
response.Result = false;
response.Message = "error";
}
return response;
}
/// <summary>
/// 指派流程审核人
/// </summary>
/// <param name="processId">流程进程主键</param>
/// <param name="pointList">流程指派人信息</param>
/// <returns></returns>
public async Task<Response<bool>> PointUser(string processId, List<WFProcessPoint> pointList)
{
var list = await GetUnFinishTaskList(processId);
Dictionary<string, List<WFTask>> map = new Dictionary<string, List<WFTask>>();
foreach (var item in list)
{
if (!map.ContainsKey(item.UnitId))
{
map.Add(item.UnitId, new List<WFTask>());
}
map[item.UnitId].Add(item);
}
var addList = new List<WFTask>();
var iWFEngine = await Bootstraper("", processId, null);
using (var uwo = UnitWork.CreateContext())
{
foreach (var item in pointList)
{
if (map.ContainsKey(item.UnitId))
{
await CloseTask(processId, map[item.UnitId][0].Token, "");
var userIdList = item.UserIds.Split(",");
foreach (var userId in userIdList)
{
var addItem = Newtonsoft.Json.JsonConvert.SerializeObject(map[item.UnitId][0]).ToObject<WFTask>();
addItem.State = 1;
if (addItem.Type == 6)
{
addItem.Type = 1;
}
var userEntity = _auth.GetCurrentUser().User;
addItem.UserId = userId;
addItem.UserName = userEntity.Name;
//addItem.UserCompanyId = userEntity.F_CompanyId;
//addItem.UserDepartmentId = userEntity.F_DepartmentId;
// 发送消息
var msg = $"【审核】{addItem.ProcessTitle},{addItem.UnitName}";
var userList = new List<string>();
userList.Add(userId);
var node = iWFEngine.GetNode(addItem.UnitId);
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, addItem.F_Token);
addList.Add(addItem);
}
}
else
{
throw (new Exception("找不到指派任务节点!"));
}
}
foreach (var item in addList)
{
await Add(item);
}
var flag = uwo.Commit();
return new Response<bool>()
{
Result = flag,
Message = flag == true ? "success" : "error"
};
}
}
#endregion
#region
/// <summary>
/// 流程模板初始化
/// </summary>
/// <param name="code">流程模板</param>
/// <param name="processId">流程实例</param>
/// <param name="userInfo">提交人用户信息</param>
/// <param name="nextUsers">下一个节点审核人</param>
/// <returns></returns>
private async Task<IWFEngine> Bootstraper(string code, string processId, SysUser userInfo, Dictionary<string, string> nextUsers = null)
{
WFEngineConfig wfEngineConfig = new WFEngineConfig();
WFParams wfParams = new WFParams();
wfEngineConfig.Params = wfParams;
var currentUser = _auth.GetCurrentUser().User;
wfParams.CurrentUser = new WFUserInfo()
{
Id = currentUser.Id.ToString(),
Account = currentUser.Account,
Name = currentUser.Name
//CompanyId = currentUser.F_CompanyId,
//DepartmentId = currentUser.F_DepartmentId
};
if (!string.IsNullOrEmpty(code))
{
var schemeInfo = await client.Queryable<WFSchemeInfo>().FirstAsync(a => a.Code == code);
if (schemeInfo != null)
{
var data = await client.Queryable<WFScheme>().FirstAsync(a => a.Id == schemeInfo.SchemeId);
if (data != null)
{
wfParams.Scheme = data.Content;
wfParams.SchemeCode = code;
wfParams.SchemeId = schemeInfo.SchemeId;
wfParams.SchemeName = schemeInfo.Name;
wfParams.ProcessId = processId;
wfParams.HasInstance = false;
wfParams.CreateUser = new WFUserInfo()
{
Id = userInfo.Id.ToString(),
Account = userInfo.Account,
Name = userInfo.Name
//CompanyId = userInfo.F_CompanyId,
//DepartmentId = userInfo.F_DepartmentId
};
}
else
{
throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code));
}
}
else
{
throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code));
}
}
else if (!string.IsNullOrEmpty(processId))
{
var processEntity = await GetEntity(processId);
if (processEntity != null)
{
var data = await client.Queryable<WFScheme>().FirstAsync(a => a.Id == processEntity.SchemeId);
if (data != null)
{
wfParams.Scheme = data.Content;
wfParams.SchemeCode = processEntity.SchemeCode;
wfParams.SchemeId = processEntity.SchemeId;
wfParams.SchemeName = processEntity.SchemeName;
wfParams.IsChild = processEntity.IsChild == 1;
wfParams.ParentProcessId = processEntity.ParentProcessId;
wfParams.ParentTaskId = processEntity.ParentTaskId;
wfParams.ParentNodeId = processEntity.ParentNodeId;
wfParams.ProcessId = processId;
wfParams.HasInstance = true;
wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0;
wfParams.Title = processEntity.Title;
wfParams.CreateUser = new WFUserInfo()
{
Id = processEntity.CreateUserId,
Account = processEntity.CreateUserAccount,
Name = processEntity.CreateUserName,
CompanyId = processEntity.CreateUserCompanyId,
DepartmentId = processEntity.CreateUserDepartmentId
};
}
else
{
throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId));
}
}
else if (string.IsNullOrEmpty(wfParams.Scheme))
{
throw new Exception(string.Format("无法获取实例数据【{0}】", processId));
}
}
wfParams.NextUsers = nextUsers;
// 注册委托方法
wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList;
wfEngineConfig.GetUserList = GetUserList;
wfEngineConfig.GetSystemUserList = GetSystemUserList;
wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList;
wfEngineConfig.IsCountersignAgree = IsCountersignAgree;
wfEngineConfig.GetPrevUnitId = GetPrevUnitId;
IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client);
return iwfEngine;
}
/// <summary>
/// 流程模板初始化
/// </summary>
/// <param name="code">流程模板</param>
/// <param name="processId">流程实例</param>
/// <param name="userInfo">提交人用户信息</param>
/// <param name="nextUsers">下一个节点审核人</param>
/// <returns></returns>
private async Task<IWFEngine> BootstraperWithUser(string code, string processId, SysUser userInfo, Dictionary<string, string> nextUsers = null)
{
WFEngineConfig wfEngineConfig = new WFEngineConfig();
WFParams wfParams = new WFParams();
wfEngineConfig.Params = wfParams;
var currentUser = userInfo;
wfParams.CurrentUser = new WFUserInfo()
{
Id = currentUser.Id.ToString(),
Account = currentUser.Account,
Name = currentUser.Name
//CompanyId = currentUser.F_CompanyId,
//DepartmentId = currentUser.F_DepartmentId
};
if (!string.IsNullOrEmpty(code))
{
var schemeInfo = await client.Queryable<WFSchemeInfo>().FirstAsync(a => a.Code == code);
if (schemeInfo != null)
{
var data = await client.Queryable<WFScheme>().FirstAsync(a => a.Id == schemeInfo.SchemeId);
if (data != null)
{
wfParams.Scheme = data.Content;
wfParams.SchemeCode = code;
wfParams.SchemeId = schemeInfo.SchemeId;
wfParams.SchemeName = schemeInfo.Name;
wfParams.ProcessId = processId;
wfParams.HasInstance = false;
wfParams.CreateUser = new WFUserInfo()
{
Id = userInfo.Id.ToString(),
Account = userInfo.Account,
Name = userInfo.Name
//CompanyId = userInfo.F_CompanyId,
//DepartmentId = userInfo.F_DepartmentId
};
}
else
{
throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code));
}
}
else
{
throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code));
}
}
else if (!string.IsNullOrEmpty(processId))
{
var processEntity = await GetEntity(processId);
if (processEntity != null)
{
var data = await client.Queryable<WFScheme>().FirstAsync(a => a.Id == processEntity.SchemeId);
if (data != null)
{
wfParams.Scheme = data.Content;
wfParams.SchemeCode = processEntity.SchemeCode;
wfParams.SchemeId = processEntity.SchemeId;
wfParams.SchemeName = processEntity.SchemeName;
wfParams.IsChild = processEntity.IsChild == 1;
wfParams.ParentProcessId = processEntity.ParentProcessId;
wfParams.ParentTaskId = processEntity.ParentTaskId;
wfParams.ParentNodeId = processEntity.ParentNodeId;
wfParams.ProcessId = processId;
wfParams.HasInstance = true;
wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0;
wfParams.Title = processEntity.Title;
wfParams.CreateUser = new WFUserInfo()
{
Id = processEntity.CreateUserId,
Account = processEntity.CreateUserAccount,
Name = processEntity.CreateUserName,
CompanyId = processEntity.CreateUserCompanyId,
DepartmentId = processEntity.CreateUserDepartmentId
};
}
else
{
throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId));
}
}
else if (string.IsNullOrEmpty(wfParams.Scheme))
{
throw new Exception(string.Format("无法获取实例数据【{0}】", processId));
}
}
wfParams.NextUsers = nextUsers;
// 注册委托方法
wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList;
wfEngineConfig.GetUserList = GetUserList;
wfEngineConfig.GetSystemUserList = GetSystemUserList;
wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList;
wfEngineConfig.IsCountersignAgree = IsCountersignAgree;
wfEngineConfig.GetPrevUnitId = GetPrevUnitId;
IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client);
return iwfEngine;
}
/// <summary>
/// 获取等待任务
/// </summary>
/// <param name="processId">流程进程ID</param>
/// <param name="unitId">流程单元ID</param>
/// <returns></returns>
private async Task<List<WorkFlow.WFTask>> GetAwaitTaskList(string processId, string unitId)
{
List<WorkFlow.WFTask> res = new List<WorkFlow.WFTask>();
var list = await client.Queryable<WFTask>().Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == 21 && t.State == 1).ToListAsync();
foreach (var item in list)
{
res.Add(GetWFTask(item));
}
return res;
}
/// <summary>
/// 获取设置人员
/// </summary>
/// <param name="auditorList">人员配置信息</param>
/// <param name="createUser">流程发起人</param>
/// <param name="processId">流程进程实例ID</param>
/// <param name="startNode">开始节点</param>
/// <returns></returns>
private async Task<List<WFUserInfo>> GetUserList(List<WFAuditor> auditorList, WFUserInfo createUser, string processId, WFUnit startNode)
{
var res = new List<WFUserInfo>();
List<string> userIds = new List<string>();
foreach (var item in auditorList)
{
switch (item.Type)
{
//岗位
case "1":
var rlist = await userManager.UserIdsByPosition("", item.Id);
foreach (var ritem in rlist)
{
userIds.Add(ritem);
}
break;
//角色
case "2":
var rlist2 = await userManager.UserIdsByRole(item.Id);
List<string> userIds2 = new List<string>();
foreach (var ritem2 in rlist2)
{
userIds2.Add(ritem2);
}
var userList2 = await GetListByKeyValues(userIds2.ToArray());
var userOrgs = await userManager.UserOrgsByUserIds(userIds2);
foreach (var userOrg in userOrgs)
{
var user2 = userList2.FirstOrDefault(a => a.Id.ToString() == userOrg.Key);
switch (item.Condition)
{
case "1":
if ((userOrg.Value as List<string>).Contains(createUser.DepartmentId))
{
res.Add(GetWFUserInfo(user2));
}
break;
//case "2":
// if (user2.CompanyId == createUser.CompanyId)
// {
// res.Add(GetWFUserInfo(user2));
// }
// break;
case "3":
//// 获取当前用户的岗位
var postList1 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位
var postList2 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位
//if (await _postIBLL.IsUp(postList1, postList2))
if (await positionManager.IsUp(postList1, postList2))
{
res.Add(GetWFUserInfo(user2));
}
break;
case "4":
// 获取当前用户的岗位
var postList3 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位
var postList4 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位
if (await positionManager.IsDown(postList3, postList4))
{
res.Add(GetWFUserInfo(user2));
}
break;
default:
res.Add(GetWFUserInfo(user2));
break;
}
}
break;
//用户
case "3":
userIds.Add(item.Id);
break;
//上下级
case "4":
var postIds = await userManager.PositonsByUser(createUser.Id);// 发起人岗位
int level = Convert.ToInt32(item.Id);
List<string> postList;
if (level < 6)
{
postList = (await positionManager.GetUpIdList(postIds, level)).ToList();
}
else
{
level = level - 5;
postList = (await positionManager.GetDownIdList(postIds, level)).ToList();
}
var userRelationList4 = await userManager.UserIdsByPositions(postList);
userIds.AddRange(userRelationList4);
break;
//节点执行人
case "5":
if (item.Id == startNode.Id)
{
res.Add(createUser);
}
else
{
var taskList = await GetLastFinishTaskList(item.Id, processId);
foreach (var task in taskList)
{
userIds.Add(task.UserId);
}
}
break;
//数据库表字段
case "6":
using (var db = this.CodeClient(item.DbCode, _configuration))
{
DataTable dt = await db.Ado.GetDataTableAsync(string.Format("select {0} from {1} where {2} = @processId ", item.AuditorField, item.Table, item.Rfield), new { processId });
foreach (DataRow row in dt.Rows)
{
var userIdString = row[0].ToString();
if (!string.IsNullOrEmpty(userIdString))
{
var userIdList = userIdString.Split(",");
foreach (var userIdItem in userIdList)
{
userIds.Add(userIdItem);
}
}
}
break;
}
//数据库表字段
case "7":
using (var db = this.CodeClient(item.DbCode, _configuration))
{
//获取数据id
var process = await client.Queryable<WFProcess>().FirstAsync(a => a.Id == processId);
WFInstanceInfo instanceInfo = null;
if (process != null)
{
// instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WFInstanceInfo>(process.InstanceInfo);
instanceInfo = process.InstanceInfo;
}
DataTable dt = await db.Ado.GetDataTableAsync(string.Format(item.Sql), new { pkeyValue = instanceInfo.pkeyValue });
foreach (DataRow row in dt.Rows)
{
var userIdString = row[0].ToString();
if (!string.IsNullOrEmpty(userIdString))
{
var userIdList = userIdString.Split(",");
foreach (var userIdItem in userIdList)
{
userIds.Add(userIdItem);
}
}
}
break;
}
}
}
var userList = await GetListByKeyValues(userIds.ToArray());
foreach (var user in userList)
{
res.Add(GetWFUserInfo(user));
}
return res;
}
/// <summary>
/// 获取单元上一次的审核人
/// </summary>
/// <param name="processId">流程进程ID</param>
/// <param name="unitId">流程单元ID</param>
/// <returns></returns>
private async Task<List<WFUserInfo>> GetPrevTaskUserList(string processId, string unitId)
{
var res = new List<WFUserInfo>();
var list = await GetLastTaskList(processId, unitId);
foreach (var item in list)
{
if (!string.IsNullOrEmpty(item.UserId))
{
res.Add(new WFUserInfo()
{
Id = item.UserId,
Name = item.UserName,
CompanyId = item.UserCompanyId,
DepartmentId = item.UserDepartmentId,
IsAgree = item.IsAgree == 1,
//Sort = item,
State = (int)item.State
});
}
}
return res;
}
/// <summary>
/// 获取系统管理员
/// </summary>
/// <returns></returns>
private async Task<List<WFUserInfo>> GetSystemUserList()
{
var res = new List<WFUserInfo>();
var user = new SysUser
{
Id = -1,
Account = Define.SYSTEM_USERNAME,
Name = "超级管理员"
};
res.Add(GetWFUserInfo(user));
return res;
}
/// <summary>
/// 判断会签是否通过
/// </summary>
/// <param name="processId">流程进程ID</param>
/// <param name="unitId">流程单元ID</param>
/// <returns></returns>
private async Task<bool> IsCountersignAgree(string processId, string unitId)
{
var list = (List<WFTaskLog>)await GetLogList(processId, unitId);
if (list.Count == 0)
{
return false;
}
return list[0].IsAgree == 1;
}
/// <summary>
/// 获取上一个流入节点(不是驳回流入的)
/// </summary>
/// <param name="processId"></param>
/// <param name="unitId"></param>
/// <returns></returns>
private async Task<string> GetPrevUnitId(string processId, string unitId)
{
var data = await GetLastNotRejectTask(processId, unitId);
if (data != null)
{
return data.PrevUnitId;
}
else
{
return string.Empty;
}
}
/// <summary>
/// 获取流程任务数据
/// </summary>
/// <param name="wfTaskEntity"></param>
/// <returns></returns>
private WorkFlow.WFTask GetWFTask(WFTask wfTaskEntity)
{
var res = new WorkFlow.WFTask()
{
UnitId = wfTaskEntity.UnitId,
Name = wfTaskEntity.UnitName,
PrevUnitId = wfTaskEntity.PrevUnitId,
PrevUnitName = wfTaskEntity.PrevUnitName,
Token = wfTaskEntity.Token,
Type = (int)wfTaskEntity.Type
};
return res;
}
/// <summary>
/// 获取用户
/// </summary>
/// <param name="userEntity"></param>
/// <returns></returns>
private WFUserInfo GetWFUserInfo(SysUser userEntity)
{
var res = new WFUserInfo()
{
Id = userEntity.Id.ToString(),
Name = userEntity.Name,
Account = userEntity.Account,
//DepartmentId = userEntity.F_DepartmentId,
//CompanyId = userEntity.F_CompanyId,
IsNew = true
};
return res;
}
/// <summary>
/// 获取流程实例
/// </summary>
/// <param name="myParams">流程运行参数</param>
/// <param name="title">标题</param>
/// <returns></returns>
private WFProcess GetWFProcessEntity(WFParams myParams, string title)
{
WFProcess wfProcessEntity = new WFProcess()
{
Id = myParams.ProcessId,
SchemeCode = myParams.SchemeCode,
SchemeId = myParams.SchemeId,
SchemeName = myParams.SchemeName,
Title = title,
EnabledMark = 1,
IsAgain = 0,
IsFinished = 0,
IsChild = myParams.IsChild ? 1 : 0,
IsStart = 0,
IsCancel = 1,
ParentNodeId = myParams.ParentNodeId,
ParentProcessId = myParams.ParentProcessId,
ParentTaskId = myParams.ParentTaskId,
CreateUserId = myParams.CreateUser.Id,
CreateUserName = myParams.CreateUser.Name,
CreateUserAccount = myParams.CreateUser.Account,
CreateUserCompanyId = myParams.CreateUser.CompanyId,
CreateUserDepartmentId = myParams.CreateUser.DepartmentId,
UserId = _auth.GetUserId()
};
return wfProcessEntity;
}
/// <summary>
/// 处理任务
/// </summary>
/// <param name="list">任务列表</param>
/// <param name="iWFEngine"></param>
/// <param name="processId">流程进程实例</param>
/// <param name="prevToken">任务Token</param>
/// <param name="taskId">任务id</param>
/// <returns></returns>
private async Task<List<WFTask>> ExecuteWFTaskEntity(List<WorkFlow.WFTask> list, IWFEngine iWFEngine, string processId, string prevToken, string taskId = "")
{
var res = new List<WFTask>();
//单任务审核
var tlist = list.Where(r => r.Type == 7).ToList();
if (tlist.Count > 0)
{
var group = tlist.GroupBy(r => r.UnitId).ToList();
foreach (var item in group)
{
var taskuser = new List<WFTaskUser>();
var users = tlist.Where(r => r.UnitId == item.Key).ToList();
var userTask = new WFTask
{
Id = Guid.NewGuid().ToString(),
Type = users[0].Type,
ProcessId = processId,
Token = users[0].Token,
UnitId = users[0].UnitId,
UnitName = users[0].Name,
PrevUnitId = users[0].PrevUnitId,
PrevUnitName = users[0].PrevUnitName,
PrevToken = prevToken,
PrevTaskId = taskId,
UserId = users[0].User.Id,
UserName = users[0].User.Name,
UserDepartmentId = users[0].User.DepartmentId,
UserCompanyId = users[0].User.CompanyId,
State = users[0].User.IsAwait ? 2 : 1,
Sort = users[0].User.Sort,
IsReject = users[0].IsReject ? 1 : 0,
ChildProcessId = users[0].ChildSchemeInfoId,
TimeoutInterval = users[0].OvertimeMessageInterval,
TimeoutStrategy = users[0].OvertimeMessageType,
IsBatchAudit = users[0].IsBatchAudit ? 1 : 0,
ProcessUserId = iWFEngine.CreateUser.Id,
ProcessUserName = iWFEngine.CreateUser.Name,
ProcessCode = iWFEngine.Config.Params.SchemeCode,
ProcessTitle = iWFEngine.Config.Params.Title,
IsRetract=0
};
if (users[0].IsOvertimeMessage)
{
if (users[0].OvertimeGo > 0)
{
userTask.TimeoutAction = DateTime.Now.AddHours(users[0].OvertimeGo);
}
if (users[0].OvertimeMessageStart > 0)
{
userTask.TimeoutNotice = DateTime.Now.AddHours(users[0].OvertimeMessageStart);
}
}
foreach (var ts in users)
{
WFTaskUser tu = new WFTaskUser();
tu.UserId = ts.User.Id;
tu.TaskId = userTask.Id;
taskuser.Add(tu);
}
userTask.WFTaskUser = taskuser;
res.Add(userTask);
}
}
foreach (var item in list)
{
if (!string.IsNullOrEmpty(item.MessageType))
{
// 发送消息
var taskType = "";
switch (item.Type)
{
case 1:
case 5:
case 7:
taskType = "审核";
break;
case 2:
taskType = "查阅";
break;
case 3:
taskType = "提交";
break;
case 4:
taskType = "重新提交";
break;
}
if (!string.IsNullOrEmpty(taskType))
{
var msg = $"【{taskType}】{iWFEngine.Config.Params.Title},{item.Name}";
var userList = new List<string>();
userList.Add(item.User.Id);
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, item.MessageType, item.Token);
}
}
string childSchemeInfoCode = "";
if (item.Type == 3)
{
var schemeInfo = await this.Repository.ChangeRepository<SugarRepositiry<WFSchemeInfo>>().GetByIdAsync(item.ChildSchemeInfoId);
if (schemeInfo != null)
{
childSchemeInfoCode = schemeInfo.Code;
}
}
switch (item.Type)
{
case 1:
case 2:
case 3:
case 4:
case 5:
var userTask = new WFTask
{
Type = item.Type,
ProcessId = processId,
Token = item.Token,
UnitId = item.UnitId,
UnitName = item.Name,
PrevUnitId = item.PrevUnitId,
PrevUnitName = item.PrevUnitName,
PrevToken = prevToken,
PrevTaskId = taskId,
UserId = item.User.Id,
UserName = item.User.Name,
UserDepartmentId = item.User.DepartmentId,
UserCompanyId = item.User.CompanyId,
State = item.User.IsAwait ? 2 : 1,
Sort = item.User.Sort,
IsReject = item.IsReject ? 1 : 0,
ChildProcessId = item.ChildSchemeInfoId,
ChildSchemeInfoCode = childSchemeInfoCode,
TimeoutInterval = item.OvertimeMessageInterval,
TimeoutStrategy = item.OvertimeMessageType,
IsBatchAudit = item.IsBatchAudit ? 1 : 0,
ProcessUserId = iWFEngine.CreateUser.Id,
ProcessUserName = iWFEngine.CreateUser.Name,
ProcessCode = iWFEngine.Config.Params.SchemeCode,
ProcessTitle = iWFEngine.Config.Params.Title,
IsRetract=0
};
if (item.IsOvertimeMessage)
{
if (item.OvertimeGo > 0)
{
userTask.TimeoutAction = DateTime.Now.AddHours(item.OvertimeGo);
}
if (item.OvertimeMessageStart > 0)
{
userTask.TimeoutNotice = DateTime.Now.AddHours(item.OvertimeMessageStart);
}
}
res.Add(userTask);
break;
case 10:
// 执行脚本
res.Add(new WFTask
{
Type = item.Type,
ProcessId = processId,
Token = item.Token,
UnitId = item.UnitId,
UnitName = item.Name,
PrevUnitId = item.PrevUnitId,
PrevUnitName = item.PrevUnitName,
PrevToken = prevToken
});
break;
case 21:
res.Add(new WFTask
{
Type = item.Type,
ProcessId = processId,
Token = item.Token,
UnitId = item.UnitId,
UnitName = item.Name,
PrevUnitId = item.PrevUnitId,
PrevUnitName = item.PrevUnitName,
PrevToken = prevToken,
State = 1,
});
break;
case 22:
await CloseTask(processId, item.UnitId, 21, taskId);
break;
case 23:
case 24:
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = "系统任务",
TaskType = item.Type,
Token = item.Token,
ProcessId = processId,
UnitId = item.UnitId,
UnitName = item.Name,
PrevUnitId = item.PrevUnitId,
PrevUnitName = item.PrevUnitName
};
await AddLog(wfTaskLogEntity);
break;
case 26:
// 更新任务状态
await Update(processId, item.UnitId);
break;
}
}
return res;
}
public void AddOpenJob(WFTask task, DateTime outtime, DateTime overtime)
{
try
{
AddOrUpdateOpenJobReq req = new AddOrUpdateOpenJobReq();
req.JobName = $"超时通知 {task.Id}";
req.JobType = 0;
req.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}";
req.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskTimeoutJob";
req.Status = 1;
req.Cron = GetCorn(outtime);
req.Remark = $"{task.ProcessUserId}--{task.UnitName}";
_job.AddStart(req);
AddOrUpdateOpenJobReq req1 = new AddOrUpdateOpenJobReq();
req1.JobName = $"严重超时通知 {task.Id}";
req1.JobType = 0;
req1.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}";
req1.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskOverTimeJob";
req1.Status = 1;
req1.Cron = GetCorn(overtime);
req1.Remark = $"{task.ProcessUserId}--{task.UnitName}";
_job.AddStart(req1);
}
catch
{
return;
}
}
public string GetCorn(DateTime time)
{
StringBuilder sb = new StringBuilder();
sb.Append(time.Second.ToString());
sb.Append(" ");
sb.Append(time.Minute.ToString());
sb.Append(" ");
sb.Append(time.Hour.ToString());
sb.Append(" ");
sb.Append(time.Day.ToString());
sb.Append(" ");
sb.Append(time.Month.ToString());
sb.Append(" ");
sb.Append("?");
sb.Append(" ");
sb.Append(time.Year.ToString());
return sb.ToString();
}
/// <summary>
/// 执行脚本
/// </summary>
/// <param name="task">脚本任务</param>
/// <param name="code"></param>
/// <param name="processId"></param>
/// <param name="prevTaskId"></param>
/// <param name="createUser"></param>
/// <param name="iWFEngine"></param>
/// <param name="preTask"></param>
/// <returns></returns>
private async Task<bool> ExecuteScript(WFTask task, string code, string processId, string prevTaskId,string nextid, WFUserInfo createUser, IWFEngine iWFEngine, WFTask preTask,string des)
{
SysUser userInfo;
if (preTask == null)
{
userInfo = new SysUser()
{
Id = long.Parse(createUser.Id),
Account = createUser.Account,
//CompanyId = createUser.CompanyId,
//F_DepartmentId = createUser.DepartmentId
};
}
else
{
//userInfo = await this.CurrentUser(preTask.F_UserId);
userInfo = _auth.GetCurrentUser().User;
}
string nextnode = "";
if (!string.IsNullOrEmpty(nextid))
{
nextnode = iWFEngine.GetNode(nextid).Name;
}
var process = await client.Queryable<WFProcess>().FirstAsync(a => a.Id == processId);
WFInstanceInfo instanceInfo = null;
if (process != null)
{
// instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WFInstanceInfo>(process.InstanceInfo);
instanceInfo = process.InstanceInfo;
}
var param = new
{
processId,
userId = createUser.Id,
userAccount = createUser.Account,
companyId = createUser.CompanyId,
departmentId = createUser.DepartmentId,
userName2 = userInfo.Name,
userId2 = userInfo.Id.ToString(),
userAccount2 = userInfo.Account,
//companyId2 = userInfo.F_CompanyId,
//departmentId2 = userInfo.F_DepartmentId,
code,
nodeName=nextnode,
pkeyValue = instanceInfo == null ? "" : instanceInfo.pkeyValue,
des=des
};
try
{
var node = iWFEngine.GetNode(task.UnitId);
switch (node.ExecuteType)
{
case "1":
if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStr))
{
await client.Ado.ExecuteCommandAsync(node.SqlStr, param);
}
break;
case "2":
if (!string.IsNullOrEmpty(node.Ioc) && IocManager.Instance.IsRegistered<WorkFlow.IWorkFlowMethod>(node.Ioc))
{
WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService<WorkFlow.IWorkFlowMethod>(node.Ioc);
WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter()
{
ProcessId = processId,
UnitName = task.UnitName,
TaskId = prevTaskId,
Code = code,
UserId = createUser.Id,
UserAccount = createUser.Account,
CompanyId = createUser.CompanyId,
DepartmentId = createUser.DepartmentId
};
await iWorkFlowMethod.Execute(wfMethodParameter);
}
break;
case "3":
if (!string.IsNullOrEmpty(node.ApiUrl))
{
await HttpMethods.Post(node.ApiUrl, Json.ToJson(param));
}
break;
}
/*脚本执行成功*/
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = "脚本执行成功",
TaskType = 99,
ProcessId = processId,
TaskId = task.Id,
UnitId = task.UnitId,
UnitName = task.UnitName
};
await AddLog(wfTaskLogEntity);
return true;
}
catch (Exception ex)
{
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = string.Format("脚本执行异常:{0}", ex.Message),
TaskType = 99,
ProcessId = processId,
TaskId = task.Id,
UnitId = task.UnitId,
UnitName = task.UnitName
};
await AddLog(wfTaskLogEntity);
return false;
}
}
/// <summary>
/// 执行脚本
/// </summary>
/// <param name="processId"></param>
/// <param name="code"></param>
/// <param name="createUser"></param>
/// <param name="executeType"></param>
/// <param name="sqlDb"></param>
/// <param name="sqlStr"></param>
/// <param name="apiUrl"></param>
/// <param name="iocName"></param>
/// <returns></returns>
private async Task<bool> ExecuteScript(string processId, string code, WFUserInfo createUser, string executeType, string sqlDb, string sqlStr, string apiUrl, string iocName)
{
var param = new
{
processId,
userId = createUser.Id,
userAccount = createUser.Account,
companyId = createUser.CompanyId,
departmentId = createUser.DepartmentId,
code
};
try
{
switch (executeType)
{
case "1":
if (!string.IsNullOrEmpty(sqlDb) && !string.IsNullOrEmpty(sqlStr))
{
//await wfProcessSerive.BaseRepository(sqlDb).ExecuteSql(sqlStr, param);
await client.Ado.ExecuteCommandAsync(sqlStr, param);
}
break;
case "2":
if (!string.IsNullOrEmpty(iocName) && IocManager.Instance.IsRegistered<WorkFlow.IWorkFlowMethod>(iocName))
{
WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService<WorkFlow.IWorkFlowMethod>(iocName);
WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter()
{
ProcessId = processId,
Code = code,
UserId = createUser.Id,
UserAccount = createUser.Account,
CompanyId = createUser.CompanyId,
DepartmentId = createUser.DepartmentId
};
await iWorkFlowMethod.Execute(wfMethodParameter);
}
break;
case "3":
if (!string.IsNullOrEmpty(apiUrl))
{
await HttpMethods.Post(apiUrl, Json.ToJson(param));
}
break;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// 执行脚本(撤销)
/// </summary>
/// <param name="unitId"></param>
/// <param name="unitName"></param>
/// <param name="processId"></param>
/// <param name="createUser"></param>
/// <param name="iWFEngine"></param>
/// <returns></returns>
private async Task ExecuteRevokeScript(string unitId, string unitName, string processId, WFUserInfo createUser, IWFEngine iWFEngine)
{
var param = new
{
processId,
userId = createUser.Id,
userAccount = createUser.Account,
companyId = createUser.CompanyId,
departmentId = createUser.DepartmentId,
code = "revoke",
};
try
{
var node = iWFEngine.GetNode(unitId);
switch (node.ExecuteType)
{
case "1":
if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStrRevoke))
{
//await wfProcessSerive.BaseRepository(node.SqlDb).ExecuteSql(node.SqlStrRevoke, param);
await client.Ado.ExecuteCommandAsync(node.SqlStrRevoke, param);
}
break;
case "2":
if (!string.IsNullOrEmpty(node.IocRevoke) && IocManager.Instance.IsRegistered<WorkFlow.IWorkFlowMethod>(node.IocRevoke))
{
WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService<WorkFlow.IWorkFlowMethod>(node.IocRevoke);
WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter()
{
ProcessId = processId,
UnitName = unitName,
Code = "revoke",
UserId = createUser.Id,
UserAccount = createUser.Account,
CompanyId = createUser.CompanyId,
DepartmentId = createUser.DepartmentId
};
await iWorkFlowMethod.Execute(wfMethodParameter);
}
break;
case "3":
if (!string.IsNullOrEmpty(node.ApiUrlRevoke))
{
await HttpMethods.Post(node.ApiUrlRevoke, Json.ToJson(param));
}
break;
}
}
catch (Exception ex)
{
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = string.Format("脚本执行异常:{0}", ex.Message),
TaskType = 99,
ProcessId = processId,
UnitId = unitId,
UnitName = $"{unitName}-撤销"
};
await AddLog(wfTaskLogEntity);
}
}
/// <summary>
/// 普通审核
/// </summary>
/// <param name="iWFEngine"></param>
/// <param name="taskEntity"></param>
/// <param name="code"></param>
/// <param name="name"></param>
/// <param name="nextId">下一个节点</param>
/// <param name="des"></param>
/// <param name="stampImg"></param>
/// <returns></returns>
private async Task AuditNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "")
{
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId);
if (taskList.FindAll(t => t.Type != 10).Count == 0)
{
throw (new Exception("找不到下一个流转节点!"));
}
List<WFTask> myTaskList;
// 处理任务并更新数据
using (var uwo = UnitWork.CreateContext())
{
var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId);
await uwo.Db.Updateable<WFProcess>()
.SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 })
.SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1)
.SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1)
.Where(p => p.Id == taskEntity.ProcessId)
.ExecuteCommandAsync();
if (taskList.FindIndex(t => t.Type == 100) != -1)
{
if (process.IsChild == 1)
{
await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId);
}
}
// 更新任务状态
taskEntity.IsAgree = code == "disagree" ? 0 : 1;
taskEntity.State = 3;
if (taskEntity.Type == 7)
{
var currentUser = _auth.GetCurrentUser().User;
taskEntity.UserId = currentUser.Id.ToString();
taskEntity.UserName = currentUser.Name;
}
await uwo.WFTask.UpdateAsync(taskEntity);
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId);
// 关闭同一个节点,其他人的任务
await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id);
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id);
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
await Add(item);
}
await CreateTaskLog(taskEntity, code, name, des, stampImg);
uwo.Commit();
}
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,des);
}
}
/// <summary>
/// 子流程结束,获取父流程下一任务
/// </summary>
/// <param name="processId">父流程id</param>
/// <param name="unitId">父流程的节点id</param>
/// <param name="code">上一任务code类似agressdegress</param>
/// <param name="taskEntity">任务</param>
/// <param name="nextId">下一节点</param>
/// <returns></returns>
private async Task ChildrenEndTask(string processId, string unitId, string code, WFTask taskEntity, string nextId = "")
{
var process = await GetEntity(processId);
var iWFEngine = await Bootstraper("", processId, null, null);
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(unitId, code, nextId);
if (taskList.FindAll(t => t.Type != 10).Count == 0)
{
throw (new Exception("找不到下一个流转节点!"));
}
// 处理任务并更新数据
//wfProcessSerive.BeginTrans();
List<WFTask> myTaskList;
using (var uwo = UnitWork.CreateContext())
{
try
{
// 更新流程状态
await uwo.Db.Updateable<WFProcess>()
.SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 })
.SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1)
.SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1)
.Where(p => p.Id == processId)
.ExecuteCommandAsync();
if (taskList.FindIndex(t => t.Type == 100) != -1)
{
if (process.IsChild == 1)
{
await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId);
}
}
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id);
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
await Add(item);
}
}
catch
{
throw;
}
uwo.Commit();
}
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
await ExecuteScript(item, code, processId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,"");
}
}
private async Task AuditNodeByCountersign(IWFEngine iWFEngine, WFTask taskEntiy, string code, string name, string des, string stampImg)
{
taskEntiy.IsAgree = code == "disagree" ? 0 : 1;
var node = iWFEngine.GetNode(taskEntiy.UnitId);
var list = (List<WFTask>)await GetLastTaskList(taskEntiy.ProcessId, taskEntiy.UnitId);
var myIndex = list.FindIndex(t => t.Id == taskEntiy.Id);
if (myIndex == -1)
{
throw (new Exception("会签任务记录异常无法审核!"));
}
if (taskEntiy.IsAgree == 0)
{
if (node.CountersignType == "1")
{
// 并行
if (node.IsCountersignAll)
{
// 等待
if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1)
{
// 表示还有人没有审核
// 表示还有任务没有完成
using (var uwo = UnitWork.CreateContext())
{
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
await CreateTaskLog(taskEntiy, code, name, des, stampImg);
uwo.Commit();
}
}
else
{
var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId);
var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1;
if ((num - fnum) * 100 / num >= node.CountersignAllType)
{
await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg);
}
else
{
await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg);
}
}
}
else
{
// 不等待,每次都需要计算通过率
var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId);
var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1;
if ((num - fnum) * 100 / num >= node.CountersignAllType)// 表示还有通过的希望
{
using (var uwo = UnitWork.CreateContext())
{
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
await CreateTaskLog(taskEntiy, code, name, des, stampImg);
uwo.Commit();
}
}
else
{
await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg);
}
}
}
else
{
// 串行
await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg);
}
}
else
{
if (node.CountersignType == "1")
{
// 并行
// 如果不等待,不同意直接跳转
if (node.IsCountersignAll)
{
if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1) // 表示还有人没有处理完
{
// 表示还有任务没有完成
using (var uwo = UnitWork.CreateContext())
{
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
await CreateTaskLog(taskEntiy, code, name, des, stampImg);
uwo.Commit();
}
}
else
{
var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId);
var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count;
if ((num - fnum) * 100 / num >= node.CountersignAllType)
{
await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg);
}
else
{
await AuditNode(iWFEngine, taskEntiy, "disagree", "不同意", des, stampImg);
}
}
}
else
{
var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId);
var snum = list.FindAll(t => t.State == 3 && t.IsAgree == 1).Count;
if (snum * 100 / num >= node.CountersignAllType)
{
await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg);
}
else
{
using (var uwo = UnitWork.CreateContext())
{
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
await CreateTaskLog(taskEntiy, code, name, des, stampImg);
uwo.Commit();
}
}
}
}
else
{
// 串行
if (myIndex == list.Count - 1) // 表示最后一个人审核完成,然后往下执行
{
await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg);
}
else
{
// 表示还有任务没有完成
using (var uwo = UnitWork.CreateContext())
{
WFProcess processEntity = new WFProcess()
{
Id = taskEntiy.ProcessId,
IsStart = 1,
IsCancel = 0,
};
await uwo.WFProcess.UpdateAsync(processEntity);
taskEntiy.State = 3;
await uwo.WFTask.UpdateAsync(taskEntiy);
await CreateTaskLog(taskEntiy, code, name, des, stampImg);
if (node.CountersignType == "2")
{
// 串行,更新上一个任务的撤销操作,开启下一个任务
if (myIndex == 0)
{
await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId);
}
else
{
await CloseTaskLogCancel(list[myIndex - 1].Id);
}
await uwo.WFTask.UpdateAsync(new WFTask { Id = list[myIndex + 1].Id, State = 1 });
}
var flag = uwo.Commit();
}
}
}
}
}
/// <summary>
/// 创建日志
/// </summary>
/// <param name="taskEntiy"></param>
/// <param name="code"></param>
/// <param name="name"></param>
/// <param name="des"></param>
/// <param name="stampImg"></param>
/// <returns></returns>
private async Task CreateTaskLog(WFTask taskEntiy, string code, string name, string des, string stampImg)
{
WFTaskLog wfTaskLogEntity = new WFTaskLog()
{
Des = $"【{name}】{des}",
TaskType = taskEntiy.Type,
ProcessId = taskEntiy.ProcessId,
UnitId = taskEntiy.UnitId,
UnitName = taskEntiy.UnitName,
IsAgree = taskEntiy.IsAgree,
OperationCode = code,
OperationName = name,
Token = taskEntiy.Token,
PrevUnitId = taskEntiy.PrevUnitId,
PrevUnitName = taskEntiy.PrevUnitName,
TaskId = taskEntiy.Id,
StampImg = stampImg,
IsCancel = 1,
IsLast = 1
};
await UpdateLog(taskEntiy.ProcessId, taskEntiy.UnitId);
await AddLog(wfTaskLogEntity);
}
#endregion
public async Task<Response<bool>> Supervise(string processId,int supervise = 1)
{
// todo 实现督办
var iWFEngine = await Bootstraper(string.Empty, processId, null, null);
// 获取未完成的任务
var taskList = await GetUnFinishTaskList(processId);
using (var uwo = UnitWork.CreateContext())
{
foreach (var item in taskList)
{
if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7)
{
// 督办时间督办标志
item.IsSupervise = supervise;
item.SuperviseTime = DateTime.Now;
item.SuperviseId = _auth.GetCurrentUser().User.Id;
// 发送消息
var msg = $"【审核】【督办】{item.ProcessTitle},{item.UnitName}";
var userList = new List<string>();
// todo 单体任务处理
userList.Add(item.UserId);
var node = iWFEngine.GetNode(item.UnitId);
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token);
await uwo.WFTask.UpdateAsync(item);
}
}
//await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId });
var wfTaskLogEntity = new WFTaskLog
{
Des = "督办审核",
TaskType = 98,
ProcessId = processId,
UnitId = iWFEngine.StartNode.Id,
UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name,
CreateDate = DateTime.Now,
UserId = _auth.GetUserId(),
UserName = _auth.GetUserNickName(),
Id = Guid.NewGuid().ToString()
};
await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity);
var flag = uwo.Commit();
return new Response<bool>
{
Result = flag,
Message = flag ? "success" : "error"
};
}
}
#region 撤回
/// <summary>
/// 撤回流程
/// </summary>
/// <param name="taskId">流程任务主键</param>
/// <param name="code">流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时</param>
/// <param name="name">流程审批操名称</param>
/// <param name="des">审批意见</param>
/// <param name="nextUsers">下一节点指定审核人</param>
/// <param name="stampImg">盖章图片</param>
/// <param name="stampPassWord">盖章图片密码</param>
/// <param name="nextId">下一个审核节点</param>
public async Task RetractFlow(string taskId, string code, string name, string des, Dictionary<string, string> nextUsers, string stampImg, string stampPassWord, string nextId)
{
var taskEntiy = await client.Queryable<WFTask>().Where(a => a.Id == taskId).FirstAsync();
if (taskEntiy == null)
{
throw (new Exception("找不到对应流程任务!"));
}
else if (taskEntiy.State != 3&& taskEntiy.State != 4)
{
throw (new Exception("该任务未完成!"));
}
//后期改
stampImg = "";
//stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord);
var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers);
// 1.判断任务类型 1 普通任务 5 会签任务
if (taskEntiy.Type == 1 || taskEntiy.Type == 7)
{
await RetractNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId);
}
else
{
throw (new Exception("该任务无法审核!"));
}
//await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息
// 发送消息
var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被撤回";
var userList = new List<string>();
userList.Add(iWFEngine.CreateUser.Id);
var node = iWFEngine.StartNode;
//await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId);
}
/// <summary>
/// 撤回
/// </summary>
/// <param name="iWFEngine"></param>
/// <param name="taskEntity"></param>
/// <param name="code"></param>
/// <param name="name"></param>
/// <param name="nextId">下一个节点</param>
/// <param name="des"></param>
/// <param name="stampImg"></param>
/// <returns></returns>
private async Task RetractNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "")
{
// 下一部需要执行的任务
var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId);
List<WFTask> myTaskList;
//修改原有任务的IsLast状态
await client.Updateable<WFTask>()
.SetColumns(t => new WFTask() { IsLast = 0 })
.Where(t => t.Id==taskEntity.Id)
.ExecuteCommandAsync();
//删除该节点之后生成的所有任务
var dellist=client.Queryable<WFTask>().Where(r=>r.CreateDate>taskEntity.CreateDate&&r.ProcessId==taskEntity.ProcessId).ToList();
await client.Deleteable<WFTask>(dellist).ExecuteCommandAsync();
// 处理任务并更新数据
using (var uwo = UnitWork.CreateContext())
{
var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId);
await uwo.Db.Updateable<WFProcess>()
.SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 })
.SetColumns(p=>p.IsFinished==0)
.SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1)
.SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1)
.Where(p => p.Id == taskEntity.ProcessId)
.ExecuteCommandAsync();
if (taskList.FindIndex(t => t.Type == 100) != -1)
{
if (process.IsChild == 1)
{
await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId);
}
}
var newTask = new WFTask
{
Id = Guid.NewGuid().ToString(),
Type = taskEntity.Type,
ProcessId = taskEntity.ProcessId,
Token = Guid.NewGuid().ToString(),
UnitId = taskEntity.UnitId,
UnitName = taskEntity.UnitName,
PrevUnitId = taskEntity.PrevUnitId,
PrevUnitName = taskEntity.PrevUnitName,
PrevToken = taskEntity.Token,
PrevTaskId = taskEntity.Id,
UserId = taskEntity.UserId,
UserName = taskEntity.UserName,
UserDepartmentId = taskEntity.UserDepartmentId,
UserCompanyId = taskEntity.UserCompanyId,
State = 1,
Sort = taskEntity.Sort,
IsReject = 0,
ChildProcessId = taskEntity.ChildProcessId,
ChildSchemeInfoCode = taskEntity.ChildSchemeInfoCode,
TimeoutInterval = taskEntity.TimeoutInterval,
TimeoutStrategy = taskEntity.TimeoutStrategy,
IsBatchAudit = taskEntity.IsBatchAudit,
ProcessUserId = iWFEngine.CreateUser.Id,
ProcessUserName = iWFEngine.CreateUser.Name,
ProcessCode = iWFEngine.Config.Params.SchemeCode,
ProcessTitle = iWFEngine.Config.Params.Title,
CreateDate = DateTime.Now,
CreateUserId = _auth.GetUserId(),
CreateUserName = _auth.GetUserName(),
IsLast=1,
IsRetract=1
};
await uwo.WFTask.InsertAsync(newTask);
// 更新上一个流转过来的任务,提示他无法被撤销
await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId);
// 关闭同一个节点,其他人的任务
await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id);
myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id);
foreach (var item in myTaskList)
{
if (item.Type == 7)
{
await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser);
}
await Add(item);
}
await CreateTaskLog(taskEntity, code, name, des, stampImg);
uwo.Commit();
}
// 脚本执行
var scriptTaskList = myTaskList.FindAll(t => t.Type == 10);
foreach (var item in scriptTaskList)
{
await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity, des);
}
}
#endregion
}
}