添加项目文件。

This commit is contained in:
2023-03-13 15:00:34 +08:00
parent 42bf06ca3e
commit 1d73df3235
1205 changed files with 185078 additions and 0 deletions

View File

@@ -0,0 +1,402 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DatabaseAccessor;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.WorkFlow.Entitys.Dto.FlowBefore;
using JNPF.WorkFlow.Entitys.Enum;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Interfaces.Manager;
using JNPF.WorkFlow.Interfaces.Repository;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程审批.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowBefore", Order = 303)]
[Route("api/workflow/Engine/[controller]")]
public class FlowBeforeService : IDynamicApiController, ITransient
{
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IFlowTaskManager _flowTaskManager;
private readonly IUserManager _userManager;
public FlowBeforeService(IFlowTaskRepository flowTaskRepository, IFlowTaskManager flowTaskManager, IUserManager userManager)
{
_flowTaskRepository = flowTaskRepository;
_flowTaskManager = flowTaskManager;
_userManager = userManager;
}
#region Get
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <param name="category">分类.</param>
/// <returns></returns>
[HttpGet("List/{category}")]
public async Task<dynamic> GetList([FromQuery] FlowBeforeListQuery input, string category)
{
try
{
switch (category)
{
case "1":
return await _flowTaskRepository.GetWaitList(input);
case "2":
return await _flowTaskRepository.GetTrialList(input);
case "3":
return await _flowTaskRepository.GetCirculateList(input);
case "4":
return await _flowTaskRepository.GetBatchWaitList(input);
default:
return PageResult<FlowBeforeListOutput>.SqlSugarPageResult(new SqlSugarPagedList<FlowBeforeListOutput>());
}
}
catch (Exception ex)
{
return PageResult<FlowBeforeListOutput>.SqlSugarPageResult(new SqlSugarPagedList<FlowBeforeListOutput>());
}
}
/// <summary>
/// 获取任务详情.
/// </summary>
/// <param name="id">任务id.</param>
/// <param name="flowId">流程id.</param>
/// <param name="taskNodeId">节点id.</param>
/// <param name="taskOperatorId">经办id.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id, [FromQuery] string flowId, [FromQuery] string taskNodeId, [FromQuery] string taskOperatorId)
{
try
{
return await _flowTaskManager.GetFlowBeforeInfo(id, flowId, taskNodeId, taskOperatorId);
}
catch (Exception ex)
{
throw Oops.Oh(ErrorCode.WF0033);
}
}
/// <summary>
/// 审批汇总.
/// </summary>
/// <param name="taskRecordId">主键值.</param>
/// <param name="category">分类1部门2角色3岗位.</param>
/// <returns></returns>
[HttpGet("RecordList/{taskRecordId}")]
public async Task<dynamic> GetRecordList(string taskRecordId, [FromQuery] string category, [FromQuery] string type)
{
var recordList = await _flowTaskRepository.GetRecordListByCategory(taskRecordId, category, type);
var categoryId = recordList.Select(x => x.category).Distinct().ToList();
var list = new List<FlowBeforeRecordListOutput>();
foreach (var item in categoryId)
{
var categoryList = recordList.FindAll(x => x.category == item).ToList();
var output = new FlowBeforeRecordListOutput();
output.fullName = categoryList.FirstOrDefault()?.categoryName;
output.list = categoryList.OrderByDescending(x => x.handleTime).ToList();
list.Add(output);
}
return list;
}
/// <summary>
/// 获取候选人编码.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Candidates/{taskOperatorId}")]
public async Task<dynamic> Candidates(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
if (taskOperatorId != "0")
{
var flowTaskParamter = await _flowTaskManager.Validation(taskOperatorId, flowHandleModel);
var flowEngine = _flowTaskRepository.GetFlowTemplateInfo(flowTaskParamter.flowTaskEntity.FlowId);
if (flowTaskParamter.flowTaskEntity.RejectDataId.IsNotEmptyOrNull())
{
return new List<FlowTaskCandidateModel>();
}
await _flowTaskManager.AdjustNodeByCon(flowEngine, flowHandleModel.formData, flowTaskParamter.flowTaskOperatorEntity);
}
return await _flowTaskManager.GetCandidateModelList(taskOperatorId, flowHandleModel);
}
/// <summary>
/// 获取候选人.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("CandidateUser/{taskOperatorId}")]
public async Task<dynamic> CandidateUser(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
return await _flowTaskManager.GetCandidateModelList(taskOperatorId, flowHandleModel, 1);
}
/// <summary>
/// 批量审批流程列表.
/// </summary>
/// <returns></returns>
[HttpGet("BatchFlowSelector")]
public async Task<dynamic> BatchFlowSelector()
{
return await _flowTaskRepository.BatchFlowSelector();
}
/// <summary>
/// 批量审批节点列表.
/// </summary>
/// <param name="flowId">流程id.</param>
/// <returns></returns>
[HttpGet("NodeSelector/{templateId}")]
public async Task<dynamic> NodeSelector(string templateId)
{
return await _flowTaskManager.NodeSelector(templateId);
}
/// <summary>
/// 批量审批候选人.
/// </summary>
/// <param name="flowId">流程id.</param>
/// <param name="taskOperatorId">经办id.</param>
/// <returns></returns>
[HttpGet("BatchCandidate")]
public async Task<dynamic> GetBatchCandidate([FromQuery] string flowId, [FromQuery] string taskOperatorId)
{
await _flowTaskManager.Validation(taskOperatorId, null);
return await _flowTaskManager.GetBatchCandidate(flowId, taskOperatorId);
}
/// <summary>
/// 验证站内信详情是否有查看权限.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <returns></returns>
[HttpGet("{taskOperatorId}/Info")]
public async Task<dynamic> IsInfo(string taskOperatorId)
{
var flowTaskOperatorEntity = await _flowTaskRepository.GetTaskOperatorInfo(taskOperatorId);
if (flowTaskOperatorEntity.IsNullOrEmpty())
throw Oops.Oh(ErrorCode.WF0029);
var flowTaskEntity = _flowTaskRepository.GetTaskFirstOrDefault(flowTaskOperatorEntity.TaskId);
if (flowTaskOperatorEntity.HandleId == _userManager.UserId)
{
if (flowTaskOperatorEntity.State == "-1" || flowTaskEntity.Status == 5)
throw Oops.Oh(ErrorCode.WF0029);
}
else
{
var toUserId = _flowTaskRepository.GetToUserId(flowTaskOperatorEntity.HandleId, flowTaskEntity.FlowId);
if (!toUserId.Contains(_userManager.UserId) || flowTaskOperatorEntity.State == "-1" || flowTaskEntity.Status == 5)
throw Oops.Oh(ErrorCode.WF0029);
}
// true 跳转抄送页面 false 审批页面
return new { isCheck = flowTaskOperatorEntity.Completion != 0 };
}
/// <summary>
/// 节点列表.
/// </summary>
/// <param name="taskId">任务id.</param>
/// <returns></returns>
[HttpGet("Selector/{taskId}")]
public async Task<dynamic> Selector(string taskId)
{
var nodeList = await _flowTaskRepository.GetTaskNodeList(x => x.TaskId == taskId && x.State == "0" && x.NodeType == "approver");
return nodeList.Select(x => new { id = x.Id, nodeName = x.NodeName }).ToList();
}
/// <summary>
/// 驳回节点列表.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <returns></returns>
[HttpGet("RejectList/{taskOperatorId}")]
public async Task<dynamic> RejectNodeList(string taskOperatorId)
{
return await _flowTaskManager.RejectNodeList(taskOperatorId);
}
#endregion
#region POST
/// <summary>
/// 审核同意.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Audit/{taskOperatorId}")]
public async Task<dynamic> Audit(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskManager.Validation(taskOperatorId, flowHandleModel);
return await _flowTaskManager.Audit(flowTaskParamter);
}
/// <summary>
/// 审核拒绝.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Reject/{taskOperatorId}")]
public async Task<dynamic> Reject(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByOperatorId(taskOperatorId, flowHandleModel);
if (_flowTaskManager.IsSubFlowUpNode(flowTaskParamter))
throw Oops.Oh(ErrorCode.WF0019);
return await _flowTaskManager.Reject(flowTaskParamter);
}
/// <summary>
/// 审批撤回.
/// 注意:在撤销流程时要保证你的下一节点没有处理这条记录;如已处理则无法撤销流程.
/// </summary>
/// <param name="taskRecordId">经办记录id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Recall/{taskRecordId}")]
public async Task Recall(string taskRecordId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskOperatorRecord = await _flowTaskRepository.GetTaskOperatorRecordInfo(taskRecordId);
if (await _flowTaskRepository.AnyFlowTask(x => x.ParentId == flowTaskOperatorRecord.TaskId && x.Status != FlowTaskStatusEnum.Cancel.ParseToInt() && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.WF0018);
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByOperatorId(flowTaskOperatorRecord.TaskOperatorId, flowHandleModel);
await _flowTaskManager.Recall(flowTaskParamter, flowTaskOperatorRecord);
}
/// <summary>
/// 终止审核.
/// </summary>
/// <param name="taskId">任务id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Cancel/{taskId}")]
public async Task Cancel(string taskId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByTaskId(taskId, flowHandleModel);
if (flowTaskParamter.flowTaskEntity.FlowType == 1)
throw Oops.Oh(ErrorCode.WF0016);
await _flowTaskManager.Cancel(flowTaskParamter);
}
/// <summary>
/// 转办.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Transfer/{taskOperatorId}")]
public async Task Transfer(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskManager.Validation(taskOperatorId, flowHandleModel);
await _flowTaskManager.Transfer(flowTaskParamter);
}
/// <summary>
/// 指派.
/// </summary>
/// <param name="taskId">任务id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Assign/{taskId}")]
public async Task Assigned(string taskId, [FromBody] FlowHandleModel flowHandleModel)
{
var nodeEntity = await _flowTaskRepository.GetTaskNodeList(x => x.TaskId == taskId && x.State.Equals("0") && FlowTaskNodeTypeEnum.subFlow.ParseToString().Equals(x.NodeType) && x.NodeCode.Equals(flowHandleModel.nodeCode));
if (nodeEntity.IsNotEmptyOrNull() && nodeEntity.Count > 0)
throw Oops.Oh(ErrorCode.WF0014);
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByTaskId(taskId, flowHandleModel);
flowTaskParamter.thisFlowTaskOperatorEntityList = await _flowTaskRepository.GetTaskOperatorList(x => x.State == "0" && x.NodeCode == flowHandleModel.nodeCode && x.TaskId == taskId);
await _flowTaskManager.Assigned(flowTaskParamter);
}
/// <summary>
/// 保存审批草稿数据.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("SaveAudit/{taskOperatorId}")]
[UnitOfWork]
public async Task SaveAudit(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskManager.Validation(taskOperatorId, flowHandleModel);
flowTaskParamter.flowTaskOperatorEntity.DraftData = flowHandleModel.formData.ToJsonString();
await _flowTaskRepository.UpdateTaskOperator(flowTaskParamter.flowTaskOperatorEntity);
}
/// <summary>
/// 批量审批.
/// </summary>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("BatchOperation")]
public async Task BatchOperation([FromBody] FlowHandleModel flowHandleModel)
{
foreach (var item in flowHandleModel.ids)
{
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByOperatorId(item, flowHandleModel);
flowTaskParamter.formData = await _flowTaskManager.GetBatchOperationData(flowTaskParamter);
flowHandleModel.formData = flowTaskParamter.formData;
switch (flowHandleModel.batchType)
{
case 0:
if (flowTaskParamter.flowTaskOperatorEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
if (flowTaskParamter.flowTaskOperatorEntity.Completion != 0)
throw Oops.Oh(ErrorCode.WF0006);
await _flowTaskManager.Audit(flowTaskParamter);
break;
case 1:
await Reject(item, flowHandleModel);
break;
case 2:
await Transfer(item, flowHandleModel);
break;
}
}
}
/// <summary>
/// 任务(变更/复活).
/// </summary>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("Change")]
public async Task<dynamic> Change([FromBody] FlowHandleModel flowHandleModel)
{
// 清除依次经办数据
await _flowTaskRepository.DeleteTaskOperatorUser(flowHandleModel.taskId);
_flowTaskRepository.DeleteFlowCandidates(x => x.TaskId == flowHandleModel.taskId);
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByTaskId(flowHandleModel.taskId, flowHandleModel);
return await _flowTaskManager.Change(flowTaskParamter);
}
/// <summary>
/// 加签.
/// </summary>
/// <param name="taskOperatorId">经办id.</param>
/// <param name="flowHandleModel">审批参数.</param>
/// <returns></returns>
[HttpPost("freeApprover/{taskOperatorId}")]
public async Task<dynamic> FreeApprover(string taskOperatorId, [FromBody] FlowHandleModel flowHandleModel)
{
return await Audit(taskOperatorId, flowHandleModel);
}
#endregion
}

View File

@@ -0,0 +1,117 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Filter;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Permission;
using JNPF.WorkFlow.Entitys.Dto.FlowComment;
using JNPF.WorkFlow.Entitys.Entity;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程评论.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowComment", Order = 304)]
[Route("api/workflow/Engine/[controller]")]
public class FlowCommentService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<FlowCommentEntity> _repository;
private readonly IUserManager _userManager;
public FlowCommentService(ISqlSugarRepository<FlowCommentEntity> repository, IUserManager userManager)
{
_repository = repository;
_userManager = userManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowCommentListQuery input)
{
var list = await _repository.AsSugarClient().Queryable<FlowCommentEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.CreatorUserId == b.Id))
.Where((a, b) => a.TaskId == input.taskId && a.DeleteMark == null).Select((a, b) => new FlowCommentListOutput()
{
id = a.Id,
taskId = a.TaskId,
text = a.Text,
image = a.Image,
file = a.File,
creatorUserId = b.Id,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
creatorUserHeadIcon = SqlFunc.MergeString("/api/File/Image/userAvatar/", b.HeadIcon),
isDel = SqlFunc.IIF(a.CreatorUserId == _userManager.UserId, true, false),
lastModifyTime = a.LastModifyTime,
}).MergeTable().OrderBy(a => a.creatorTime, OrderByType.Desc).OrderByIF(!string.IsNullOrEmpty(input.keyword), a => a.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowCommentListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 详情.
/// </summary>
/// <param name="id">主键id.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
return (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<FlowCommentInfoOutput>();
}
#endregion
#region Post
/// <summary>
/// 新增.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] FlowCommentCrInput input)
{
var entity = input.Adapt<FlowCommentEntity>();
var isOk = await _repository.AsInsertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 修改.
/// </summary>
/// <param name="id">主键id.</param>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] FlowCommentUpInput input)
{
var entity = input.Adapt<FlowCommentEntity>();
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键id.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
#endregion
}

View File

@@ -0,0 +1,281 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Dto.User;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Interfaces.Permission;
using JNPF.WorkFlow.Entitys.Dto.FlowDelegete;
using JNPF.WorkFlow.Entitys.Dto.FlowTemplate;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Interfaces.Repository;
using JNPF.WorkFlow.Interfaces.Service;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程委托.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowDelegate", Order = 300)]
[Route("api/workflow/Engine/[controller]")]
public class FlowDelegateService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<FlowDelegateEntity> _repository;
private readonly IFlowTemplateService _flowTemplateService;
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IOrganizeService _organizeService;
private readonly IUserManager _userManager;
public FlowDelegateService(ISqlSugarRepository<FlowDelegateEntity> repository, IFlowTemplateService flowTemplateService, IFlowTaskRepository flowTaskRepository, IOrganizeService organizeService, IUserManager userManager)
{
_repository = repository;
_flowTemplateService = flowTemplateService;
_flowTaskRepository = flowTaskRepository;
_organizeService = organizeService;
_userManager = userManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowDelegateQuery input)
{
var output = new SqlSugarPagedList<FlowDelegateEntity>();
if (input.myOrDelagateToMe.Equals("1"))
{
//var crUserList = new List<string>();
//if (!_userManager.IsAdministrator)
//{
// var orgIds = _userManager.DataScope.Select(x => x.organizeId).ToList();//分管组织id
// crUserList = await _repository.AsSugarClient().Queryable<UserRelationEntity>().Where(x => orgIds.Contains(x.ObjectId)).Select(x => x.UserId).ToListAsync();
// crUserList.Add(_userManager.UserId);
//}
//output = await _repository.AsQueryable().Where(x => x.DeleteMark == null).WhereIF(crUserList.Count > 0, x => crUserList.Contains(x.UserId))
//.WhereIF(!input.keyword.IsNullOrEmpty(), m => m.FlowName.Contains(input.keyword) || m.ToUserName.Contains(input.keyword)).OrderBy(t => t.SortCode)
//.OrderBy(x => x.CreatorTime, OrderByType.Desc).OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
output = await _repository.AsQueryable().Where(x => x.DeleteMark == null).Where(x => x.UserId == _userManager.UserId)
.WhereIF(!input.keyword.IsNullOrEmpty(), m => m.FlowName.Contains(input.keyword) || m.ToUserName.Contains(input.keyword)).OrderBy(t => t.SortCode)
.OrderBy(x => x.CreatorTime, OrderByType.Desc).OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
}
else
{
output = await _repository.AsQueryable().Where(x => x.ToUserId == _userManager.UserId && x.DeleteMark == null)
.WhereIF(!input.keyword.IsNullOrEmpty(), m => m.FlowName.Contains(input.keyword) || m.ToUserName.Contains(input.keyword)).OrderBy(t => t.SortCode)
.OrderBy(x => x.CreatorTime, OrderByType.Desc).OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
}
var pageList = new SqlSugarPagedList<FlowDelegeteListOutput>()
{
list = output.list.Adapt<List<FlowDelegeteListOutput>>(),
pagination = output.pagination
};
return PageResult<FlowDelegeteListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo_Api(string id)
{
return (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<FlowDelegeteInfoOutput>();
}
/// <summary>
/// 委托发起流程列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("getflow")]
public async Task<dynamic> GetFlowList([FromQuery] FlowTemplateListQuery input)
{
var output = new List<FlowTemplateTreeOutput>();
//委托给我的发起流程
var flowDelegateList = await _repository.GetListAsync(x => x.ToUserId == _userManager.UserId && x.Type == "0" && x.EndTime > DateTime.Now && x.StartTime < DateTime.Now && x.DeleteMark == null);
foreach (var item in flowDelegateList)
{
var flowList = await _flowTemplateService.GetFlowFormList(input.flowType.ParseToInt(), item.UserId);
// 非全部流程
if (item.FlowId.IsNotEmptyOrNull())
{
output = output.Union(flowList.FindAll(x => item.FlowId.Contains(x.templateId))).DistinctBy(x => x.id).ToList();
}
else
{
output = output.Union(flowList).DistinctBy(x => x.id).ToList();
}
}
if (input.keyword.IsNotEmptyOrNull())
output = output.FindAll(o => o.fullName.Contains(input.keyword) || o.enCode.Contains(input.keyword));
var pageList = new SqlSugarPagedList<FlowTemplateTreeOutput>()
{
list = output.Skip((input.currentPage - 1) * input.pageSize).Take(input.pageSize).ToList(),
pagination = new Pagination()
{
CurrentPage = input.currentPage,
PageSize = input.pageSize,
Total = output.Count
}
};
return PageResult<FlowTemplateTreeOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 发起流程委托人.
/// </summary>
/// <param name="flowId">请求参数.</param>
/// <returns></returns>
[HttpGet("userList")]
public async Task<dynamic> GetFlowList([FromQuery] string flowId)
{
var output = new List<UserListOutput>();
var orgList = _organizeService.GetOrgListTreeName();
var flowJsonModel = _flowTaskRepository.GetFlowTemplateInfo(flowId);
// 委托给我的发起流程
var delagateToMeList = await _repository.GetListAsync(x => x.ToUserId == _userManager.UserId && x.Type == "0" && x.EndTime > DateTime.Now && x.StartTime < DateTime.Now && x.DeleteMark == null);
foreach (var item in delagateToMeList)
{
var isDelagateUser = false;
if (item.IsNotEmptyOrNull())
{
if (item.FlowId.IsNotEmptyOrNull())
{
// 非全部流程
isDelagateUser = item.FlowId.Contains(flowJsonModel.templateId);
}
else
{
// 全部流程
var flowList = await _flowTemplateService.GetFlowFormList(flowJsonModel.type.ParseToInt(), item.UserId);
isDelagateUser = flowList.Select(x => x.id).Contains(flowId);
}
}
if (isDelagateUser)
{
UserListOutput userListOutput = new UserListOutput();
var delagateUser = _repository.AsSugarClient().Queryable<UserEntity>().First(x => x.Id == item.UserId && x.EnabledMark == 1 && x.DeleteMark == null);
userListOutput.id = delagateUser.Id;
userListOutput.headIcon = string.Format("/api/File/Image/userAvatar/{0}", delagateUser.HeadIcon);
userListOutput.fullName = string.Format("{0}/{1}", delagateUser.RealName, delagateUser.Account);
userListOutput.organize = orgList.FirstOrDefault(x => x.Id == delagateUser.OrganizeId).Description;
output.Add(userListOutput);
}
}
return new { list = output };
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 新建.
/// </summary>
/// <param name="jd">新建参数.</param>
[HttpPost("")]
public async Task Create([FromBody] FlowDelegeteCrInput input)
{
await Validation(input.Adapt<FlowDelegeteUpInput>());
var entity = input.Adapt<FlowDelegateEntity>();
var isOk = await _repository.AsInsertable(entity).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="jd">修改参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] FlowDelegeteUpInput input)
{
await Validation(input.Adapt<FlowDelegeteUpInput>());
var entity = input.Adapt<FlowDelegateEntity>();
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
#endregion
/// <summary>
/// 委托验证.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task Validation(FlowDelegeteUpInput input)
{
if (input.userId.Equals(input.toUserId)) throw Oops.Oh(ErrorCode.WF0001);
//同委托人、被委托人、委托类型
var list = await _repository.GetListAsync(x => x.UserId == input.userId && x.ToUserId == input.toUserId && x.Type == input.type && x.Id != input.id && x.DeleteMark == null);
if (list.Any())
{
//同一时间段内
list = list.FindAll(x => !((x.StartTime > input.startTime && x.StartTime > input.endTime) || (x.EndTime < input.startTime && x.EndTime < input.endTime)));
if (list.Any())
{
if (list.Any(x => x.FlowId.IsNullOrEmpty()) || input.flowId.IsNullOrEmpty())
{
throw Oops.Oh(ErrorCode.WF0041);
}
else
{
//非全部流程看存不存在相同流程
foreach (var item in input.flowId.Split(","))
{
if (list.Any(x => x.FlowId.Contains(item))) throw Oops.Oh(ErrorCode.WF0041);
}
}
}
}
var list1 = await _repository.GetListAsync(x => x.UserId == input.toUserId && x.ToUserId == input.userId && x.Type == input.type && x.Id != input.id && x.DeleteMark == null);
if (list1.Any())
{
//同一时间段内
list1 = list1.FindAll(x => !((x.StartTime > input.startTime && x.StartTime > input.endTime) || (x.EndTime < input.startTime && x.EndTime < input.endTime)));
if (list1.Any())
{
if (list1.Any(x => x.FlowId.IsNullOrEmpty()) || input.flowId.IsNullOrEmpty())
{
throw Oops.Oh(ErrorCode.WF0042);
}
else
{
//非全部流程看存不存在相同流程
foreach (var item in input.flowId.Split(","))
{
if (list1.Any(x => x.FlowId.Contains(item))) throw Oops.Oh(ErrorCode.WF0042);
}
}
}
}
}
}

View File

@@ -0,0 +1,713 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev.Engine.Core;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using JNPF.WorkFlow.Entitys.Dto.FlowEngine;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Entitys.Model.Properties;
using JNPF.WorkFlow.Interfaces.Repository;
using JNPF.WorkFlow.Interfaces.Service;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程设计.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowEngine", Order = 301)]
[Route("api/workflow/Engine/[controller]")]
public class FlowEngineService : IFlowEngineService, IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<FlowEngineEntity> _repository;
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IUserManager _userManager;
private readonly IFileManager _fileManager;
private readonly IDataBaseManager _dataBaseManager;
private readonly ITenant _db;
public FlowEngineService(
ISqlSugarRepository<FlowEngineEntity> repository,
IFlowTaskRepository flowTaskRepository,
IDictionaryDataService dictionaryDataService,
IRunService runService,
IVisualDevService visualDevService,
IUserManager userManager,
IFileManager fileManager,
IDataBaseManager dataBaseManager,
ISqlSugarClient context)
{
_repository = repository;
_flowTaskRepository = flowTaskRepository;
_dictionaryDataService = dictionaryDataService;
_runService = runService;
_visualDevService = visualDevService;
_userManager = userManager;
_fileManager = fileManager;
_dataBaseManager = dataBaseManager;
_db = context.AsTenant();
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowEngineListInput input)
{
var list = await _repository.AsSugarClient().Queryable<FlowEngineEntity, DictionaryDataEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Category == b.EnCode))
.Where((a, b) => a.DeleteMark == null && b.DictionaryTypeId == "507f4f5df86b47588138f321e0b0dac7")
.Where(a => !(a.FormType == 2 && a.Type == 1))
.WhereIF(input.category.IsNotEmptyOrNull(), a => a.Category == input.category)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select((a, b) => new FlowEngineListAllOutput
{
category = b.FullName,
id = a.Id,
description = a.Description,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = a.EnCode,
enabledMark = a.EnabledMark,
flowTemplateJson = a.FlowTemplateJson,
formData = a.FormTemplateJson,
fullName = a.FullName,
formType = a.FormType,
icon = a.Icon,
iconBackground = a.IconBackground,
lastModifyTime = a.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = a.Type,
visibleType = a.VisibleType,
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowEngineListAllOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 列表(树形).
/// </summary>
/// <returns></returns>
[HttpGet("ListAll")]
public async Task<dynamic> GetListAll()
{
var list1 = await GetFlowFormList();
var dicDataInfo = await _dictionaryDataService.GetInfo(list1.First().parentId);
var dicDataList = await _dictionaryDataService.GetList(dicDataInfo.DictionaryTypeId);
var list2 = new List<FlowEngineListOutput>();
foreach (var item in dicDataList)
{
list2.Add(new FlowEngineListOutput()
{
fullName = item.FullName,
parentId = "0",
id = item.Id,
num = list1.FindAll(x => x.category == item.EnCode).Count
});
}
var output = list1.Union(list2).ToList().ToTree();
return new { list = output };
}
/// <summary>
/// 列表(分页).
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("PageListAll")]
public async Task<dynamic> GetListPageAll([FromQuery] FlowEngineListInput input)
{
var data = await GetFlowFormList();
if (input.category.IsNotEmptyOrNull())
data = data.FindAll(x => x.category == input.category);
if (input.keyword.IsNotEmptyOrNull())
data = data.FindAll(o => o.fullName.Contains(input.keyword) || o.enCode.Contains(input.keyword));
var pageList = new SqlSugarPagedList<FlowEngineListOutput>()
{
list = data.Skip((input.currentPage - 1)* input.pageSize).Take(input.pageSize).ToList(),
pagination = new Pagination()
{
CurrentPage = input.currentPage,
PageSize = input.pageSize,
Total = data.Count
}
};
return PageResult<FlowEngineListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo_Api(string id)
{
return (await GetInfo(id)).Adapt<FlowEngineInfoOutput>();
}
/// <summary>
/// 列表(子流程选择流程).
/// </summary>
/// <param name="type">(预留字段).</param>
/// <returns></returns>
[HttpGet("Selector")]
public async Task<dynamic> ListSelect([FromQuery] int type)
{
var list1 = await GetOutList();
if (type.IsEmpty())
list1 = list1.FindAll(x => x.formType == type);
var dicDataInfo = await _dictionaryDataService.GetInfo(list1.First().parentId);
var dicDataList = (await _dictionaryDataService.GetList(dicDataInfo.DictionaryTypeId)).FindAll(x => x.EnabledMark == 1);
var list2 = new List<FlowEngineListOutput>();
foreach (var item in dicDataList)
{
var index = list1.FindAll(x => x.category == item.EnCode).Count;
if (index > 0)
{
list2.Add(new FlowEngineListOutput()
{
fullName = item.FullName,
parentId = "0",
id = item.Id,
num = index
});
}
}
var output = list1.Union(list2).ToList().ToTree();
return new { list = output };
}
/// <summary>
/// 表单主表属性.
/// </summary>
/// <param name="id">主键.</param>
/// <returns></returns>
[HttpGet("{id}/FormDataFields")]
public async Task<dynamic> getFormDataField(string id)
{
var entity = await GetInfo(id);
List<FlowEngineFieldOutput> formDataFieldList = new List<FlowEngineFieldOutput>();
if (entity.FormType == 1)
{
var dicList = entity.FormTemplateJson.ToList<Dictionary<string, object>>();
formDataFieldList = dicList.Select(x =>
new FlowEngineFieldOutput()
{
vmodel = x.ContainsKey("filedId") ? x["filedId"].ToString() : string.Empty,
label = x.ContainsKey("filedName") ? x["filedName"].ToString() : string.Empty
}).ToList();
}
else
{
var formTemplateBase = new TemplateParsingBase(entity.FormTemplateJson, entity.Tables, true);
formDataFieldList = formTemplateBase.SingleFormData
.Where(x => x.__config__.jnpfKey != "relationForm" && x.__config__.jnpfKey != "relationFlow")
.Select(x => new FlowEngineFieldOutput() { vmodel = x.__vModel__, label = x.__config__.label }).ToList();
}
return new { list = formDataFieldList };
}
/// <summary>
/// 表单列表.
/// </summary>
/// <param name="id">流程id.</param>
/// <returns></returns>
[HttpGet("{id}/FieldDataSelect")]
public async Task<dynamic> getFormData(string id)
{
var flowTaskList = await _flowTaskRepository.GetTaskList(id);
return flowTaskList.Select(x => new FlowEngineListSelectOutput()
{
id = x.Id,
fullName = SqlFunc.MergeString(x.FullName, "/", x.EnCode)
}).ToList();
}
/// <summary>
/// 导出.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}/Actions/ExportData")]
public async Task<dynamic> ActionsExport(string id)
{
var importModel = new FlowEngineImportOutput();
importModel.flowEngine = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
importModel.visibleList = await _repository.AsSugarClient().Queryable<FlowEngineVisibleEntity>().Where(x => x.FlowId == id).ToListAsync();
var jsonStr = importModel.ToJsonString();
return await _fileManager.Export(jsonStr, importModel.flowEngine.FullName, ExportFileType.ffe);
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var flowEngineEntity = await GetInfo(id);
if (flowEngineEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
if (await _flowTaskRepository.AnyFlowTask(x => x.DeleteMark == null && x.FlowId == id))
throw Oops.Oh(ErrorCode.WF0024);
_db.BeginTran();
await _repository.AsSugarClient().Deleteable<FlowEngineVisibleEntity>(a => a.FlowId == flowEngineEntity.Id).ExecuteCommandHasChangeAsync();
var isOk = await _repository.AsUpdateable(flowEngineEntity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
_db.CommitTran();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] FlowEngineCrInput input)
{
if (await _repository.IsAnyAsync(x => (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
if (input.formType == 2)
{
var formTemplateBase = new TemplateParsingBase(input.formData, input.tables, true);
if (!formTemplateBase.VerifyTemplate())
throw Oops.Oh(ErrorCode.D1401);
}
var flowEngineEntity = input.Adapt<FlowEngineEntity>();
flowEngineEntity.Version = "1";
var flowVisibleList = GetFlowEngineVisibleList(input.flowTemplateJson);
var result = await Create(flowEngineEntity, flowVisibleList);
_ = result ?? throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] FlowEngineUpInput input)
{
if (await _repository.IsAnyAsync(x => x.Id != id && (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
if (input.formType == 2)
{
var formTemplateBase = new TemplateParsingBase(input.formData, input.tables, true);
if (!formTemplateBase.VerifyTemplate())
throw Oops.Oh(ErrorCode.D1401);
}
var flowEngineEntity = input.Adapt<FlowEngineEntity>();
flowEngineEntity.Version = ((await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Version.ParseToInt() + 1).ToString();
var flowVisibleList = GetFlowEngineVisibleList(input.flowTemplateJson);
var isOk = await Update(flowEngineEntity, flowVisibleList);
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 复制.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("{id}/Actions/Copy")]
public async Task ActionsCopy(string id)
{
var entity = await GetInfo(id);
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
entity.FullName = string.Format("{0}副本{1}", entity.FullName, random);
entity.EnCode = string.Format("{0}{1}", entity.EnCode, random);
entity.Version = "1";
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
throw Oops.Oh(ErrorCode.COM1009);
var flowVisibleList = GetFlowEngineVisibleList(entity.FlowTemplateJson);
var result = await Create(entity, flowVisibleList);
_ = result ?? throw Oops.Oh(ErrorCode.WF0002);
}
/// <summary>
/// 导入.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost("Actions/ImportData")]
public async Task ActionsImport(IFormFile file)
{
var fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
if (!fileType.ToLower().Equals(ExportFileType.ffe.ToString()))
throw Oops.Oh(ErrorCode.D3006);
var josn = _fileManager.Import(file);
FlowEngineImportOutput model;
try
{
model = josn.ToObject<FlowEngineImportOutput>();
}
catch
{
throw Oops.Oh(ErrorCode.D3006);
}
if (model == null)
throw Oops.Oh(ErrorCode.D3006);
await ImportData(model);
}
/// <summary>
/// 发布.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Release/{id}")]
public async Task Release(string id)
{
var entity = await GetInfo(id);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable<FlowEngineEntity>().SetColumns(it => it.EnabledMark == 1).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
/// <summary>
/// 停止.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Stop/{id}")]
public async Task Stop(string id)
{
var entity = await GetInfo(id);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable<FlowEngineEntity>().SetColumns(it => it.EnabledMark == 0).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
#endregion
#region PublicMethod
/// <summary>
/// 发起列表.
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<List<FlowEngineListOutput>> GetFlowFormList()
{
var list = await GetOutList();
if (_userManager.User.IsAdministrator == 0)
{
var data = await GetVisibleFlowList();
data = data.Union(list.FindAll(x => x.visibleType == 0)).ToList();
return data;
}
else
{
return list;
}
}
#endregion
#region PrivateMethod
/// <summary>
/// 详情.
/// </summary>
/// <param name="id">主键.</param>
/// <returns></returns>
[NonAction]
private async Task<FlowEngineEntity> GetInfo(string id)
{
return await _repository.GetFirstAsync(a => a.Id == id && a.DeleteMark == null);
}
/// <summary>
/// 新增流程.
/// </summary>
/// <param name="entity">流程实例.</param>
/// <param name="visibleList">可见范围.</param>
/// <returns></returns>
[NonAction]
private async Task<FlowEngineEntity> Create(FlowEngineEntity entity, List<FlowEngineVisibleEntity> visibleList)
{
try
{
_db.BeginTran();
entity.VisibleType = visibleList.Count == 0 ? 0 : 1;
entity.Id = SnowflakeIdHelper.NextId();
foreach (var item in visibleList)
{
item.FlowId = entity.Id;
item.SortCode = visibleList.IndexOf(item);
}
if (visibleList.Count > 0)
await _repository.AsSugarClient().Insertable(visibleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (entity.FormType == 2)
{
// 无表转有表
if (entity.Tables.IsNullOrEmpty() || entity.Tables == "[]")
{
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
// 主表名称
var mTableName = "wform_" + entity.EnCode + "_" + random;
var devEntity = new VisualDevEntity()
{
//FlowId = entity.Id,
FormData = entity.FormTemplateJson,
};
var res = await _visualDevService.NoTblToTable(devEntity, mTableName);
entity.Tables = res.Tables;
entity.FormTemplateJson = res.FormData;
}
}
var result = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
if (result == null)
throw Oops.Oh(ErrorCode.COM1005);
_db.CommitTran();
return result;
}
catch (Exception ex)
{
_db.RollbackTran();
return null;
}
}
/// <summary>
/// 修改流程.
/// </summary>
/// <param name="entity">流程实体.</param>
/// <param name="visibleList">可见范围.</param>
/// <returns></returns>
[NonAction]
private async Task<bool> Update(FlowEngineEntity entity, List<FlowEngineVisibleEntity> visibleList)
{
try
{
_db.BeginTran();
entity.VisibleType = visibleList.Count == 0 ? 0 : 1;
await _repository.AsSugarClient().Deleteable<FlowEngineVisibleEntity>(a => a.FlowId == entity.Id).ExecuteCommandHasChangeAsync();
foreach (var item in visibleList)
{
item.FlowId = entity.Id;
item.SortCode = visibleList.IndexOf(item);
}
if (visibleList.Count > 0)
await _repository.AsSugarClient().Insertable(visibleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (entity.FormType == 2)
{
#region
//无表转有表
var mTableName = "wform_" + entity.EnCode;//主表名称
if (entity.Tables.IsNullOrEmpty() || entity.Tables == "[]")
{
var devEntity = new VisualDevEntity()
{
//FlowId = entity.Id,
FormData = entity.FormTemplateJson
};
var res = await _visualDevService.NoTblToTable(devEntity, mTableName);
entity.Tables = res.Tables;
entity.FormTemplateJson = res.FormData;
var entityData = await _runService.GetInfo(entity.Id);
if (entityData != null && entityData.Data != null)
{
var sqlList = _visualDevService.DataToInsertSql(mTableName, entityData.Data);
if (sqlList.Any())
{
var link = await _flowTaskRepository.GetLinkInfo(entity.DbLinkId) ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
foreach (var item in sqlList)
{
await _dataBaseManager.ExecuteSql(link, item);
}
}
}
}
#endregion
}
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
_db.CommitTran();
return isOk;
}
catch (Exception ex)
{
_db.RollbackTran();
return false;
}
}
/// <summary>
/// 解析流程可见参数.
/// </summary>
/// <param name="josnStr"></param>
/// <returns></returns>
private List<FlowEngineVisibleEntity> GetFlowEngineVisibleList(string josnStr)
{
var output = new List<FlowEngineVisibleEntity>();
// 发起节点属性.
var pro = josnStr.ToObject<FlowTemplateJsonModel>().properties.ToObject<StartProperties>();
if (pro.initiator != null && pro.initiator.Count > 0)
{
var list = pro.initiator.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "user" }).ToList();
output.AddRange(list);
}
if (pro.initiatePos != null && pro.initiatePos.Count > 0)
{
var list = pro.initiatePos.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Position" }).ToList();
output.AddRange(list);
}
if (pro.initiateRole != null && pro.initiateRole.Count > 0)
{
var list = pro.initiateRole.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Role" }).ToList();
output.AddRange(list);
}
return output;
}
/// <summary>
/// 获取当前用户可见流程.
/// </summary>
/// <returns></returns>
[NonAction]
private async Task<List<FlowEngineListOutput>> GetVisibleFlowList()
{
return await _repository.AsSugarClient().Queryable<FlowEngineVisibleEntity, UserRelationEntity, FlowEngineEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.OperatorId == b.ObjectId, JoinType.Left, a.FlowId == c.Id))
.Where((a, b, c) => (a.OperatorId == _userManager.UserId || b.UserId == _userManager.UserId) && c.DeleteMark == null && c.EnabledMark == 1 && c.Type == 0)
.Select((a, b, c) => new FlowEngineListOutput
{
category = c.Category,
id = c.Id,
description = c.Description,
creatorTime = c.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == c.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = c.EnCode,
enabledMark = c.EnabledMark,
flowTemplateJson = c.FlowTemplateJson,
formData = c.FormTemplateJson,
fullName = c.FullName,
formType = c.FormType,
icon = c.Icon,
iconBackground = c.IconBackground,
lastModifyTime = c.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == c.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = c.Type,
visibleType = c.VisibleType,
parentId = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(d => d.EnCode == c.Category && d.DictionaryTypeId== "507f4f5df86b47588138f321e0b0dac7").Select(d => d.Id),
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderBy(a => a.lastModifyTime, OrderByType.Desc).ToListAsync();
}
/// <summary>
/// 流程列表(功能流程不显示).
/// </summary>
/// <returns></returns>
private async Task<List<FlowEngineListOutput>> GetOutList()
{
return await _repository.AsSugarClient().Queryable<FlowEngineEntity, DictionaryDataEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Category == b.EnCode))
.Where((a, b) => a.DeleteMark == null && a.EnabledMark == 1 && a.Type == 0 && b.DictionaryTypeId == "507f4f5df86b47588138f321e0b0dac7")
.Select((a, b) => new FlowEngineListOutput
{
category = a.Category,
id = a.Id,
description = a.Description,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = a.EnCode,
enabledMark = a.EnabledMark,
flowTemplateJson = a.FlowTemplateJson,
formData = a.FormTemplateJson,
fullName = a.FullName,
formType = a.FormType,
icon = a.Icon,
iconBackground = a.IconBackground,
lastModifyTime = a.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = a.Type,
visibleType = a.VisibleType,
parentId = b.Id
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderBy(a => a.lastModifyTime, OrderByType.Desc).ToListAsync();
}
/// <summary>
/// 导入数据.
/// </summary>
/// <param name="model">导入实例.</param>
/// <returns></returns>
private async Task ImportData(FlowEngineImportOutput model)
{
try
{
_db.BeginTran();
// 存在更新不存在插入 根据主键
var stor = _repository.AsSugarClient().Storageable(model.flowEngine).Saveable().ToStorage();
// 执行插入
await stor.AsInsertable.ExecuteCommandAsync();
// await stor.AsUpdateable.ExecuteCommandAsync(); //执行更新停用原因Oracle 数据库环境会抛异常ora-01704: 字符串文字太长
// 执行更新
await _repository.AsSugarClient().Updateable(model.flowEngine).ExecuteCommandAsync();
// 存在更新不存在插入 根据主键
var stor1 = _repository.AsSugarClient().Storageable(model.visibleList).Saveable().ToStorage();
// 执行插入
await stor1.AsInsertable.ExecuteCommandAsync();
// 执行更新
await stor1.AsUpdateable.ExecuteCommandAsync();
_db.CommitTran();
}
catch (Exception ex)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.D3006);
}
}
#endregion
}

View File

@@ -0,0 +1,483 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Model.DataBase;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev.Engine.Core;
using JNPF.VisualDev.Interfaces;
using JNPF.WorkFlow.Entitys.Dto.FlowEngine;
using JNPF.WorkFlow.Entitys.Dto.FlowForm;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Interfaces.Repository;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程设计.
/// </summary>
[ApiDescriptionSettings(Tag = "FlowForm", Name = "Form", Order = 301)]
[Route("api/flowForm/Form")]
public class FlowFormService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<FlowFormEntity> _repository;
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IUserManager _userManager;
private readonly IFileManager _fileManager;
private readonly IDataBaseManager _dataBaseManager;
private readonly ITenant _db;
public FlowFormService(
ISqlSugarRepository<FlowFormEntity> repository,
IRunService runService,
IVisualDevService visualDevService,
IUserManager userManager,
IFileManager fileManager,
IDataBaseManager dataBaseManager,
ISqlSugarClient context)
{
_repository = repository;
_runService = runService;
_visualDevService = visualDevService;
_userManager = userManager;
_fileManager = fileManager;
_dataBaseManager = dataBaseManager;
_db = context.AsTenant();
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowEngineListInput input)
{
var list = await _repository.AsQueryable()
.Where(a => a.DeleteMark == null && !(a.FormType == 2 && a.FlowType == 1))
.WhereIF(input.category.IsNotEmptyOrNull(), a => a.Category == input.category)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select(a => new FlowFormListOutput
{
id = a.Id,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = a.EnCode,
enabledMark = a.EnabledMark,
fullName = a.FullName,
formType = a.FormType,
flowType = a.FlowType,
lastModifyTime = a.LastModifyTime,
sortCode = a.SortCode,
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowFormListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo_Api(string id)
{
var entity = await GetInfo(id);
var res = entity.Adapt<FlowFormListOutput>();
var draft = entity.DraftJson?.ToObject<FlowFormEntity>().Adapt<FlowFormListOutput>();
res.propertyJson = entity.PropertyJson;
res.draftJson = draft != null && draft.propertyJson.IsNotEmptyOrNull() ? draft?.propertyJson : entity.PropertyJson;
return res;
}
/// <summary>
/// 列表(下拉).
/// </summary>
/// <param name="type">(预留字段).</param>
/// <returns></returns>
[HttpGet("Select")]
public async Task<dynamic> Select([FromQuery] FlowEngineListInput input)
{
var list = await _repository.AsSugarClient().Queryable<FlowFormEntity>()
.Where(a => a.DeleteMark == null && a.EnabledMark.Equals(1) && a.FlowType == input.flowType)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select(a => new FlowFormListOutput
{
category = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(it => it.EnCode.Equals(a.Category)).Select(it => it.FullName),
id = a.Id,
description = a.Description,
creatorTime = a.CreatorTime,
enCode = a.EnCode,
enabledMark = a.EnabledMark,
fullName = a.FullName,
formType = a.FormType,
flowType = a.FlowType,
sortCode = a.SortCode,
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowFormListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 导出.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}/Actions/ExportData")]
public async Task<dynamic> ActionsExport(string id)
{
var info = await GetInfo(id);
info.DraftJson = info.ToJsonString();
var jsonStr = info.ToJsonString();
return await _fileManager.Export(jsonStr, info.FullName, ExportFileType.fff);
}
/// <summary>
/// 复制.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}/Actions/Copy")]
public async Task ActionsCopy(string id)
{
var entity = await GetInfo(id);
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
entity.Id = SnowflakeIdHelper.NextId();
entity.FullName = string.Format("{0}副本{1}", entity.FullName, random);
entity.EnCode = string.Format("{0}{1}", entity.EnCode, random);
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
throw Oops.Oh(ErrorCode.COM1009);
entity.EnabledMark = 0;
//entity.TableJson = "[]";
entity.DraftJson = entity.ToJsonString();
var result = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
_ = result ?? throw Oops.Oh(ErrorCode.WF0002);
}
/// <summary>
/// 根据表单Id 获取流程信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("GetFormById/{id}")]
public async Task<dynamic> GetFormById(string id)
{
var entity = await GetInfo(id);
if (entity == null || entity.EnabledMark != 1) throw Oops.Oh(ErrorCode.COM1016);
var tempId = _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().Where(x => x.Id.Equals(entity.FlowId)).Select(x => x.TemplateId).First();
if (tempId == null) throw Oops.Oh(ErrorCode.COM1016);
if (!_repository.AsSugarClient().Queryable<FlowTemplateEntity>().Where(x => x.Id.Equals(tempId) && x.EnabledMark.Equals(1)).Any()) throw Oops.Oh(ErrorCode.COM1017);
var res = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity, FlowTemplateEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id))
.Select((a, b) => new
{
id = SqlFunc.IIF(b.EnabledMark == 0, null, a.Id),
enCode = b.EnCode,
}).MergeTable().FirstAsync(a => a.id.Equals(entity.FlowId));
if (res == null) throw Oops.Oh(ErrorCode.COM1016);
return res;
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var flowFormEntity = await GetInfo(id);
if (flowFormEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
if (await _repository.AsSugarClient().Queryable<FlowFormRelationEntity>().Where(x => x.FormId.Equals(id)).AnyAsync())
throw Oops.Oh(ErrorCode.COM1012);
var isOk = await _repository.AsSugarClient().Updateable(flowFormEntity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Deleteable<FlowFormRelationEntity>().Where(x => x.FormId.Equals(id)).ExecuteCommandAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] FlowEngineCrInput input)
{
if (await _repository.IsAnyAsync(x => (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var flowFormEntity = input.Adapt<FlowFormEntity>();
flowFormEntity.Id = SnowflakeIdHelper.NextId();
flowFormEntity.EnabledMark = 0;
flowFormEntity.PropertyJson = flowFormEntity.DraftJson;
flowFormEntity.DraftJson = flowFormEntity.ToJsonString();
if (input.formType.Equals(2) && input.draftJson.IsNotEmptyOrNull())
{
TemplateParsingBase? tInfo = new TemplateParsingBase(flowFormEntity.PropertyJson, flowFormEntity.TableJson); // 解析模板
if (!tInfo.VerifyTemplate()) throw Oops.Oh(ErrorCode.D1401); // 验证模板
await VerifyPrimaryKeyPolicy(tInfo, flowFormEntity.DbLinkId); // 验证雪花Id 和自增长Id 主键是否支持
}
var result = await _repository.AsSugarClient().Insertable(flowFormEntity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
_ = result ?? throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPut("")]
public async Task Update([FromBody] FlowEngineUpInput input)
{
if (await _repository.IsAnyAsync(x => x.Id != input.id && (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
if (await _repository.AsQueryable().AnyAsync(x => x.Id.Equals(input.id) && x.EnabledMark.Equals(1) && x.FormType == 2))
{
if (input.tableJson.IsNullOrWhiteSpace() || input.tableJson.Equals("[]"))
throw Oops.Oh(ErrorCode.D1416); // 已发布的模板 表不能为空.
input.enabledMark = 1;
}
var isOk = false;
var fEntity = input.Adapt<FlowFormEntity>();
if (fEntity != null)
{
if (input.formType.Equals(2) && input.draftJson.IsNotEmptyOrNull())
{
TemplateParsingBase? tInfo = new TemplateParsingBase(fEntity.DraftJson, fEntity.TableJson); // 解析模板
if (!tInfo.VerifyTemplate()) throw Oops.Oh(ErrorCode.D1401); // 验证模板
await VerifyPrimaryKeyPolicy(tInfo, fEntity.DbLinkId); // 验证雪花Id 和自增长Id 主键是否支持
}
// EnabledMark=0 未发布EnabledMark=1 已发布
if (fEntity.EnabledMark.Equals(0))
{
fEntity.PropertyJson = fEntity.DraftJson;
fEntity.DraftJson = fEntity.ToJsonString();
// 修改流程表单
isOk = await _repository.AsSugarClient().Updateable(fEntity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
}
else
{
var nEntity = await _repository.AsSugarClient().Queryable<FlowFormEntity>().Where(x => x.Id.Equals(input.id)).FirstAsync();
fEntity.PropertyJson = fEntity.DraftJson;
nEntity.DraftJson = fEntity.ToJsonString();
nEntity.FullName = fEntity.FullName;
nEntity.EnCode = fEntity.EnCode;
nEntity.SortCode = fEntity.SortCode;
nEntity.Description = fEntity.Description;
nEntity.TableJson = fEntity.TableJson;
nEntity.DbLinkId = fEntity.DbLinkId;
nEntity.AppUrlAddress = fEntity.AppUrlAddress;
nEntity.UrlAddress = fEntity.UrlAddress;
nEntity.InterfaceUrl = fEntity.InterfaceUrl;
// 修改流程表单
isOk = await _repository.AsSugarClient().Updateable(nEntity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
}
}
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 导入.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost("Actions/ImportData")]
public async Task ActionsImport(IFormFile file)
{
var fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
if (!fileType.ToLower().Equals(ExportFileType.fff.ToString()))
throw Oops.Oh(ErrorCode.D3006);
var josn = _fileManager.Import(file);
var model = new FlowFormEntity();
try
{
model = josn.ToObject<FlowFormEntity>();
}
catch
{
throw Oops.Oh(ErrorCode.D3006);
}
if (model == null)
throw Oops.Oh(ErrorCode.D3006);
await ImportData(model);
}
/// <summary>
/// 发布.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Release/{id}")]
public async Task Release(string id, [FromQuery] int isRelease)
{
var entity = await GetInfo(id);
// 0 回滚表单 , 1 发布表单.
if (isRelease.Equals(0))
{
if (entity == null) throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(it => it.DraftJson == entity.ToJsonString()).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
if (!isOk) throw Oops.Oh(ErrorCode.COM1003);
}
else
{
if (entity == null || entity.PropertyJson.IsNullOrEmpty()) throw Oops.Oh(ErrorCode.COM1013);
var newEntity = entity.DraftJson.ToObject<FlowFormEntity>();
if (newEntity == null)
{
newEntity = entity;
}
entity.TableJson = newEntity.TableJson;
entity.PropertyJson = newEntity.PropertyJson;
if (entity.FormType == 2)
{
// 无表转有表
if (entity.TableJson.IsNullOrEmpty() || entity.TableJson == "[]")
{
// 主表名称
var mTableName = "wf_" + entity.EnCode;
if (mTableName.Length > 24) mTableName = "wf_" + SnowflakeIdHelper.NextId();
var devEntity = new VisualDev.Entitys.VisualDevEntity()
{
Id = entity.Id,
State = 1,
WebType = 3,
FullName = entity.FullName,
EnCode = entity.EnCode,
FormData = entity.PropertyJson
};
var res = await _visualDevService.NoTblToTable(devEntity, mTableName);
if (res == null) throw Oops.Oh(ErrorCode.COM1000);
entity.TableJson = res.Tables;
entity.PropertyJson = res.FormData;
//await _repository.AsSugarClient().Insertable(res).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
}
//else if (await _repository.AsSugarClient().Queryable<VisualDev.Entitys.VisualDevEntity>().Where(x => x.Id.Equals(id)).AnyAsync())
//await _repository.AsSugarClient().Updateable<VisualDev.Entitys.VisualDevEntity>().SetColumns(it => it.IsRelease == 1).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
}
entity.DraftJson = entity.ToJsonString();
entity.EnabledMark = 1;
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(x => x.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk) throw Oops.Oh(ErrorCode.COM1003);
}
}
/// <summary>
/// 回滚.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Stop/{id}")]
public async Task Stop(string id)
{
var entity = await GetInfo(id);
}
#endregion
#region PrivateMethod
/// <summary>
/// 详情.
/// </summary>
/// <param name="id">主键.</param>
/// <returns></returns>
[NonAction]
private async Task<FlowFormEntity> GetInfo(string id)
{
return await _repository.GetFirstAsync(a => a.Id == id && a.DeleteMark == null);
}
/// <summary>
/// 导入数据.
/// </summary>
/// <param name="model">导入实例.</param>
/// <returns></returns>
private async Task ImportData(FlowFormEntity entity)
{
if (await _repository.IsAnyAsync(x => (x.EnCode.Equals(entity.EnCode) || x.FullName.Equals(entity.FullName)) && x.DeleteMark == null)) throw Oops.Oh(ErrorCode.COM1004);
// 在线开发生成导入版本自带ID
//entity.Id = SnowflakeIdHelper.NextId();
try
{
_db.BeginTran();
// 存在更新不存在插入 根据主键
var stor = _repository.AsSugarClient().Storageable(entity).Saveable().ToStorage();
// 执行插入
await stor.AsInsertable.ExecuteCommandAsync();
// await stor.AsUpdateable.ExecuteCommandAsync(); //执行更新停用原因Oracle 数据库环境会抛异常ora-01704: 字符串文字太长
// 执行更新
await _repository.AsSugarClient().Updateable(entity).ExecuteCommandAsync();
_db.CommitTran();
}
catch (Exception ex)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.D3006);
}
}
/// <summary>
/// 验证主键策略 数据库表是否支持.
/// </summary>
/// <param name="tInfo">模板信息.</param>
/// <param name="dbLinkId">数据库连接id.</param>
private async Task VerifyPrimaryKeyPolicy(TemplateParsingBase tInfo, string dbLinkId)
{
if (tInfo.IsHasTable)
{
DbLinkEntity link = await _runService.GetDbLink(dbLinkId);
tInfo.AllTable.ForEach(item =>
{
var tableList = _dataBaseManager.GetFieldList(link, item.table); // 获取主表所有列
var mainPrimary = tableList.Find(t => t.primaryKey); // 主表主键
if (mainPrimary == null) throw Oops.Oh(ErrorCode.D1409, "主键为空", item.table);
if (tInfo.FormModel.primaryKeyPolicy.Equals(2) && !mainPrimary.identity)
{
throw Oops.Oh(ErrorCode.D1409, "自增长ID,没有自增标识", item.table);
}
if (tInfo.FormModel.primaryKeyPolicy.Equals(1) && !(mainPrimary.dataType.ToLower().Equals("string") || mainPrimary.dataType.ToLower().Equals("varchar") || mainPrimary.dataType.ToLower().Equals("nvarchar")))
throw Oops.Oh(ErrorCode.D1409, "雪花ID", item.table);
});
_dataBaseManager.ChangeDataBase(_dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName));
}
}
#endregion
}

View File

@@ -0,0 +1,97 @@
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.WorkFlow.Entitys.Dto.FlowLaunch;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Interfaces.Manager;
using JNPF.WorkFlow.Interfaces.Repository;
using Microsoft.AspNetCore.Mvc;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程发起.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowLaunch", Order = 305)]
[Route("api/workflow/Engine/[controller]")]
public class FlowLaunchService : IDynamicApiController, ITransient
{
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IFlowTaskManager _flowTaskManager;
public FlowLaunchService(IFlowTaskRepository flowTaskRepository, IFlowTaskManager flowTaskManager)
{
_flowTaskRepository = flowTaskRepository;
_flowTaskManager = flowTaskManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowLaunchListQuery input)
{
return await _flowTaskRepository.GetLaunchList(input);
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = _flowTaskRepository.GetTaskFirstOrDefault(id);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
if (!entity.ParentId.Equals("0") && entity.ParentId.IsNotEmptyOrNull())
throw Oops.Oh(ErrorCode.WF0003, entity.FullName);
if (entity.FlowType == 1)
throw Oops.Oh(ErrorCode.WF0012, entity.FullName);
await _flowTaskRepository.DeleteSubTask(entity);
var isOk = await _flowTaskRepository.DeleteTask(entity);
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 撤回
/// 注意:在撤回流程时要保证你的下一节点没有处理这条记录;如已处理则无法撤销流程.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">流程经办.</param>
/// <returns></returns>
[HttpPut("{id}/Actions/Withdraw")]
public async Task Revoke(string id, [FromBody] FlowHandleModel flowHandleModel)
{
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByTaskId(id, flowHandleModel);
if (flowTaskParamter.flowTaskEntity.Status != 1)
throw Oops.Oh(ErrorCode.WF0011);
if (flowTaskParamter.flowTaskEntity.ParentId.IsNotEmptyOrNull()&& !flowTaskParamter.flowTaskEntity.ParentId.Equals("0"))
throw Oops.Oh(ErrorCode.WF0015);
await _flowTaskManager.Revoke(flowTaskParamter);
}
/// <summary>
/// 催办.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("Press/{id}")]
public async Task Press(string id)
{
var flowTaskParamter = await _flowTaskRepository.GetTaskParamterByTaskId(id, null);
await _flowTaskManager.Press(flowTaskParamter);
}
#endregion
}

View File

@@ -0,0 +1,65 @@
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.WorkFlow.Entitys.Dto.FlowMonitor;
using JNPF.WorkFlow.Interfaces.Repository;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程监控.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowMonitor", Order = 304)]
[Route("api/workflow/Engine/[controller]")]
public class FlowMonitorService : IDynamicApiController, ITransient
{
private readonly IFlowTaskRepository _flowTaskRepository;
/// <param name="flowTaskRepository"></param>
public FlowMonitorService(IFlowTaskRepository flowTaskRepository)
{
_flowTaskRepository = flowTaskRepository;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowMonitorListQuery input)
{
return await _flowTaskRepository.GetMonitorList(input);
}
/// <summary>
/// 批量删除.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpDelete]
public async Task Delete([FromBody] FlowMonitorDeleteInput input)
{
var ids = input.ids.Split(",").ToList();
var tsakList = await _flowTaskRepository.GetTaskList(x => ids.Contains(x.Id) && x.FlowType == 1);
if (tsakList.Any()) throw Oops.Oh(ErrorCode.WF0012, tsakList.FirstOrDefault().FullName);
tsakList = await _flowTaskRepository.GetTaskList(x => ids.Contains(x.Id) && !x.ParentId.Equals("0") && !SqlFunc.IsNullOrEmpty(x.ParentId));
if (tsakList.Any()) throw Oops.Oh(ErrorCode.WF0003, tsakList.FirstOrDefault().FullName);
foreach (var item in input.ids.Split(","))
{
var entity = _flowTaskRepository.GetTaskFirstOrDefault(item);
if (entity.IsNotEmptyOrNull())
{
await _flowTaskRepository.DeleteSubTask(entity);
await _flowTaskRepository.DeleteTask(entity);
}
}
}
#endregion
}

View File

@@ -0,0 +1,97 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Models.WorkFlow;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Interfaces.Manager;
using JNPF.WorkFlow.Interfaces.Service;
using Microsoft.AspNetCore.Mvc;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程任务.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowEngine", Name = "FlowTask", Order = 306)]
[Route("api/workflow/Engine/[controller]")]
public class FlowTaskService : IFlowTaskService, IDynamicApiController, ITransient
{
private readonly IFlowTaskManager _flowTaskManager;
private readonly IUserManager _userManager;
public FlowTaskService(IFlowTaskManager flowTaskManager, IUserManager userManager)
{
_flowTaskManager = flowTaskManager;
_userManager = userManager;
}
#region Post
/// <summary>
/// 新建.
/// </summary>
/// <param name="flowTaskSubmit">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task<dynamic> Create([FromBody] FlowTaskSubmitModel flowTaskSubmit)
{
try
{
var flowTaskCandidateModel = new List<FlowTaskCandidateModel>();
flowTaskSubmit.isDelegate = flowTaskSubmit.delegateUserList.Any();//是否委托发起.
if (!flowTaskSubmit.isDelegate) flowTaskSubmit.delegateUserList.Add(_userManager.UserId);
foreach (var item in flowTaskSubmit.delegateUserList)
{
flowTaskSubmit.crUser = item;
if (flowTaskSubmit.status == 1)
{
await _flowTaskManager.Save(flowTaskSubmit);
}
else
{
flowTaskCandidateModel = await _flowTaskManager.Submit(flowTaskSubmit);
if (flowTaskCandidateModel.Any())
{
return flowTaskCandidateModel;
}
}
}
return flowTaskCandidateModel;
}
catch (AppFriendlyException ex)
{
throw Oops.Oh(ex.ErrorCode, ex.Args);
}
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="flowTaskSubmit">请求参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task<dynamic> Update(string id, [FromBody] FlowTaskSubmitModel flowTaskSubmit)
{
try
{
//if (_userManager.UserId.Equals("admin"))
// throw JNPFException.Oh(ErrorCode.WF0004);
if (flowTaskSubmit.status == 1)
{
await _flowTaskManager.Save(flowTaskSubmit);
return new List<FlowTaskCandidateModel>();
}
else
{
return await _flowTaskManager.Submit(flowTaskSubmit);
}
}
catch (AppFriendlyException ex)
{
throw Oops.Oh(ex.ErrorCode, ex.Args);
}
}
#endregion
}

View File

@@ -0,0 +1,887 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Models.WorkFlow;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.Permission;
using JNPF.Systems.Interfaces.System;
using JNPF.WorkFlow.Entitys.Dto.FlowTemplate;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Entitys.Model.Properties;
using JNPF.WorkFlow.Interfaces.Repository;
using JNPF.WorkFlow.Interfaces.Service;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.WorkFlow.Service;
/// <summary>
/// 流程设计.
/// </summary>
[ApiDescriptionSettings(Tag = "WorkflowTemplate", Name = "FlowTemplate", Order = 301)]
[Route("api/workflow/Engine/[controller]")]
public class FlowTemplateService : IFlowTemplateService, IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<FlowTemplateEntity> _repository;
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IUserRelationService _userRelationService;
private readonly IUserManager _userManager;
private readonly IFileManager _fileManager;
private readonly ITenant _db;
public FlowTemplateService(
ISqlSugarRepository<FlowTemplateEntity> repository,
IFlowTaskRepository flowTaskRepository,
IDictionaryDataService dictionaryDataService,
IUserRelationService userRelationService,
IUserManager userManager,
IFileManager fileManager,
ISqlSugarClient context)
{
_repository = repository;
_flowTaskRepository = flowTaskRepository;
_dictionaryDataService = dictionaryDataService;
_userRelationService = userRelationService;
_userManager = userManager;
_fileManager = fileManager;
_db = context.AsTenant();
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] FlowTemplateListQuery input)
{
var objList = _flowTaskRepository.GetCurrentUserObjId();
var list = await _repository.AsSugarClient().Queryable<FlowTemplateEntity, FlowTemplateJsonEntity, FlowEngineVisibleEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.Id == b.TemplateId, JoinType.Left, a.Id == c.FlowId))
.Where((a, b) => a.DeleteMark == null && b.DeleteMark == null && b.EnabledMark == 1)
.WhereIF(_userManager.User.IsAdministrator == 0, (a, b, c) => a.CreatorUserId == _userManager.UserId || (objList.Contains(c.OperatorId) && c.Type == "2"))
.WhereIF(input.category.IsNotEmptyOrNull(), a => a.Category == input.category)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select((a, b) => new FlowTemplateListOutput
{
category = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(d => d.Id == a.Category).Select(d => d.FullName),
id = a.Id,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = a.EnCode,
enabledMark = a.EnabledMark,
fullName = a.FullName,
icon = a.Icon,
iconBackground = a.IconBackground,
lastModifyTime = a.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = a.Type,
visibleType = b.VisibleType,
version = b.Version,
hasAssistBtn = SqlFunc.IIF((_userManager.UserId == a.CreatorUserId || _userManager.User.IsAdministrator == 1), 1, 0),
}).Distinct().MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowTemplateListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 列表(树形).
/// </summary>
/// <returns></returns>
[HttpGet("ListAll")]
public async Task<dynamic> GetListAll()
{
var list1 = await GetFlowFormList(0);
foreach (var item in list1)
{
item.id = item.templateId;
}
if (list1.Any())
{
var dicDataInfo = await _dictionaryDataService.GetInfo(list1.FirstOrDefault().parentId);
var dicDataList = await _dictionaryDataService.GetList(dicDataInfo.DictionaryTypeId);
var list2 = new List<FlowTemplateTreeOutput>();
foreach (var item in dicDataList)
{
list2.Add(new FlowTemplateTreeOutput()
{
fullName = item.FullName,
parentId = "0",
id = item.Id,
num = list1.FindAll(x => x.category == item.EnCode).Count
});
}
var output = list1.Union(list2).ToList().ToTree();
return new { list = output };
}
else
{
return new { list = new List<FlowTemplateTreeOutput>() };
}
}
/// <summary>
/// 列表(分页).
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("PageListAll")]
public async Task<dynamic> GetListPageAll([FromQuery] FlowTemplateListQuery input)
{
var data = await GetFlowFormList(input.flowType.ParseToInt());
if (input.category.IsNotEmptyOrNull())
data = data.FindAll(x => x.category == input.category);
if (input.keyword.IsNotEmptyOrNull())
data = data.FindAll(o => o.fullName.Contains(input.keyword) || o.enCode.Contains(input.keyword));
var pageList = new SqlSugarPagedList<FlowTemplateTreeOutput>()
{
list = data.Skip((input.currentPage - 1) * input.pageSize).Take(input.pageSize).ToList(),
pagination = new Pagination()
{
CurrentPage = input.currentPage,
PageSize = input.pageSize,
Total = data.Count
}
};
return PageResult<FlowTemplateTreeOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 流程版本列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("{id}/FlowJsonList")]
public async Task<dynamic> GetFlowJsonList(string id, [FromQuery] FlowTemplateListQuery input)
{
var whereLambda = LinqExpression.And<FlowTemplateJsonEntity>();
whereLambda = whereLambda.And(x => x.DeleteMark == null && x.TemplateId == id);
var start = new DateTime();
var end = new DateTime();
if (input.endTime != null && input.startTime != null)
{
start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.CreatorTime, start, end));
}
if (input.keyword.IsNotEmptyOrNull())
{
whereLambda = whereLambda.And(x => x.Version.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>()
.Where(whereLambda)
.Select((a) => new FlowTemplateJsonInfoOutput
{
id = a.Id,
version = a.Version,
enabledMark = a.EnabledMark,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
creatorTime = a.CreatorTime,
lastModifyTime = a.LastModifyTime,
flowTemplateJson = a.FlowTemplateJson,
}).MergeTable().OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowTemplateJsonInfoOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
var output = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<FlowTemplateInfoOutput>();
output.flowTemplateJson = _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().First(x => x.TemplateId == id && x.EnabledMark == 1 && x.DeleteMark == null)?.FlowTemplateJson;
return output;
}
/// <summary>
/// 列表(子流程选择流程).
/// </summary>
/// <param name="type">(预留字段).</param>
/// <returns></returns>
[HttpGet("Selector")]
public async Task<dynamic> ListSelect([FromQuery] int type)
{
var list1 = await GetOutList(0);
if (type.IsEmpty())
list1 = list1.FindAll(x => x.formType == type);
var dicDataInfo = await _dictionaryDataService.GetInfo(list1.First().parentId);
var dicDataList = (await _dictionaryDataService.GetList(dicDataInfo.DictionaryTypeId)).FindAll(x => x.EnabledMark == 1);
var list2 = new List<FlowTemplateTreeOutput>();
foreach (var item in dicDataList)
{
var index = list1.FindAll(x => x.category == item.EnCode).Count;
if (index > 0)
{
list2.Add(new FlowTemplateTreeOutput()
{
fullName = item.FullName,
parentId = "0",
id = item.Id,
num = index
});
}
}
var output = list1.Union(list2).ToList().ToTree();
return new { list = output };
}
/// <summary>
/// 导出.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}/Actions/ExportData")]
public async Task<dynamic> ActionsExport(string id)
{
var importModel = new FlowTemplateImportOutput();
importModel.flowTemplate = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
importModel.flowTemplateJson = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.TemplateId == id && x.EnabledMark == 1 && x.DeleteMark == null);
importModel.visibleList = await _repository.AsSugarClient().Queryable<FlowEngineVisibleEntity>().Where(x => x.FlowId == importModel.flowTemplateJson.Id).ToListAsync();
var jsonStr = importModel.ToJsonString();
return await _fileManager.Export(jsonStr, importModel.flowTemplate.FullName, ExportFileType.ffe);
}
/// <summary>
/// 表单主表属性.
/// </summary>
/// <param name="id">主键.</param>
/// <returns></returns>
[HttpGet("{id}/FormInfo")]
public async Task<dynamic> GetFormInfo(string id)
{
var flowJson = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
if (flowJson.IsNullOrEmpty()) return null;
var formId = flowJson.FlowTemplateJson.ToObject<FlowTemplateJsonModel>().properties.ToObject<StartProperties>().formId;
var formEntity = await _repository.AsSugarClient().Queryable<FlowFormEntity>().FirstAsync(x => x.Id == formId && x.DeleteMark == null);
return formEntity.Adapt<FlowFormModel>();
}
/// <summary>
/// 流程协管列表.
/// </summary>
/// <param name="id">主键.</param>
/// <returns></returns>
[HttpGet("{id}/assistList")]
public async Task<dynamic> GetAssistList(string id)
{
var output = await _repository.AsSugarClient().Queryable<FlowEngineVisibleEntity>().Where(a => a.FlowId == id && a.Type == "2").Select(a => a.OperatorId).ToListAsync();
return new { list = output };
}
/// <summary>
/// 委托流程列表(所有流程).
/// </summary>
/// <returns></returns>
[HttpGet("getflowAll")]
public async Task<dynamic> GetFlowAll([FromQuery] FlowTemplateListQuery input)
{
var list = await _repository.AsSugarClient().Queryable<FlowTemplateEntity>()
.Where(a => a.DeleteMark == null && a.EnabledMark == 1)
.WhereIF(input.category.IsNotEmptyOrNull(), a => a.Category == input.category)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select(a => new FlowTemplateTreeOutput
{
id = a.Id,
category = a.Category,
enCode = a.EnCode,
fullName = a.FullName,
sortCode = a.SortCode,
creatorTime = a.CreatorTime,
lastModifyTime = a.LastModifyTime,
type = a.Type,
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderBy(a => a.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<FlowTemplateTreeOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 委托流程列表(所有流程).
/// </summary>
/// <returns></returns>
[HttpPost("getflowList")]
public async Task<dynamic> GetflowList([FromBody] List<string> input)
{
return (await _repository.GetListAsync(x => input.Contains(x.Id))).Adapt<List<FlowTemplateListOutput>>();
}
/// <summary>
/// 通过编码获取流程id.
/// </summary>
/// <returns></returns>
[HttpGet("getFlowIdByCode/{code}")]
public async Task<dynamic> GetflowCode(string code)
{
var entity = await _repository.GetFirstAsync(x => x.EnCode == code && x.DeleteMark == null);
if (entity == null) Oops.Oh(ErrorCode.COM1005);
var jsonEntity = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.TemplateId == entity.Id && x.EnabledMark == 1 && x.DeleteMark == null);
if (jsonEntity == null) Oops.Oh(ErrorCode.COM1005);
return jsonEntity.Id;
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var flowTemplateEntity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (flowTemplateEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
var flowTemplateJsonIdList = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().Where(x => x.TemplateId == id).Select(x => x.Id).ToListAsync();
if (await _flowTaskRepository.AnyFlowTask(x => x.DeleteMark == null && flowTemplateJsonIdList.Contains(x.FlowId)))
throw Oops.Oh(ErrorCode.WF0037);
_db.BeginTran();
await _repository.AsSugarClient().Deleteable<FlowEngineVisibleEntity>(a => flowTemplateJsonIdList.Contains(a.FlowId)).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Deleteable<FlowFormRelationEntity>(a => flowTemplateJsonIdList.Contains(a.FlowId)).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Deleteable<FlowTemplateJsonEntity>(a => flowTemplateJsonIdList.Contains(a.Id)).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(x => x.FlowId == null).Where(x => flowTemplateJsonIdList.Contains(x.FlowId)).ExecuteCommandAsync();
var isOk = await _repository.AsUpdateable(flowTemplateEntity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
_db.CommitTran();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] FlowTemplateInfoOutput input)
{
if (await _repository.IsAnyAsync(x => (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var flowTemplateEntity = input.Adapt<FlowTemplateEntity>();
var result = await Create(flowTemplateEntity, input.flowTemplateJson);
_ = result ?? throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task<dynamic> Update(string id, [FromBody] FlowTemplateInfoOutput input)
{
if (await _repository.IsAnyAsync(x => x.Id != id && (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var flowTemplateEntity = input.Adapt<FlowTemplateEntity>();
var result = await Update(flowTemplateEntity, input.flowTemplateJson);
if (result.IsNullOrEmpty())
throw Oops.Oh(ErrorCode.COM1001);
return result;
}
/// <summary>
/// 复制.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("{id}/Actions/Copy")]
public async Task ActionsCopy(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var flowTemplateJsonEntity = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.TemplateId == id && x.EnabledMark == 1 && x.DeleteMark == null);
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
entity.FullName = string.Format("{0}副本{1}", entity.FullName, random);
entity.EnCode = string.Format("{0}{1}", entity.EnCode, random);
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
throw Oops.Oh(ErrorCode.COM1009);
var result = await Create(entity, flowTemplateJsonEntity.FlowTemplateJson);
_ = result ?? throw Oops.Oh(ErrorCode.WF0002);
}
/// <summary>
/// 导入.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost("Actions/ImportData")]
public async Task ActionsImport(IFormFile file)
{
var fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
if (!fileType.ToLower().Equals(ExportFileType.ffe.ToString()))
throw Oops.Oh(ErrorCode.D3006);
var josn = _fileManager.Import(file);
FlowTemplateImportOutput model;
try
{
model = josn.ToObject<FlowTemplateImportOutput>();
}
catch
{
throw Oops.Oh(ErrorCode.D3006);
}
if (model == null)
throw Oops.Oh(ErrorCode.D3006);
await ImportData(model);
}
/// <summary>
/// 发布.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Release/{id}")]
public async Task Release(string id)
{
var entity = await GetInfo(id);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var flowJson = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.TemplateId == id && x.EnabledMark == 1 && x.DeleteMark == null);
if (flowJson.IsNotEmptyOrNull() && flowJson.FlowTemplateJson.IsNotEmptyOrNull())
{
var isOk = await _repository.AsSugarClient().Updateable<FlowTemplateEntity>().SetColumns(it => it.EnabledMark == 1).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
else
{
throw Oops.Oh(ErrorCode.WF0038);
}
}
/// <summary>
/// 停止.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Stop/{id}")]
public async Task Stop(string id)
{
var entity = await GetInfo(id);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable<FlowTemplateEntity>().SetColumns(it => it.EnabledMark == 0).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
/// <summary>
/// 设置主版本.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("{id}/MainVersion")]
public async Task MainVersion(string id)
{
var jsonInfo = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
await _repository.AsSugarClient().Updateable<FlowTemplateJsonEntity>().SetColumns(it => it.EnabledMark == 0).Where(it => it.Id != id && it.TemplateId == jsonInfo.TemplateId).ExecuteCommandHasChangeAsync();
var isOk = await _repository.AsSugarClient().Updateable<FlowTemplateJsonEntity>().SetColumns(it => it.EnabledMark == 1).Where(it => it.Id == id && it.TemplateId == jsonInfo.TemplateId).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
/// <summary>
/// 删除版本.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}/FlowJson")]
public async Task DeleteFlowJson(string id)
{
if (await _flowTaskRepository.AnyFlowTask(x => x.DeleteMark == null && x.FlowId == id))
throw Oops.Oh(ErrorCode.WF0037);
var isOk = await _repository.AsSugarClient().Updateable<FlowTemplateJsonEntity>().SetColumns(it => new FlowTemplateJsonEntity() { DeleteMark = 1, DeleteTime = SqlFunc.GetDate(), DeleteUserId = _userManager.UserId }).Where(it => it.Id == id).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Deleteable<FlowFormRelationEntity>(a => a.FlowId == id).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(x => x.FlowId == null).Where(x => x.FlowId==id).ExecuteCommandAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
/// <summary>
/// 流程协管.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("assist")]
public async Task SaveAssist([FromBody] FlowTemplateAssistQuery input)
{
var visibleList = new List<FlowEngineVisibleEntity>();
var flowTemplateEntity = await _repository.GetFirstAsync(x => x.Id == input.templateId && x.DeleteMark == null);
foreach (var item in input.list)
{
var visibleEntity = new FlowEngineVisibleEntity()
{
OperatorId = item,
FlowId = input.templateId,
Type = "2"
};
visibleList.Add(visibleEntity);
}
await _repository.AsSugarClient().Deleteable<FlowEngineVisibleEntity>(a => a.FlowId == input.templateId && a.Type == "2").ExecuteCommandHasChangeAsync();
if (visibleList.Any())
{
await _repository.AsSugarClient().Insertable(visibleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
}
#endregion
#region PublicMethod
/// <summary>
/// 发起列表.
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<List<FlowTemplateTreeOutput>> GetFlowFormList(int flowType, string userId = null)
{
var list = await GetOutList(flowType);
var IsAdministrator = false;
if (userId.IsNullOrEmpty())
{
userId = _userManager.UserId;
IsAdministrator = _userManager.User.IsAdministrator == 0;
}
else
{
IsAdministrator = _repository.AsSugarClient().Queryable<UserEntity>().Any(x => x.Id == userId && x.IsAdministrator == 0);
}
if (IsAdministrator)
{
var data = await GetVisibleFlowList(userId, flowType);
data = data.Union(list.FindAll(x => x.visibleType == 0)).ToList();
return data;
}
else
{
return list;
}
}
#endregion
#region PrivateMethod
/// <summary>
/// 新增流程.
/// </summary>
/// <param name="entity">流程实例.</param>
/// <param name="visibleList">可见范围.</param>
/// <returns></returns>
[NonAction]
private async Task<FlowTemplateEntity> Create(FlowTemplateEntity entity, string flowTemplateJson)
{
try
{
_db.BeginTran();
var formIdList = new List<string>();
entity.Id = SnowflakeIdHelper.NextId();
entity.EnabledMark = entity.EnabledMark == null ? 0 : entity.EnabledMark;
var flowTemplateJsonEntity = new FlowTemplateJsonEntity();
flowTemplateJsonEntity.Id = SnowflakeIdHelper.NextId();
flowTemplateJsonEntity.TemplateId = entity.Id;
flowTemplateJsonEntity.Version = "1";
flowTemplateJsonEntity.FlowTemplateJson = flowTemplateJson;
if (flowTemplateJson.IsNotEmptyOrNull())
{
var visibleList = GetFlowEngineVisibleList(flowTemplateJson);
flowTemplateJsonEntity.VisibleType = visibleList.Count == 0 ? 0 : 1;
foreach (var item in visibleList)
{
item.FlowId = flowTemplateJsonEntity.Id;
item.SortCode = visibleList.IndexOf(item);
item.Type = "1";
}
if (visibleList.Count > 0)
await _repository.AsSugarClient().Insertable(visibleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
#region
GetFormIdList(flowTemplateJson.ToObject<FlowTemplateJsonModel>(), formIdList);
foreach (var item in formIdList)
{
var formRelationEntity = new FlowFormRelationEntity
{
Id = SnowflakeIdHelper.NextId(),
FlowId = flowTemplateJsonEntity.Id,
FormId = item
};
await _repository.AsSugarClient().Insertable(formRelationEntity).ExecuteReturnEntityAsync();
}
if (entity.Type == 1)
{
if (await _repository.AsSugarClient().Queryable<FlowFormEntity>().AnyAsync(x => x.Id == formIdList.FirstOrDefault() && !SqlFunc.IsNullOrEmpty(x.FlowId)))
throw Oops.Oh(ErrorCode.WF0043);
await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(x => x.FlowId == flowTemplateJsonEntity.Id).Where(x => x.Id == formIdList.FirstOrDefault()).ExecuteCommandAsync();
}
#endregion
}
await _repository.AsSugarClient().Insertable(flowTemplateJsonEntity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
var result = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
if (result == null)
throw Oops.Oh(ErrorCode.COM1005);
_db.CommitTran();
return result;
}
catch (AppFriendlyException ex)
{
_db.RollbackTran();
throw Oops.Oh(ex.ErrorCode);
}
}
/// <summary>
/// 修改流程.
/// </summary>
/// <param name="entity">流程实体.</param>
/// <param name="visibleList">可见范围.</param>
/// <returns></returns>
[NonAction]
private async Task<object> Update(FlowTemplateEntity entity, string flowTemplateJson)
{
try
{
_db.BeginTran();
var flag = false;
var formIdList = new List<string>();
var flowTemplateJsonEntity = await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().FirstAsync(x => x.TemplateId == entity.Id && x.DeleteMark == null && x.EnabledMark == 1);
if (flowTemplateJsonEntity.FlowTemplateJson.IsNotEmptyOrNull())
{
// 清空就模板关联表单数据
string oldFormId = flowTemplateJsonEntity.FlowTemplateJson.ToObject<FlowTemplateJsonModel>().properties.ToObject<StartProperties>().formId;
await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(x => x.FlowId == null).Where(x => x.Id == oldFormId).ExecuteCommandAsync();
await _repository.AsSugarClient().Deleteable<FlowFormRelationEntity>().Where(x => x.FlowId == flowTemplateJsonEntity.Id).ExecuteCommandAsync();
}
var isCreate = flowTemplateJsonEntity.FlowTemplateJson.Equals(flowTemplateJson);//流程json是否变更
flowTemplateJsonEntity.FlowTemplateJson = flowTemplateJson;
if (flowTemplateJson.IsNotEmptyOrNull())
{
var visibleList = GetFlowEngineVisibleList(flowTemplateJson);
flowTemplateJsonEntity.VisibleType = visibleList.Count == 0 ? 0 : 1;
if ((await _flowTaskRepository.AnyFlowTask(x => x.DeleteMark == null && x.FlowId == flowTemplateJsonEntity.Id)) && !isCreate)
{
flag = true;
flowTemplateJsonEntity.Version = ((await _repository.AsSugarClient().Queryable<FlowTemplateJsonEntity>().Where(x => x.TemplateId == entity.Id).Select(x => SqlFunc.AggregateMax(SqlFunc.ToInt64(x.Version))).FirstAsync()).ParseToInt() + 1).ToString();
flowTemplateJsonEntity.Id = SnowflakeIdHelper.NextId();
flowTemplateJsonEntity.EnabledMark = 0;
await _repository.AsSugarClient().Insertable(flowTemplateJsonEntity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
}
else
{
await _repository.AsSugarClient().Updateable(flowTemplateJsonEntity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
await _repository.AsSugarClient().Deleteable<FlowEngineVisibleEntity>(a => a.FlowId == flowTemplateJsonEntity.Id).ExecuteCommandHasChangeAsync();
}
foreach (var item in visibleList)
{
item.FlowId = flowTemplateJsonEntity.Id;
item.SortCode = visibleList.IndexOf(item);
item.Type = "1";
}
if (visibleList.Count > 0)
await _repository.AsSugarClient().Insertable(visibleList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
GetFormIdList(flowTemplateJson.ToObject<FlowTemplateJsonModel>(), formIdList);
foreach (var item in formIdList)
{
var formRelationEntity = new FlowFormRelationEntity
{
Id = SnowflakeIdHelper.NextId(),
FlowId = flowTemplateJsonEntity.Id,
FormId = item
};
await _repository.AsSugarClient().Insertable(formRelationEntity).ExecuteReturnEntityAsync();
}
if (entity.Type == 1)
{
if (await _repository.AsSugarClient().Queryable<FlowFormEntity>().AnyAsync(x => x.Id == formIdList.FirstOrDefault() && !SqlFunc.IsNullOrEmpty(x.FlowId)))
throw Oops.Oh(ErrorCode.WF0043);
await _repository.AsSugarClient().Updateable<FlowFormEntity>().SetColumns(x => x.FlowId == flowTemplateJsonEntity.Id).Where(x => x.Id == formIdList.FirstOrDefault()).ExecuteCommandAsync();
}
}
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
_db.CommitTran();
return new { isMainVersion = flag, id = flowTemplateJsonEntity.Id };
}
catch (AppFriendlyException ex)
{
_db.RollbackTran();
throw Oops.Oh(ex.ErrorCode);
}
}
/// <summary>
/// 解析流程可见参数.
/// </summary>
/// <param name="josnStr"></param>
/// <returns></returns>
private List<FlowEngineVisibleEntity> GetFlowEngineVisibleList(string josnStr)
{
var output = new List<FlowEngineVisibleEntity>();
if (josnStr.IsNotEmptyOrNull())
{
// 发起节点属性.
var pro = josnStr.ToObject<FlowTemplateJsonModel>().properties.ToObject<StartProperties>();
if (pro.initiator.Any())
{
var list = pro.initiator.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "user" }).ToList();
output.AddRange(list);
}
if (pro.initiatePos.Any())
{
var list = pro.initiatePos.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Position" }).ToList();
output.AddRange(list);
}
if (pro.initiateRole.Any())
{
var list = pro.initiateRole.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Role" }).ToList();
output.AddRange(list);
}
if (pro.initiateGroup.Any())
{
var list = pro.initiateGroup.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Group" }).ToList();
output.AddRange(list);
}
if (pro.initiateOrg.Any())
{
var list = pro.initiateOrg.Select(x => new FlowEngineVisibleEntity() { OperatorId = x, OperatorType = "Organize" }).ToList();
output.AddRange(list);
}
}
return output;
}
/// <summary>
/// 获取当前用户可见流程.
/// </summary>
/// <returns></returns>
[NonAction]
private async Task<List<FlowTemplateTreeOutput>> GetVisibleFlowList(string userId, int flowType)
{
return await _repository.AsSugarClient().Queryable<FlowEngineVisibleEntity, UserRelationEntity, FlowTemplateJsonEntity, FlowTemplateEntity>((a, b, c, d) => new JoinQueryInfos(JoinType.Left, a.OperatorId == b.ObjectId, JoinType.Left, a.FlowId == c.Id, JoinType.Left, c.TemplateId == d.Id))
.Where((a, b, c, d) => (a.OperatorId == userId || b.UserId == userId) && c.DeleteMark == null && c.EnabledMark == 1 && d.Type == flowType)
.Select((a, b, c, d) => new FlowTemplateTreeOutput
{
category = d.Category,
id = c.Id,
description = d.Description,
creatorTime = d.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == d.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = d.EnCode,
enabledMark = d.EnabledMark,
fullName = d.FullName,
icon = d.Icon,
iconBackground = d.IconBackground,
lastModifyTime = d.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == c.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = d.Type,
visibleType = c.VisibleType,
parentId = d.Category,
templateId = a.Id
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderBy(a => a.lastModifyTime, OrderByType.Desc).ToListAsync();
}
/// <summary>
/// 流程列表.
/// </summary>
/// <returns></returns>
private async Task<List<FlowTemplateTreeOutput>> GetOutList(int flowType)
{
return await _repository.AsSugarClient().Queryable<FlowTemplateEntity, FlowTemplateJsonEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.TemplateId))
.Where((a, b) => a.DeleteMark == null && a.EnabledMark == 1 && a.Type == flowType && b.DeleteMark == null && b.EnabledMark == 1)
.Select((a, b) => new FlowTemplateTreeOutput
{
category = a.Category,
id = b.Id,
description = a.Description,
creatorTime = a.CreatorTime,
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
enCode = a.EnCode,
enabledMark = a.EnabledMark,
fullName = a.FullName,
icon = a.Icon,
iconBackground = a.IconBackground,
lastModifyTime = a.LastModifyTime,
lastModifyUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.LastModifyUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
sortCode = a.SortCode,
type = a.Type,
visibleType = b.VisibleType,
parentId = a.Category,
templateId = a.Id
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderBy(a => a.lastModifyTime, OrderByType.Desc).ToListAsync();
}
/// <summary>
/// 导入数据.
/// </summary>
/// <param name="model">导入实例.</param>
/// <returns></returns>
private async Task ImportData(FlowTemplateImportOutput model)
{
try
{
_db.BeginTran();
await _repository.AsSugarClient().Storageable(model.flowTemplate).ExecuteCommandAsync();
await _repository.AsSugarClient().Storageable(model.flowTemplateJson).ExecuteCommandAsync();
await _repository.AsSugarClient().Storageable(model.visibleList).ExecuteCommandAsync();
_db.CommitTran();
}
catch (Exception ex)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.D3006);
}
}
/// <summary>
/// 递归模板获取formid.
/// </summary>
/// <param name="template"></param>
/// <param name="formIdList"></param>
private void GetFormIdList(FlowTemplateJsonModel template, List<string> formIdList)
{
if (template.IsNotEmptyOrNull()&&!template.type.Equals("subFlow"))
{
if (template.properties["formId"].ToString().IsNotEmptyOrNull())
{
formIdList.Add(template.properties["formId"].ToString());
}
if (template.childNode.IsNotEmptyOrNull())
{
GetFormIdList(template.childNode, formIdList);
}
}
}
#endregion
}