Files
WarehouseMgmt/KingInfoWebApi/VolPro.Core/WorkFlow/WorkFlowManager.cs
2025-10-09 13:58:21 +08:00

1739 lines
77 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Primitives;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using KingInfoWebApi.Core.BaseProvider;
using KingInfoWebApi.Core.Configuration;
using KingInfoWebApi.Core.DBManager;
using KingInfoWebApi.Core.DbSqlSugar;
using KingInfoWebApi.Core.EFDbContext;
using KingInfoWebApi.Core.Extensions;
using KingInfoWebApi.Core.Infrastructure;
using KingInfoWebApi.Core.ManageUser;
using KingInfoWebApi.Core.Services;
using KingInfoWebApi.Core.SignalR;
using KingInfoWebApi.Core.Utilities;
using KingInfoWebApi.Entity.DomainModels;
using static Npgsql.PostgresTypes.PostgresCompositeType;
namespace KingInfoWebApi.Core.WorkFlow
{
public static class WorkFlowManager
{
public static bool Exists<T>(string workFlowTableName = null)
{
return WorkFlowContainer.Exists<T>(workFlowTableName);
}
public static bool Exists<T>(T entity, string workFlowTableName = null)
{
return WorkFlowContainer.Exists<T>(workFlowTableName) && GetAuditFlowTable<T>(typeof(T).GetKeyProperty().GetValue(entity).ToString(), workFlowTableName) != null;
}
public static bool Exists(string table)
{
return WorkFlowContainer.Exists(table);
}
/// <summary>
/// 获取审批的数据
/// </summary>
public static async Task<object> GetAuditFormDataAsync(string tableKey, string table)
{
Type type = WorkFlowContainer.GetType(table);
if (type == null)
{
return Array.Empty<object>();
}
var detailOptions = WorkFlowContainer.GetDetail(type).FirstOrDefault();
var obj = typeof(WorkFlowManager).GetMethod("GetFormDataAsync").MakeGenericMethod(new Type[] { type, detailOptions?.Type ?? type })
.Invoke(null, new object[] { tableKey, table, detailOptions }) as Task<object>;
return await obj;
}
/// <summary>
/// 审批表单数据查询与数据源转换
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tableKey"></param>
/// <param name="table"></param>
/// <returns></returns>
public static async Task<object> GetFormDataAsync<T, Detail>(string tableKey, string table, WorkFlowFormDetails flowFormDetails)
where T : class where Detail : class
{
string[] fields = WorkFlowContainer.GetFormFields(table);
if (fields == null || fields.Length == 0)
{
return Array.Empty<object>();
}
string keyName = typeof(T).GetKeyName();
var condition = keyName.CreateExpression<T>(tableKey, Enums.LinqExpressionType.Equal);
//动态分库应该查询对应的数据库
var data = await DbManger.GetDbContext<T>().Set<T>().Where(condition).FirstOrDefaultAsync();
if (data == null)
{
Console.WriteLine($"未查到数据,表:{table},id:{tableKey}");
return Array.Empty<object>();
}
var mainObj = typeof(WorkFlowManager).GetMethod("GetFormData")
.MakeGenericMethod(new Type[] { typeof(T) })
.Invoke(null, new object[] { new List<T>() { data }, fields });
var mainList = (List<object>)mainObj;
if (mainList.Count == 0)
{
string msg = $"未查到审核流程表【{typeof(T).Name}】id【{tableKey}】数据";
Console.WriteLine(msg);
Logger.Error(msg);
return new
{
data = mainList[0]
};
}
//获取明细表配置
if (flowFormDetails != null)
{
var detailCondition = keyName.CreateExpression<Detail>(tableKey, Enums.LinqExpressionType.Equal);
var detailData = await DbManger.GetDbContext<Detail>().Set<Detail>().Where(detailCondition).ToListAsync();
var detailObj = typeof(WorkFlowManager).GetMethod("GetFormData")
.MakeGenericMethod(new Type[] { typeof(Detail) })
.Invoke(null, new object[] { detailData, flowFormDetails.FormFields });
return new
{
key = keyName,
data = mainList[0],
detail = new
{
name = typeof(Detail).GetEntityTableCnName(),
data = detailObj
}
};
}
return new
{
key = keyName,
data = mainList[0]
};
//List<object> list = new List<object>();
//var properties = typeof(T).GetProperties();
//foreach (var field in fields)
//{
// var property = properties.Where(c => c.Name == field).FirstOrDefault();
// string value = property.GetValue(data)?.ToString();
// var option = tableOptions.Where(c => c.ColumnName == field).FirstOrDefault();
// string name = option?.ColumnCnName;
// if (string.IsNullOrEmpty(name))
// {
// name = property.GetDisplayName();
// }
// if (option == null || string.IsNullOrEmpty(value))
// {
// list.Add(new
// {
// name,
// value = value ?? ""
// });
// continue;
// }
// if (option.isDate)
// {
// value = value.GetDateTime().Value.ToString("yyyy-MM-dd");
// }
// else if (!string.IsNullOrEmpty(option.DropNo))
// {
// string val = dictionaries.Where(c => c.DicNo == option.DropNo).FirstOrDefault()
// ?.Sys_DictionaryList
// //这里多选的暂时没处理
// ?.Where(c => c.DicValue == value)?.Select(s => s.DicName)
// .FirstOrDefault();
// if (!string.IsNullOrEmpty(val))
// {
// value = val;
// }
// }
// list.Add(new
// {
// name,
// value
// });
//}
}
public static List<object> GetFormData<T>(List<T> enities, string[] fields) where T : class
{
string table = typeof(T).Name;
var tableOptions = DBServerProvider.DbContext.Set<Sys_TableColumn>()
.Where(c => c.TableName == table && fields.Contains(c.ColumnName))
.Select(s => new
{
s.ColumnName,
s.ColumnCnName,
s.DropNo,
isDate = s.IsImage == 4,
s.ColumnType,
s.EditRowNo,
s.EditType,
s.IsNull
}).ToList();
List<Sys_Dictionary> dictionaries = new List<Sys_Dictionary>();
var dicNos = tableOptions.Select(s => s.DropNo).ToList();
if (dicNos.Count > 0)
{
dictionaries = DictionaryManager.GetDictionaries(dicNos, true).ToList();
}
string[] editFormFeilds = WorkFlowContainer.GetEditFields(table) ?? new string[] { };
List<object> list = new List<object>();
var properties = typeof(T).GetProperties();
string[] editType = new string[] { "file", "img", "excel", "editor" };
int index = 0;
foreach (var data in enities)
{
index++;
Dictionary<string, object> item = new Dictionary<string, object>();
foreach (var field in fields)
{
var property = properties.Where(c => c.Name == field).FirstOrDefault();
string value = property.GetValue(data)?.ToString();
var option = tableOptions.Where(c => c.ColumnName == field).FirstOrDefault();
string name = option?.ColumnCnName;
if (string.IsNullOrEmpty(name))
{
name = property.GetDisplayName();
}
if (option == null || string.IsNullOrEmpty(value))
{
if (editFormFeilds.Contains(field))
{
item[field] = new
{
name = name,
field = field,
value = value,
isEdit = true,
editRow = option?.EditRowNo,
editType = option?.EditType,
formType = option?.EditType,
require = option?.IsNull == 1 ? false : true,
dropNo = option?.DropNo
};
}
else
{
item[field] = new
{
name = name,
field = field,
value = value,
formType = option.EditType,
dropNo = option.DropNo
};
}
continue;
}
string orgVal = value;
if (option.isDate)
{
value = value.GetDateTime().Value.ToString("yyyy-MM-dd");
}
else if (option.ColumnType == "DateTime")
{
value = value.GetDateTime().Value.ToString("yyyy-MM-dd HH:mm:sss");
}
else if (!string.IsNullOrEmpty(option.DropNo))
{
string val = null;
if (option.EditType == "selectList" || option.EditType == "checkbox" || option.EditType == "treeSelect")
{
string[] arr = value.Split(",");
arr = dictionaries.Where(c => c.DicNo == option.DropNo).FirstOrDefault()
?.Sys_DictionaryList
?.Where(c => arr.Contains(c.DicValue))?.Select(s => s.DicName)
.ToArray();
val = string.Join(",", arr);
}
else
{
val = dictionaries.Where(c => c.DicNo == option.DropNo).FirstOrDefault()
?.Sys_DictionaryList
?.Where(c => c.DicValue == value)?.Select(s => s.DicName)
.FirstOrDefault();
}
if (!string.IsNullOrEmpty(val))
{
value = val;
}
}
if (editFormFeilds.Contains(field))
{
item[field] = new
{
name = name,
field = field,
value = value,
orgVal,
isEdit = true,
formType = option.EditType,
editRow = option.EditRowNo,
editType = option.EditType,
require = option?.IsNull == 1 ? false : true,
dropNo = option.DropNo
};
}
else
{
item[field] = new
{
name = name,
field = field,
value = value,
orgVal,
formType = option.EditType,
dropNo = option.DropNo
};
}
}
//var formType = tableOptions.Where(x => fields.Contains(x.ColumnName) && editType.Contains(x.EditType))
// .Select(s => new { name = s.ColumnCnName, s.EditType }).ToList();
//if (formType.Count > 0)
//{
// item[$"form:type"] = formType;
//}
////2024.01.01增加加审批表单编辑
//if (index == enities.Count)
//{
// string[] editFields = WorkFlowContainer.GetEditFields(typeof(T).Name);
// if (editFields != null)
// {
// item["form:edit"] = tableOptions.Where(x => editFields.Contains(x.ColumnName))
// .Select(s => new { field = s.ColumnName, name = s.ColumnCnName, dataKey = s.DropNo, type = s.EditType })
// .ToList();
// }
//}
list.Add(item);
}
return list;
}
public static int GetAuditStatus<T>(string value, string workFlowTableName)
{
return GetAuditFlowTable<T>(value, workFlowTableName)?.AuditStatus ?? 0;
}
public static Sys_WorkFlowTable GetAuditFlowTable<T>(string workTableKey, string workFlowTableName = null)
{
var table = DBServerProvider.DbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkTable == (workFlowTableName ?? typeof(T).GetEntityTableName(false)) && x.WorkTableKey == workTableKey)
// .Select(s => new { s.CurrentStepId,s.AuditStatus})
.FirstOrDefault();
return table;
}
private static void Rewrite<T>(T entity, Sys_WorkFlow workFlow, bool changeTableStatus) where T : class, new()
{
var autditProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditstatus").FirstOrDefault();
if (autditProperty == null)
{
return;
}
string value = typeof(T).GetKeyProperty().GetValue(entity).ToString();
var dbContext = DBServerProvider.DbContext;
var workTable = dbContext.Set<Sys_WorkFlowTable>().Where(x => x.WorkTableKey == value && x.WorkFlow_Id == workFlow.WorkFlow_Id).Includes(x => x.Sys_WorkFlowTableStep).FirstOrDefault();
if (workTable == null || workFlow.Sys_WorkFlowStep == null || workFlow.Sys_WorkFlowStep.Count == 0)
{
Console.WriteLine($"未查到流程数据id{workFlow.WorkFlow_Id}");
return;
}
// workTable.CurrentOrderId = 1;
//这里还未处理回退到上一个节点
//重新设置第一个节点(有可能是返回上一个节点)
string startStepId = workTable.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.start.ToString())
.Select(s => s.StepId).FirstOrDefault();
workTable.CurrentStepId = workTable.Sys_WorkFlowTableStep.Where(x => x.ParentId == startStepId).Select(s => s.StepId).FirstOrDefault();
workTable.AuditStatus = (int)AuditStatus.;
workTable.Sys_WorkFlowTableStep.ForEach(item =>
{
item.Enable = 0;
item.AuditId = null;
item.Auditor = null;
item.AuditDate = null;
item.Remark = null;
});
//if (changeTableStatus)
//{
// dbContext.Entry(entity).State = EntityState.Detached;
// autditProperty.SetValue(entity, 0);
// dbContext.Entry(entity).Property(autditProperty.Name).IsModified = true;
//}
//dbContext.Entry(workTable).State = EntityState.Detached;
//dbContext.Update(workTable);
//dbContext.SaveChanges();
if (changeTableStatus)
{
// dbContext.Entry(entity).State = EntityState.Detached;
autditProperty.SetValue(entity, 0);
// dbContext.Entry(entity).Property(autditProperty.Name).IsModified = true;
dbContext.Update<T>(entity, new string[] { autditProperty.Name });
}
//dbContext.Entry(workTable).State = EntityState.Detached;
dbContext.Update(workTable);
dbContext.SaveChanges();
}
/// <summary>
/// 新建时写入流程
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="rewrite">是否重新生成流程</param>
/// <param name="changeTableStatus">是否修改原表的审批状态</param>
/// <param name="changeTableStatus">是否修改原表的审批状态</param>
public static void AddProcese<T>(T entity, bool rewrite = false, bool changeTableStatus = true,
Action<T, List<int>> addWorkFlowExecuted = null, bool checkId = false,
string workFlowTableName = null) where T : class, new()
{
WorkFlowTableOptions workFlow = WorkFlowContainer.GetFlowOptions(entity);
//没有对应的流程信息
if (workFlow == null || workFlow.FilterList.Count == 0)
{
return;
}
workFlow.WorkTableName = WorkFlowContainer.GetName<T>(workFlowTableName);
string workTable = workFlowTableName ?? typeof(T).GetEntityTableName(false);
////重新生成流程
if (rewrite)
{
Rewrite(entity, workFlow, changeTableStatus);
return;
}
var auditProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditstatus").FirstOrDefault();
if (auditProperty == null)
{
Console.WriteLine("表缺少审核状态字段AuditStatus");
}
int auditStatus = (int)workFlow.DefaultAuditStatus;
string tableKey = typeof(T).GetKeyProperty().GetValue(entity).ToString();
//提交的草稿直接删除
if (checkId)
{
var list = DBServerProvider.DbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkTable == workTable && x.WorkTableKey == tableKey)
.Includes(x => x.Sys_WorkFlowTableStep)
.ToList();
if (list.Count > 0)
{
DBServerProvider.DbContext.SqlSugarClient.DeleteNav(list).Include(c => c.Sys_WorkFlowTableStep).ExecuteCommand();
//DBServerProvider.DbContext.SaveChanges();
}
auditStatus = (int)AuditStatus.;
}
auditProperty.SetValue(entity, auditStatus);
var userInfo = UserContext.Current.UserInfo;
Guid workFlowTable_Id = Guid.NewGuid();
Sys_WorkFlowTable workFlowTable = new Sys_WorkFlowTable()
{
WorkFlowTable_Id = workFlowTable_Id,
AuditStatus = auditStatus,//(int)AuditStatus.待审核,
Enable = 1,
WorkFlow_Id = workFlow.WorkFlow_Id,
WorkName = workFlow.WorkName,
WorkTable = workTable,
WorkTableKey = tableKey,
WorkTableName = workFlow.WorkTableName,
DbServiceId = workFlow.DbServiceId,
CreateID = userInfo.User_Id,
CreateDate = DateTime.Now,
Creator = userInfo.UserTrueName
};
//生成标题模板
WorkFlowGeneric.CreateTitleTemplate(entity, workFlowTable, workFlow);
//生成流程的下一步
var steps = workFlow.FilterList.Where(x => x.StepAttrType == StepType.start.ToString()).Select(s => new Sys_WorkFlowTableStep()
{
Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
WorkFlowTable_Id = workFlowTable_Id,
WorkFlow_Id = workFlow.WorkFlow_Id,
StepId = s.StepId,
StepName = s.StepName ?? "流程开始",
StepAttrType = s.StepAttrType,
NextStepId = null,
ParentId = null,
StepType = s.StepType,
StepValue = s.StepValue,
OrderId = 0,
Enable = 1,
CreateDate = DateTime.Now,
Creator = userInfo.UserTrueName,
CreateID = userInfo.User_Id
}).ToList();
var entities = new List<T>() { entity };
FilterOptions filterOption = null;
for (int i = 0; i < steps.Count; i++)
{
var item = steps[i];
//查找下一个满足条件的节点数据
FilterOptions filter = workFlow.FilterList
.Where(c => c.ParentIds.Contains(item.StepId) && c.FieldFilters.CheckFilter(entities, c.Expression))
.FirstOrDefault();
//&& c.Expression != null
//&& entities.Any(((Func<T, bool>)c.Expression))
//未找到满足条件的找无条件的节点
if (filter == null)
{
filter = workFlow.FilterList.Where(c => c.ParentIds.Contains(item.StepId) && c.Expression == null).FirstOrDefault();
}
if (filter != null)
{
var setp = workFlow.Sys_WorkFlowStep.Where(x => x.StepId == filter.StepId).Select(s => new Sys_WorkFlowTableStep()
{
Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
WorkFlowTable_Id = workFlowTable_Id,
WorkFlow_Id = s.WorkFlow_Id,
StepId = s.StepId,
StepName = s.StepName,
StepAttrType = s.StepAttrType,
NextStepId = null,
ParentId = item.StepId,
StepType = s.StepType,
StepValue = s.StepValue,
OrderId = i + 1,
Enable = 1,
CreateDate = DateTime.Now,
}).FirstOrDefault();
//显示后续部门与角色审批人待完
//设置下个审核节点
item.NextStepId = setp.StepId;
if (!steps.Any(x => x.StepId == setp.StepId))
{
//2023.10.24生成多个节点
if (!string.IsNullOrEmpty(setp.StepValue) && setp.StepValue.Contains(","))
{
var ids = setp.StepValue.Split(",");
foreach (string id in ids)
{
steps.Add(new Sys_WorkFlowTableStep()
{
Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
WorkFlowTable_Id = setp.WorkFlowTable_Id,
WorkFlow_Id = setp.WorkFlow_Id,
StepId = setp.StepId,
StepName = setp.StepName,
StepAttrType = setp.StepAttrType,
NextStepId = null,
ParentId = setp.ParentId,
StepType = setp.StepType,
StepValue = id,// setp.StepValue,
OrderId = setp.OrderId,
Enable = 1,
CreateDate = DateTime.Now,
});
}
}
else
{
steps.Add(setp);
}
}
}
else
{
//找不到满足条件的节点,直接结束流程
var end = workFlow.Sys_WorkFlowStep.Where(c => c.StepAttrType == StepType.end.ToString()).ToList();
if (end.Count > 0)
{
item.NextStepId = end[0].StepId;
steps.Add(end.Select(s => new Sys_WorkFlowTableStep()
{
Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
WorkFlowTable_Id = workFlowTable_Id,
WorkFlow_Id = s.WorkFlow_Id,
StepId = s.StepId,
StepName = s.StepName,
StepAttrType = s.StepAttrType,
NextStepId = null,
ParentId = item.StepId,
StepType = s.StepType,
StepValue = s.StepValue,
OrderId = i + 1,
Enable = 1,
CreateDate = DateTime.Now,
}).FirstOrDefault());
i = steps.Count + 1;
}
}
if (i == 1)
{
filterOption = filter;
}
}
//2023移除默认审批人
//foreach (var setp in steps)
//{
// if (setp.StepType == (int)AuditType.用户审批)
// {
// setp.AuditId = setp.StepValue.GetInt();
// }
//}
//没有满足流程的数据不走流程
int count = steps.Where(x => x.StepAttrType != StepType.start.ToString() && x.StepAttrType != StepType.end.ToString()).Count();
if (count == 0)
{
return;
}
string stepMsg = null;
if (steps.Exists(x => x.StepType == (int)AuditType.))
{
//获取提交人上级审批部门
string parentDeptIds = GetStepValueWithParentDeptId(entity);
if (parentDeptIds == null)
{
string msg = $"表【{workFlow.WorkTableName}】数据找不到提交人的上级部门,提交数据:{entity.Serialize()}";
Console.WriteLine(msg);
Logger.Error(msg);
}
foreach (var item in steps)
{
if (item.StepType == (int)AuditType.)
{
item.StepType = (int)AuditType.;
item.StepValue = parentDeptIds;
item.Remark = stepMsg;
}
}
}
if (steps.Exists(x => x.StepType == (int)AuditType.))
{
//获取提交人上级审批部门
string parentRoleIds = GetStepValueWithParentRoleId(entity);
if (parentRoleIds == null)
{
stepMsg = "数据找不到提交人的上级角色,流程不能正常进行".Translator();
string msg = $"表【{workFlow.WorkTableName}】数据找不到提交人的上级角色,提交数据:{entity.Serialize()}";
Console.WriteLine(msg);
Logger.Error(msg);
}
foreach (var item in steps)
{
if (item.StepType == (int)AuditType.)
{
item.StepType = (int)AuditType.;
item.StepValue = parentRoleIds;
item.Remark = stepMsg;
}
}
}
//2025.05.25增加提交人自己审批
if (steps.Exists(x => x.StepType == (int)AuditType.))
{
string parentDeptIds = GetStepValueWithParentDeptId(entity);
var property = typeof(T).GetProperties().Where(x => x.Name == AppSetting.CreateMember.UserIdField).FirstOrDefault();
int userId = 0;
if (property != null)
{
userId = property.GetValue(entity).GetInt();
}
foreach (var item in steps)
{
if (item.StepType == (int)AuditType.)
{
item.StepType = (int)AuditType.;
item.StepValue = userId.ToString();
item.Remark = stepMsg;
}
}
}
//设置进入流程后的第一个审核节点,(开始节点的下一个节点)
var nodeInfo = steps.Where(x => x.ParentId == steps[0].StepId).Select(s => new
{
s.StepId,
s.StepName,
s.StepType,
s.StepValue
}).FirstOrDefault();
workFlowTable.CurrentStepId = nodeInfo.StepId;
workFlowTable.StepName = nodeInfo.StepName;
workFlowTable.Sys_WorkFlowTableStep = steps;
//写入日志
var log = new Sys_WorkFlowTableAuditLog()
{
Id = Guid.NewGuid(),
WorkFlowTable_Id = workFlowTable.WorkFlowTable_Id,
CreateDate = DateTime.Now,
AuditStatus = (int)AuditStatus.,
Remark = $"[{userInfo.UserTrueName}]提交了数据"
};
//dbContext.Set<Sys_WorkFlowTable>().Add(workFlowTable);
//dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
//dbContext.SaveChanges();
var entityContext = DBServerProvider.GetEntityDbContext<T>();
entityContext.Update(entity, new string[] { auditProperty.Name }, true);
var dbContext = DBServerProvider.DbContext;
//dbContext.Set<Sys_WorkFlowTable>().Add(workFlowTable);
//dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
dbContext.SqlSugarClient.InsertNav(workFlowTable).Include(x => x.Sys_WorkFlowTableStep).ExecuteCommand();
if (workFlow.DefaultAuditStatus != AuditStatus.稿 && workFlow.DefaultAuditStatus != AuditStatus.)
{
dbContext.Add(log);
}
dbContext.SaveChanges();
if (addWorkFlowExecuted != null)
{
var userIds = GetAuditUserIds(nodeInfo.StepType ?? 0, nodeInfo.StepValue);
addWorkFlowExecuted.Invoke(entity, userIds);
}
if (auditStatus == (int)AuditStatus.)
{
//发送邮件(appsettings.json配置文件里添加邮件信息)
var nextStep = workFlowTable.Sys_WorkFlowTableStep.Where(x => x.StepAttrType != StepType.start.ToString()).OrderBy(x => x.OrderId).FirstOrDefault(); ;
SendMail(workFlowTable, filterOption, nextStep, dbContext);
}
}
private static string GetStepValueWithParentDeptId<T>(T entity)
{
var property = typeof(T).GetProperties().Where(x => x.Name == AppSetting.CreateMember.UserIdField).FirstOrDefault();
if (property != null)
{
int userId = property.GetValue(entity).GetInt();
var deptIds = DBServerProvider.DbContext.Set<Sys_UserDepartment>().Where(x => x.Enable == 1 && x.UserId == userId)
.Select(s => s.DepartmentId).ToList();
deptIds = DBServerProvider.DbContext.Set<Sys_Department>()
.Where(s => deptIds.Contains(s.DepartmentId) && s.ParentId != null)
.Select(s => (Guid)s.ParentId).Distinct().ToList();
return string.Join(",", deptIds);
}
return null;
}
private static string GetStepValueWithParentRoleId<T>(T entity)
{
var property = typeof(T).GetProperties().Where(x => x.Name == AppSetting.CreateMember.UserIdField).FirstOrDefault();
if (property != null)
{
int userId = property.GetValue(entity).GetInt();
var roleIds = DBServerProvider.DbContext.Set<Sys_UserRole>().Where(x => x.Enable == 1 && x.UserId == userId)
.Select(s => s.RoleId).Distinct().ToList();
roleIds = DBServerProvider.DbContext.Set<Sys_Role>()
.Where(s => roleIds.Contains(s.Role_Id) && s.ParentId > 0)
.Select(s => s.ParentId).Distinct().ToList();
return string.Join(",", roleIds);
}
return null;
}
/// <summary>
/// 审核
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="status"></param>
/// <param name="remark"></param>
/// <param name="autditProperty"></param>
/// <param name="workFlowExecuting"></param>
/// <param name="workFlowExecuted"></param>
/// <returns></returns>
//public static WebResponseContent Audit<T>(T entity, AuditStatus status, string remark,
// PropertyInfo autditProperty,
// Func<T, AuditStatus, bool, WebResponseContent> workFlowExecuting,
// Func<T, AuditStatus, List<int>, bool, WebResponseContent> workFlowExecuted,
// bool init = false,
// Action<T, List<int>> initInvoke = null
// ) where T : class
public static WebResponseContent Audit<T>(BaseDbContext tableDbContext, T entity, AuditStatus status, string remark,
PropertyInfo autditProperty = null,
Func<T, AuditStatus, bool, WebResponseContent> workFlowExecuting = null,
Func<T, AuditStatus, List<int>, bool, WebResponseContent> workFlowExecuted = null,
bool init = false,
Action<T, List<int>> initInvoke = null,
FlowWriteState flowWriteState = FlowWriteState.,
string workFlowTableName = null
) where T : class, new()
{
if (string.IsNullOrEmpty(workFlowTableName))
{
workFlowTableName = typeof(T).GetEntityTableName();
}
WebResponseContent webResponse = new WebResponseContent(true);
if (init)
{
if (!WorkFlowContainer.Exists<T>(workFlowTableName))
{
return webResponse;
}
}
var dbContext = DBServerProvider.DbContext;
dbContext.QueryTracking = true; ;
var queryDbSet = tableDbContext;//.Set<T>();
var keyProperty = typeof(T).GetKeyProperty();
string key = keyProperty.GetValue(entity).ToString();
string workTable = workFlowTableName ?? typeof(T).GetEntityTableName(false);
Sys_WorkFlowTable workFlow = dbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkTable == workTable && x.WorkTableKey == key)
.Includes(x => x.Sys_WorkFlowTableStep)
.FirstOrDefault();
if (workFlow == null)
{
return webResponse.Error("未查到流程信息,请检查数据是否被删除");
}
if (flowWriteState == FlowWriteState.)
{
AntiData antiData = new AntiData()
{
AuditReason = remark,
IsFlow = true
};
antiData.StepId = workFlow.Sys_WorkFlowTableStep.Where(c => c.StepAttrType != StepType.start.ToString())
.OrderBy(c => c.OrderId).Select(s => s.StepId).FirstOrDefault();
return AntiAudit<T>(antiData, tableDbContext, entity, workFlowTableName);
}
workFlow.AuditStatus = (int)status;
var currentStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == workFlow.CurrentStepId).FirstOrDefault();
if (currentStep == null)
{
return webResponse.Error($"未查到流程节点[{workFlow.CurrentStepId}]信息,请检查数据是否被删除");
}
Sys_WorkFlowTableStep nextStep = null;
//获取下一步审核id
string nextStepId = null;
//多人审批
//多人并签、或签时只更新当前用户节点(不更新所有节点)
bool isMultiAudit = workFlow.Sys_WorkFlowTableStep
.Where(x => x.StepId == workFlow.CurrentStepId
&& (x.AuditStatus == null || x.AuditStatus == (int)AuditStatus.)
).Count() > 1;
//2023.07.11修复流程存在多个配置时查不到数据的问题
var filterOptions = WorkFlowContainer.GetFlowOptions(x => x.WorkFlow_Id == workFlow.WorkFlow_Id)
.FirstOrDefault()
?.FilterList
?.Where(x => x.StepId == currentStep.StepId)
?.FirstOrDefault();
var user = UserContext.Current.UserInfo;
//多人审批时启用并签功能,如果还有两个节点未审批(包括当前正在审批的节点),设置下一个节点还是当前节点
if (isMultiAudit && filterOptions?.AuditMethod == 1)
{
nextStepId = currentStep.StepId;
nextStep = currentStep;
}
else
{
nextStepId = currentStep.NextStepId;
nextStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == nextStepId).FirstOrDefault();
}
if (nextStep != null)
{
workFlow.StepName = nextStep.StepName;
}
Sys_WorkFlowTableStep item = null;
//并签与或签匹配
//if (isMultiAudit)
//{
item = workFlow.Sys_WorkFlowTableStep.Where(x => workFlow.CurrentStepId == x.StepId
&& (x.AuditStatus == null || x.AuditStatus == (int)AuditStatus.)
//找到当前满足条件的数据,只更新一条
&& CheckAuditUserValue(x.StepType, x.StepValue)
).FirstOrDefault();
//}
//else
//{
// item = workFlow.Sys_WorkFlowTableStep.Where(x => workFlow.CurrentStepId == x.StepId).FirstOrDefault();
//}
//更新明细记录
if (item != null)
{
item.AuditId = user.User_Id;
item.Auditor = user.UserTrueName;
item.AuditDate = DateTime.Now;
//如果审核拒绝或驳回并退回上一步,待完
item.AuditStatus = (int)status;
item.Remark = remark;
}
//生成审核记录
var log = new Sys_WorkFlowTableAuditLog()
{
Id = Guid.NewGuid(),
StepId = currentStep.StepId,
WorkFlowTable_Id = currentStep.WorkFlowTable_Id,
WorkFlowTableStep_Id = currentStep.Sys_WorkFlowTableStep_Id,
AuditDate = DateTime.Now,
AuditId = user.User_Id,
Auditor = user.UserTrueName,
AuditResult = remark,
Remark = remark,
AuditStatus = (int)status,
CreateDate = DateTime.Now,
StepName = currentStep.StepName
};
if (HttpContext.Current.Request.Query.TryGetValue("attach", out StringValues attach))
{
log.AttachFile = attach;
}
if (filterOptions != null)
{
//审核未通过或者驳回
if (flowWriteState != FlowWriteState. || status == AuditStatus. || status == AuditStatus.)
{
switch (flowWriteState)
{
case FlowWriteState.退:
log.AuditStatus = (int)AuditStatus.;
break;
case FlowWriteState.:
log.AuditStatus = (int)AuditStatus.;
break;
case FlowWriteState.:
log.AuditStatus = (int)AuditStatus.;
break;
}
//记录日志
dbContext.Add(log);
autditProperty.SetValue(entity, (int)status);
//修改审批各节点状态
UpdateAuditStatus<T>(tableDbContext, entity, workFlow, filterOptions, currentStep, status, remark, flowWriteState, isMultiAudit, workFlowTableName);
List<int> userIds = null;
var userPro = typeof(T).GetProperty(AppSetting.CreateMember.UserIdField);
if (userPro != null)
{
userIds = new List<int>() { userPro.GetValue(entity).GetInt() };
//发送给提交人
string msg = $"【{workFlow.WorkName}】审批流程【{flowWriteState.ToString()}】,审批结果:【{remark ?? ""}】";
SendMail(workFlow, filterOptions, currentStep, dbContext, userIds, msg);
}
//重新获取当前节点
currentStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == workFlow.CurrentStepId).FirstOrDefault() ?? currentStep;
//不是终止的,同时发给上一个审批人
if (flowWriteState == FlowWriteState.退
|| (status == AuditStatus. && filterOptions.AuditRefuse == (int)AuditRefuse.)
|| (status == AuditStatus. && filterOptions.AuditBack == (int)AuditBack.)
//|| (status == AuditStatus.审核未通过 && filterOptions.AuditRefuse == (int)AuditRefuse.流程重新开始)
//|| (status == AuditStatus.驳回 && filterOptions.AuditBack == (int)AuditBack.流程重新开始)
)
{
//发送邮件(appsettings.json配置文件里添加邮件信息)
SendMail(workFlow, filterOptions, currentStep, dbContext);
}
if (workFlowExecuted != null)
{
webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), false);
}
return webResponse;
}
}
if (autditProperty == null)
{
autditProperty = typeof(T).GetProperties().Where(s => s.Name.ToLower() == "auditstatus").FirstOrDefault();
}
bool isLast = false;
//没有找到下一步审批,审核完成
if ((nextStep == null || nextStep.StepAttrType == StepType.end.ToString()))
{
if (status == AuditStatus.)
{
workFlow.CurrentStepId = "审核完成";
var dateProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditdate").FirstOrDefault();
if (dateProperty != null)
{
dateProperty.SetValue(entity, DateTime.Now);
}
}
else
{
workFlow.CurrentStepId = "流程结束";
}
workFlow.AuditStatus = (int)status;
if (workFlowExecuting != null)
{
webResponse = workFlowExecuting.Invoke(entity, status, true);
if (!webResponse.Status)
{
return webResponse;
}
}
//发送邮件(appsettings.json配置文件里添加邮件信息)
SendMail(workFlow, filterOptions, nextStep, dbContext);
autditProperty.SetValue(entity, (int)status);
//dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
//queryDbSet.Update(entity);
//dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
//dbContext.SaveChanges();
dbContext.Update(workFlow);//.Include(x => x.Sys_WorkFlowTableStep).ExecuteCommandAsync();
dbContext.Update(item);
dbContext.Add(log);
dbContext.SaveChanges();
queryDbSet.Update<T>(entity, true);
if (workFlowExecuted != null)
{
webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), true);
}
return webResponse;
}
//指向下一个人审批
if (nextStep != null && status == AuditStatus.)
{
workFlow.CurrentStepId = nextStep.StepId;
//原表显示审核中状态
autditProperty.SetValue(entity, (int)AuditStatus.);
workFlow.AuditStatus = (int)AuditStatus.;
}
else
{
autditProperty.SetValue(entity, (int)status);
}
//下一个节点=null或节下一个节点为结束节点流程结束
if (nextStep == null || workFlow.Sys_WorkFlowTableStep.Exists(c => c.StepId == nextStep.StepId && c.StepAttrType == StepType.end.ToString()))
{
isLast = true;
}
if (workFlowExecuting != null)
{
webResponse = workFlowExecuting.Invoke(entity, status, isLast);
if (!webResponse.Status)
{
return webResponse;
}
}
//queryDbSet.Update(entity);
//dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
//dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
//dbContext.SaveChanges();
//dbContext.Entry(workFlow).State = EntityState.Detached;
//tableDbContext.Entry(entity).State = EntityState.Detached;
//if (workFlowExecuted != null)
//{
// webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), isLast);
//}
//SendMail(workFlow, filterOptions, nextStep, dbContext);
//return webResponse;
// dbContext.SqlSugarClient.InsertNav(workFlow).Include(x => x.Sys_WorkFlowTableStep).ExecuteCommandAsync();
dbContext.Update(workFlow);//.Include(x => x.Sys_WorkFlowTableStep).ExecuteCommandAsync();
dbContext.Update(item);
dbContext.Add(log);
dbContext.SaveChanges();
queryDbSet.Update(entity, true);
//dbContext.Entry(workFlow).State = EntityState.Detached;
//tableDbContext.Entry(entity).State = EntityState.Detached;
if (workFlowExecuted != null)
{
webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), isLast);
}
SendMail(workFlow, filterOptions, nextStep, dbContext);
return webResponse;
}
private static WebResponseContent UpdateAuditStatus<T>(
BaseDbContext tableDbContext,
T entity,
Sys_WorkFlowTable workFlow,
FilterOptions filterOptions,
Sys_WorkFlowTableStep currentStep,
AuditStatus status,
string remark,
FlowWriteState flowWriteState,
bool isMultiAudit,
string workFlowTableName = null
) where T : class, new()
{
WebResponseContent webResponse = new WebResponseContent(true);
var auditProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditstatus").FirstOrDefault();
if (auditProperty == null)
{
return webResponse.Error("表缺少审核状态字段AuditStatus");
}
var dbContext = DBServerProvider.DbContext;
if (flowWriteState == FlowWriteState.)
{
status = AuditStatus.;
workFlow.AuditStatus = (int)status;
auditProperty.SetValue(entity, (int)status);
}
else if (flowWriteState == FlowWriteState.退
|| (status == AuditStatus. && filterOptions.AuditRefuse == (int)AuditRefuse.)
|| (status == AuditStatus. && filterOptions.AuditBack == (int)AuditBack.))
{
//2023.12.01修复审批驳回到退到第一个节后无法审批的问题
var preSteps = workFlow.Sys_WorkFlowTableStep.Where(x => x.NextStepId == currentStep.StepId && x.StepAttrType == StepType.node.ToString()).ToList();
if (preSteps.Count > 0)
{
foreach (var preStep in preSteps)
{
preStep.AuditStatus = null;
preStep.AuditId = null;
preStep.AuditDate = null;
preStep.Auditor = null;
preStep.Remark = null;
//workFlow.AuditStatus = (int)AuditStatus.审核中;
dbContext.Update(preStep);
}
workFlow.CurrentStepId = preSteps[0].StepId;
workFlow.StepName = preSteps[0].StepName;
}
else
{
//没有找到上一个节点,默认当前节点就是第一个节点
workFlow.CurrentStepId = currentStep.StepId;
workFlow.StepName = currentStep.StepName;
}
//清空当前节点的审批信息(2024.05.21)
workFlow.Sys_WorkFlowTableStep.ForEach(x =>
{
if (x.StepId == currentStep.StepId)
{
x.AuditStatus = null;
x.AuditId = null;
x.AuditDate = null;
x.Auditor = null;
x.Remark = null;
dbContext.Update(x);
}
});
workFlow.AuditStatus = (int)AuditStatus.;
auditProperty.SetValue(entity, (int)AuditStatus.);
}
else if (flowWriteState == FlowWriteState.
|| (status == AuditStatus. && filterOptions.AuditRefuse == (int)AuditRefuse.)
|| (status == AuditStatus. && filterOptions.AuditBack == (int)AuditBack.))
{
//2024.01.22设置重新审批的流程为初始化配置的状态
var auditStatus = WorkFlowContainer.GetFlowOptions(entity, workFlowTableName)?.DefaultAuditStatus;
//2024.04.16处理待提交流程判断
if (auditStatus == null)
{
auditStatus = WorkFlowContainer.GetFlowOptions(c => c.WorkTable == workFlowTableName).Select(s => s.DefaultAuditStatus).FirstOrDefault();
}
bool defaultAuditStatus = false;
if (auditStatus == AuditStatus.稿 || auditStatus == AuditStatus.)
{
defaultAuditStatus = true;
auditProperty.SetValue(entity, (int)auditStatus);
}
else
{
auditProperty.SetValue(entity, (int)AuditStatus.);
}
//重新开始
var steps = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.node.ToString() && (x.AuditStatus >= 0)).ToList();
if (steps.Count > 0)
{
foreach (var item in steps)
{
item.AuditStatus = null;
item.AuditId = null;
item.AuditDate = null;
item.Auditor = null;
}
//重新指向第一个节点
workFlow.CurrentStepId = steps.OrderBy(c => c.OrderId).Select(c => c.StepId).FirstOrDefault();
workFlow.AuditStatus = defaultAuditStatus ? (int)auditStatus : (int)AuditStatus.;
DBServerProvider.DbContext.UpdateRange(steps);
}
}
string msg = null;
if (AuditStatus. == status)
{
if (filterOptions.AuditRefuse == (int)AuditRefuse.)
{
msg = "审批未通过,返回上一节点";
}
else if (filterOptions.AuditRefuse == (int)AuditRefuse.)
{
msg = "审批未通过,流程重新开始";
}
else
{
workFlow.CurrentStepId = null;
workFlow.StepName = "流程结束";
}
}
else if (AuditStatus. == status)
{
if (filterOptions.AuditBack == (int)AuditBack.)
{
msg = "审批被驳回,返回上一节点";
}
else if (filterOptions.AuditBack == (int)AuditBack.)
{
msg = "审批被驳回,流程重新开始";
}
else
{
workFlow.CurrentStepId = null;
workFlow.StepName = "流程结束";
}
}
var user = UserContext.Current.UserInfo;
if (msg != null)
{
var auditLog = new Sys_WorkFlowTableAuditLog()
{
Id = Guid.NewGuid(),
StepId = currentStep.StepId,
WorkFlowTable_Id = currentStep.WorkFlowTable_Id,
WorkFlowTableStep_Id = currentStep.Sys_WorkFlowTableStep_Id,
AuditDate = DateTime.Now,
AuditId = user.User_Id,
Auditor = user.UserTrueName,
AuditResult = remark,
Remark = msg,
AuditStatus = (int)status,
CreateDate = DateTime.Now,
StepName = currentStep.StepName
};
dbContext.Add(auditLog);
}
//autditProperty.SetValue(entity, (int)status);
//query.Update(entity);
//修改状态
// dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
workFlow.StepName = workFlow.Sys_WorkFlowTableStep.Where(c => c.StepId == workFlow.CurrentStepId).Select(s => s.StepName).FirstOrDefault();
dbContext.Update(workFlow);
dbContext.UpdateRange(workFlow.Sys_WorkFlowTableStep);
dbContext.SaveChanges();
// dbContext.Entry(workFlow).State = EntityState.Detached;
tableDbContext.Update<T>(entity);
tableDbContext.SaveChanges();
//tableDbContext.Entry(entity).State = EntityState.Detached;
return webResponse.OK();
}
/// <summary>
/// 反审
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="antiData"></param>
/// <param name="tableDbContext"></param>
/// <param name="entity"></param>
public static WebResponseContent AntiAudit<T>(AntiData antiData, BaseDbContext dbContext, T entity, string workFlowTableName, bool restart = false) where T : class, new()
{
WebResponseContent webResponse = new WebResponseContent();
var keyProperty = typeof(T).GetKeyProperty();
string key = keyProperty.GetValue(entity).ToString();
string workTable = workFlowTableName ?? typeof(T).GetEntityTableName(false);
var sysDbContext = DbManger.SysDbContext;
Sys_WorkFlowTable workFlow = sysDbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkTable == workTable && x.WorkTableKey == key)
.Includes(x => x.Sys_WorkFlowTableStep)
.FirstOrDefault();
if (workFlow == null)
{
return webResponse.Error("未查到流程信息,请检查数据是否被删除".Translator());
}
var step = workFlow.Sys_WorkFlowTableStep.Where(c => c.StepId == antiData.StepId).FirstOrDefault();
var steps = workFlow.Sys_WorkFlowTableStep.Where(c => c.OrderId >= step.OrderId).ToList();
foreach (var item in steps)
{
item.AuditStatus = null;
item.AuditId = null;
item.AuditDate = null;
item.Auditor = null;
}
var user = UserContext.Current.UserInfo;
workFlow.AuditStatus = (int)AuditStatus.;
workFlow.CurrentStepId = step.StepId;
workFlow.StepName = step.StepName;
var auditLog = new Sys_WorkFlowTableAuditLog()
{
Id = Guid.NewGuid(),
StepId = workFlow.CurrentStepId,
WorkFlowTable_Id = workFlow.WorkFlowTable_Id,
WorkFlowTableStep_Id = step.Sys_WorkFlowTableStep_Id,
AuditDate = DateTime.Now,
AuditId = user.User_Id,
Auditor = user.UserTrueName,
AuditResult = antiData.AuditReason,
Remark = $"反审:{antiData.AuditReason ?? ""},退回节点[{workFlow.StepName}]",
AuditStatus = (int)AuditStatus.,
CreateDate = DateTime.Now,
StepName = workFlow.StepName
};
try
{
sysDbContext.BeginTran();
DBServerProvider.DbContext.Update(workFlow, x => new { x.AuditStatus, x.CurrentStepId, x.StepName });
if (steps.Count > 0)
{
DBServerProvider.DbContext.UpdateRange(steps, x => new { x.AuditStatus, x.Remark, x.AuditId, x.AuditDate, x.Auditor });
}
sysDbContext.Add(auditLog);
sysDbContext.SaveChanges();
var auditProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditstatus").FirstOrDefault();
if (auditProperty == null)
{
return webResponse.Error("表缺少审核状态字段AuditStatus");
}
//2024.01.22设置重新审批的流程为初始化配置的状态
AuditStatus? auditStatus = AuditStatus.;
if (restart)
{
var status = WorkFlowContainer.GetFlowOptions(entity, workFlowTableName)?.DefaultAuditStatus;
if (status == AuditStatus.稿 || status == AuditStatus.)
{
auditStatus = status;
}
}
auditProperty.SetValue(entity, (int)AuditStatus.);
dbContext.Update<T>(entity, new string[] { auditProperty.Name }, true);
DbManger.SysDbContext.CommitTran();
var currentStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == workFlow.CurrentStepId).FirstOrDefault();
if (currentStep != null)
{
//获取流程过滤条件
WorkFlowTableOptions flowOptions = WorkFlowContainer.GetFlowOptions(x => x.WorkFlow_Id == workFlow.WorkFlow_Id).FirstOrDefault();
var options = flowOptions?.FilterList?.Where(x => x.StepId == currentStep.StepId)?.FirstOrDefault();
//发送给提交人
if (auditStatus == AuditStatus.稿 || auditStatus == AuditStatus.)
{
//发送邮件(appsettings.json配置文件里添加邮件信息)
List<int> userId = new List<int>()
{
typeof(T).GetKeyProperty().GetValue(entity).GetInt()
};
SendMail(workFlow, options, currentStep, DBServerProvider.DbContext, userId, $"[{workFlow.WorkTableName}]反审回退");
}
else
{ //发送给上一个人
SendMail(workFlow, options, currentStep, DBServerProvider.DbContext);
}
}
}
catch (Exception ex)
{
DbManger.SysDbContext.RollbackTran();
throw new Exception($"反审更新异常,table:{workFlowTableName},{entity.Serialize()},{ex.Message + ex.StackTrace}");
}
return webResponse.OK("反审成功".Translator());
}
private static void SendMail(Sys_WorkFlowTable workFlow, FilterOptions filterOptions, Sys_WorkFlowTableStep nextStep, BaseDbContext dbContext, List<int> userIds = null, string title = null)
{
if (!string.IsNullOrEmpty(workFlow.TitleTemplate))
{
title = workFlow.TitleTemplate;
}
else if (title == null)
{
title = $"有新的任务待审批:流程【{workFlow.WorkName}】,任务【{nextStep.StepName}】";
}
if (userIds == null && nextStep != null)
{
//审核发送邮件通知待完
userIds = GetAuditUserIds(nextStep.StepType ?? 0, nextStep.StepValue);
if (userIds.Count == 0)
{
return;
}
}
HttpContext.Current.GetService<IMessageService>()
.SendMessage(new MessageChannelData()
{
Code = "",
UserIds = userIds,
Status = true,
MessageNotification = new MessageNotification()
{
NotificationType = Enums.NotificationType.,
Title = "审批提醒",
Content = title,
TableKey = workFlow.WorkTableKey,
TableName = workFlow.WorkTable,
Creator = workFlow.Creator,
CreateID = workFlow.CreateID
}
});
if (filterOptions == null || filterOptions.SendMail != 1)
{
return;
}
if (nextStep == null)
{
nextStep = new Sys_WorkFlowTableStep() { };
}
if (userIds == null)
{
return;
}
var emails = dbContext.Set<Sys_User>()
.Where(x => userIds.Contains(x.User_Id) && x.Email != "").Select(s => s.Email)
.ToArray();
Task.Run(() =>
{
string msg = "";
try
{
string title = $"有新的任务待审批:流程【{workFlow.WorkName}】,任务【{nextStep.StepName}】";
MailHelper.Send(title, title, emails);
msg = $"审批流程发送邮件,流程名称:{workFlow.WorkName},流程id:{workFlow.WorkFlow_Id},步骤:{nextStep.StepName},步骤Id:{nextStep.StepId},收件人:{string.Join(";", emails)}";
Logger.AddAsync(msg);
}
catch (Exception ex)
{
msg += "邮件发送异常:";
Logger.AddAsync(msg, ex.Message + ex.StackTrace);
}
});
}
/// <summary>
/// 获取审批人的id
/// </summary>
/// <param name="stepType"></param>
/// <returns></returns>
private static List<int> GetAuditUserIds(int stepType, string nextId = null)
{
List<int> userIds = new List<int>();
if (stepType == 0 || string.IsNullOrEmpty(nextId))
{
return userIds;
}
if (stepType == (int)AuditType.)
{
int roleId = nextId.GetInt();
userIds = DBServerProvider.DbContext.Set<Sys_UserRole>().Where(s => s.RoleId == roleId && s.Enable == 1)
.Take(200).Select(s => s.UserId).ToList();
}
else if (stepType == (int)AuditType.)
{
Guid departmentId = nextId.GetGuid() ?? Guid.Empty;
userIds = DBServerProvider.DbContext.Set<Sys_UserDepartment>().Where(s => s.DepartmentId == departmentId && s.Enable == 1).Take(200).Select(s => s.UserId).ToList();
}
else
{
return nextId.Split(",").Select(c => c.GetInt()).ToList();
}
return userIds;
}
/// <summary>
/// 验证节节点是否满足当前用户
/// </summary>
/// <param name="stepType"></param>
/// <param name="stepValue"></param>
/// <returns></returns>
public static bool CheckAuditUserValue(int? stepType, string stepValue = null)
{
switch (stepType)
{
case (int)AuditType.:
return UserContext.Current.RoleIds.Contains(stepValue.GetInt());
case (int)AuditType.:
return UserContext.Current.DeptIds.Contains((Guid)stepValue.GetGuid());
default:
return UserContext.Current.UserId == stepValue.GetInt();
}
}
/// <summary>
/// 增加审批记录
/// </summary>
/// <param name="keys"></param>
/// <param name="auditStatus"></param>
/// <param name="auditReason"></param>
public static void AddAuditLog<T>(object[] keys, int? auditStatus, string auditReason) where T : class, new()
{
var user = UserContext.Current.UserInfo; ;
var logs = keys.Select(id => new Sys_WorkFlowTableAuditLog()
{
Id = Guid.NewGuid(),
StepId = id?.ToString(),
StepName = typeof(T).Name,//.GetEntityTableName(false),
Auditor = user.UserTrueName,
AuditDate = DateTime.Now,
AuditId = user.User_Id,
CreateDate = DateTime.Now,
AuditStatus = auditStatus,
AuditResult = auditReason,
Remark = auditReason
}).ToList();
DBServerProvider.DbContext.AddRange(logs, true);
}
/// <summary>
/// 替换现有流程数据
/// </summary>
/// <param name="workFlow"></param>
/// <param name="add"></param>
public static void UpdateFlowData(Sys_WorkFlow workFlow, List<Sys_WorkFlowStep> add)
{
if (workFlow.AuditingEdit != 1)
{
return;
}
if (add == null || add.Count == 0)
{
return;
}
var flowStep = DBServerProvider.DbContext.Set<Sys_WorkFlowStep>().Where(x => x.WorkFlow_Id == workFlow.WorkFlow_Id).ToList();
foreach (var item in flowStep)
{
item.NextStepIds = flowStep.Where(c => c.ParentId == item.StepId).Select(c => c.StepId).FirstOrDefault();
}
foreach (var item in add)
{
item.NextStepIds = flowStep.Where(c => c.StepId == item.StepId).Select(c => c.NextStepIds).FirstOrDefault();
}
add = add.Where(x => x.StepAttrType == StepType.node.ToString()).ToList();
// var steps = repository.DbContext.Set<Sys_WorkFlowStep>().Where(x => x.WorkFlow_Id == workFlow.WorkFlow_Id).ToList();
var flowTable = DBServerProvider.DbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkFlow_Id == workFlow.WorkFlow_Id
&& (x.AuditStatus == (int)AuditStatus. || x.AuditStatus == (int)AuditStatus.)
// && x.Sys_WorkFlowTableStep.Any(c => c.AuditStatus == null || c.AuditStatus == (int)AuditStatus.待审核)
).Includes(x => x.Sys_WorkFlowTableStep).ToList();
List<Guid> updateFlowIds = new List<Guid>();
List<Guid> ingroFlowIds = new List<Guid>();
//List<Guid> updateStepIds = new List<Guid>();
foreach (var workFlowTable in flowTable)
{
for (int i = 0; i < workFlowTable.Sys_WorkFlowTableStep.Count; i++)
{
var step = workFlowTable.Sys_WorkFlowTableStep[i];
//记录父级点节点变更
string parentStepId = add.Where(x => x.NextStepIds == step.StepId).Select(c => c.StepId).FirstOrDefault();
if (!string.IsNullOrEmpty(parentStepId))
{
step.ParentId = parentStepId;
// updateStepIds.Add(step.Sys_WorkFlowTableStep_Id);
}
//第三次增加节点时添加到开始后面节点orderid没有值下一个节点也不对
//找出新加的节点前一个节点(上级)
var addItems = add.Where(x => x.ParentId == step.StepId).ToList();
if (addItems.Count > 0)
{
//设置原有节点的下一个流程
step.NextStepId = addItems[0].StepId;
//记录变更的节点,重新指向了下一个节点
// updateStepIds.Add(step.Sys_WorkFlowTableStep_Id);
//找最后一个节点
if (addItems[0].NextStepIds == null)
{
addItems[0].NextStepIds = workFlowTable.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.end.ToString()).Select(c => c.StepId).FirstOrDefault();
}
workFlowTable.Sys_WorkFlowTableStep.AddRange(addItems.Select(s => new Sys_WorkFlowTableStep()
{
WorkFlow_Id = s.WorkFlow_Id,
StepId = s.StepId,
StepName = s.StepName,
StepType = s.StepType,
StepValue = s.StepValue,
StepAttrType = s.StepAttrType,
WorkFlowTable_Id = workFlowTable.WorkFlowTable_Id,
Enable = 1,
NextStepId = s.NextStepIds,
OrderId = null,
ParentId = s.ParentId,
CreateDate = DateTime.Now
}));
}
}
//找不到上下级的节点可能已被删除,忽略不处理
bool b = workFlowTable.Sys_WorkFlowTableStep
.Exists(x => (x.StepAttrType != StepType.start.ToString() && !workFlowTable.Sys_WorkFlowTableStep.Any(c => c.StepId == x.ParentId))
|| (x.StepAttrType != StepType.end.ToString() && !workFlowTable.Sys_WorkFlowTableStep.Any(c => c.StepId == x.NextStepId)));
if (b)
{
ingroFlowIds.Add(workFlowTable.WorkFlowTable_Id);
continue;
}
string parentStep = workFlowTable.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.start.ToString()).Select(c => c.StepId).FirstOrDefault();
//重新排序
int index = 1;
foreach (var item in workFlowTable.Sys_WorkFlowTableStep)
{
var list = workFlowTable.Sys_WorkFlowTableStep.Where(x => x.ParentId == parentStep).ToList();
if (list.Count > 0)
{
foreach (var item2 in list)
{
item2.OrderId = index;
index++;
}
parentStep = list[0].StepId;
}
}
//设置当前审批节点
string currentId = workFlowTable.Sys_WorkFlowTableStep
.Where(x => x.StepAttrType != StepType.start.ToString() && (x.AuditStatus == null || x.AuditStatus == (int)AuditStatus.)
//当前审批节点=没有审批过的节点,并且节点后台不存在已经审批的数据
&& !workFlowTable.Sys_WorkFlowTableStep.Exists(c => c.OrderId > x.OrderId && c.AuditStatus > (int)AuditStatus.))
.OrderBy(x => x.OrderId)
.Select(s => s.StepId)
.FirstOrDefault();
if (!string.IsNullOrEmpty(currentId) && currentId != workFlowTable.CurrentStepId)
{
workFlowTable.CurrentStepId = currentId;
updateFlowIds.Add(workFlowTable.WorkFlowTable_Id);
}
}
if (updateFlowIds.Count > 0)
{
var updateList = flowTable.Where(x => updateFlowIds.Contains(x.WorkFlowTable_Id)).ToList();
DBServerProvider.DbContext.UpdateRange(updateList, x => new { x.CurrentStepId });
}
var steps = flowTable.SelectMany(x => x.Sys_WorkFlowTableStep).Where(c => c.Sys_WorkFlowTableStep_Id == Guid.Empty && c.OrderId > 0).ToList();
for (int s = 0; s < steps.Count; s++)
{
var item = steps[s];
if (item.StepValue != null && item.StepValue.Contains(","))
{
var stepValues = item.StepValue.Split(",");
item.StepValue = stepValues[0];
for (int i = 1; i < stepValues.Length; i++)
{
var cloneItem = item.Serialize().DeserializeObject<Sys_WorkFlowTableStep>();
cloneItem.StepValue = stepValues[i];
cloneItem.Sys_WorkFlowTableStep_Id = Guid.NewGuid();
steps.Add(cloneItem);
}
}
item.Sys_WorkFlowTableStep_Id = Guid.NewGuid();
}
DBServerProvider.DbContext.AddRange(steps);
var updateSteps = flowTable.Where(x => !ingroFlowIds.Contains(x.WorkFlowTable_Id))
.SelectMany(x => x.Sys_WorkFlowTableStep).Where(x => x.Sys_WorkFlowTableStep_Id != Guid.Empty).ToList();
if (updateSteps.Count > 0)
{
DBServerProvider.DbContext.UpdateRange(updateSteps, x => new { x.NextStepId, x.ParentId, x.OrderId });
}
DBServerProvider.DbContext.SaveChanges();
}
/// <summary>
/// 获取实体类的审批信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
public static Sys_WorkFlowTable GetWorkFlowTable<T>(this T entity) where T : class
{
string table = typeof(T).GetEntityTableName();
string key = typeof(T).GetKeyProperty().GetValue(entity).ToString();
var flow = DbManger.SysDbContext.Set<Sys_WorkFlowTable>()
.Where(x => x.WorkTable == table && x.WorkTableKey == key)
.Includes(s => s.Sys_WorkFlowTableStep)
.FirstOrDefault();
return flow;
}
}
public enum FlowWriteState
{
= 0,
,
退,
}
}