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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using 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
}
}