123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- using AutoMapper;
- using Newtonsoft.Json;
- using OASystem.Domain;
- using OASystem.Domain.Dtos.Groups;
- using OASystem.Domain.Entities.Groups;
- using OASystem.Domain.ViewModels.JuHeExchangeRate;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace OASystem.Infrastructure.Repositories.Groups
- {
- /// <summary>
- /// 团组流程总览表仓储
- /// </summary>
- public class ProcessOverviewRepository : BaseRepository<Grp_ProcessOverview, Grp_ProcessOverview>
- {
- private readonly IMapper _mapper;
- private readonly DelegationInfoRepository _groupRep;
- public ProcessOverviewRepository(SqlSugarClient sqlSugar, IMapper mapper, DelegationInfoRepository groupRep) : base(sqlSugar)
- {
- _mapper = mapper;
- _groupRep = groupRep;
- }
- /// <summary>
- /// 团组流程初始化
- /// </summary>
- /// <param name="request">创建流程请求参数</param>
- /// <returns>创建的流程信息</returns>
- public async Task<Result> ProcessInitAsync(int groupId, int currUserId)
- {
- //团组验证
- var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(g => g.Id == groupId);
- if (groupInfo == null)
- {
- return new Result { Code = 400, Msg = "团组不存在" };
- }
- // 检查是否已存在流程
- var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>().Where(p => p.GroupId == groupId).ToListAsync();
- if (existingProcesses.Any())
- {
- return new Result { Code = 400, Msg = "该团组的流程已存在" };
- }
- //处理签证国家
- var visaCountries = _groupRep.GroupSplitCountry(groupInfo.VisitCountry);
- // 定义默认的流程节点
- var processs = Grp_ProcessOverview.ProcessInit(groupId, currUserId, visaCountries);
- _sqlSugar.BeginTran();
- foreach (var item in processs)
- {
- var processId = await _sqlSugar.Insertable(item).ExecuteReturnIdentityAsync();
- if (processId < 1)
- {
- _sqlSugar.RollbackTran();
- return new Result { Code = 400, Msg = "团组流程进度总览表添加失败!" };
- }
- var nodes = item.Nodes.Select((nodeDto, index) => new Grp_ProcessNode
- {
- ProcessId = processId,
- NodeName = nodeDto.NodeName,
- NodeOrder = nodeDto.NodeOrder,
- OverallStatus = nodeDto.OverallStatus,
- //Country = nodeDto.Country,
- IsCurrent = nodeDto.IsCurrent,
- Remark = nodeDto.Remark
- }).ToList();
- var nodeIds = await _sqlSugar.Insertable(nodes).ExecuteCommandAsync();
- if (nodeIds < 1)
- {
- _sqlSugar.RollbackTran();
- return new Result { Code = 400, Msg = "团组流程进度流程表添加失败!" };
- }
- }
- _sqlSugar.CommitTran();
- return new Result { Code = 200, Msg = "添加成功!" }; ;
- }
- /// <summary>
- /// 获取团组的所有流程及流程详情
- /// </summary>
- /// <param name="request">创建流程请求参数</param>
- /// <returns>创建的流程信息</returns>
- public async Task<Result> ProcessesDetailsAsync(int groupId)
- {
- //团组验证
- var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(g => g.Id == groupId);
- if (groupInfo == null)
- {
- return new Result { Code = 400, Msg = "团组不存在" };
- }
- // 检查是否已存在流程
- var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>().Where(p => p.GroupId == groupId).ToListAsync();
- if (!existingProcesses.Any())
- {
- return new Result { Code = 400, Msg = "该团组的流程不存在" };
- }
- var users = await _sqlSugar.Queryable<Sys_Users>().ToListAsync();
- var processData = await _sqlSugar.Queryable<Grp_ProcessOverview>()
- .Where(p => p.GroupId == groupId && p.IsDel == 0)
- .Mapper(p => p.Nodes, p => p.Nodes.First().ProcessId)
- .ToListAsync();
- var processes = processData.Select(p => new
- {
- p.Id,
- p.GroupId,
- p.ProcessType,
- ProcessName = p.ProcessType.GetEnumDescription(),
- //p.OverallStatus,
- //StatusText = p.OverallStatus.GetDescription(),
- Nodes = p.Nodes.Select(n =>
- {
- //单独处理签证板块
- var visaSubNodes = new List<VisaProcessNode>();
- string remark = string.Empty;
- if (p.ProcessType == GroupProcessType.Visa)
- {
- visaSubNodes = JsonConvert.DeserializeObject<List<VisaProcessNode>>(n.Remark);
- }
- return new
- {
- n.Id,
- n.ProcessId,
- n.NodeOrder,
- n.NodeName,
- n.OverallStatus,
- StatusText = n.OverallStatus.GetEnumDescription(),
- Operator = users.FirstOrDefault(u => u.Id == n.Operator)?.CnName ?? "-",
- OpeateTime = n.OperationTime.HasValue ? n.OperationTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "-",
- //节点类型为签证时使用
- visaSubNodes
- };
- }).OrderBy(n => n.NodeOrder).ToList()
- }).ToList();
- return new Result { Code = 200, Data = processes, Msg = "查询成功!" };
- }
- /// <summary>
- /// 更新节点状态
- /// </summary>
- /// <param name="nodeId">节点ID</param>
- /// <param name="currUserId">当前用户ID</param>
- /// <param name="processStatus">流程状态,默认为已完成</param>
- /// <returns>操作结果</returns>
- public async Task<Result> UpdateNodeStatusAsync(int nodeId, int currUserId, ProcessStatus processStatus = ProcessStatus.Completed)
- {
- try
- {
- // 使用事务确保数据一致性
- var result = await _sqlSugar.Ado.UseTranAsync(async () =>
- {
- // 1. 获取并验证节点
- var node = await _sqlSugar.Queryable<Grp_ProcessNode>()
- .FirstAsync(n => n.Id == nodeId && n.IsDel == 0);
- if (node == null)
- {
- throw new BusinessException("当前节点不存在或已被删除。");
- }
- // 新增验证:当前节点已完成,不可操作
- ValidateNodeOperation(node, processStatus);
- // 2. 更新节点状态
- node.OverallStatus = processStatus;
- node.Operator = currUserId;
- node.OperationTime = DateTime.Now;
- var updateCount = await _sqlSugar.Updateable(node)
- .UpdateColumns(n => new
- {
- n.OverallStatus,
- n.Operator,
- n.OperationTime
- })
- .ExecuteCommandAsync();
- if (updateCount == 0)
- {
- throw new BusinessException("节点状态更新失败。");
- }
- // 3. 如果是完成当前节点,处理流程流转
- if (processStatus == ProcessStatus.Completed && node.IsCurrent)
- {
- await ProcessCurrentNodeCompletionAsync(node, currUserId);
- }
- return new Result { Code = StatusCodes.Status200OK, Msg = "操作成功。" };
- });
- return result.IsSuccess ? result.Data : new Result
- {
- Code = StatusCodes.Status500InternalServerError,
- Msg = result.ErrorMessage
- };
- }
- catch (BusinessException ex)
- {
- // 业务异常
- return new Result { Code = StatusCodes.Status400BadRequest, Msg = ex.Message };
- }
- catch (Exception ex)
- {
- // 系统异常
- return new Result { Code = StatusCodes.Status500InternalServerError, Msg = "系统错误,请稍后重试" };
- }
- }
- /// <summary>
- /// 验证节点操作权限
- /// </summary>
- /// <param name="node">流程节点</param>
- /// <param name="targetStatus">目标状态</param>
- private void ValidateNodeOperation(Grp_ProcessNode node, ProcessStatus targetStatus)
- {
- // 验证节点是否已完成
- if (node.OverallStatus == ProcessStatus.Completed)
- {
- throw new BusinessException("当前节点已完成,不可重复操作。");
- }
- // 验证状态流转是否合法(可选)
- if (targetStatus != ProcessStatus.Completed)
- {
- throw new BusinessException("未开始或者进行中的节点只能重新完成,不可进行其他操作。");
- }
- // 验证是否尝试将已完成节点改为其他状态
- if (node.OverallStatus == ProcessStatus.Completed && targetStatus != ProcessStatus.Completed)
- {
- throw new BusinessException("已完成节点不可修改状态。");
- }
- }
- /// <summary>
- /// 处理当前节点完成后的流程流转
- /// </summary>
- private async Task ProcessCurrentNodeCompletionAsync(Grp_ProcessNode currentNode, int currUserId)
- {
- // 1. 获取流程信息
- var process = await _sqlSugar.Queryable<Grp_ProcessOverview>()
- .FirstAsync(p => p.Id == currentNode.ProcessId && p.IsDel == 0);
- if (process == null)
- {
- throw new BusinessException("关联的流程不存在。");
- }
- // 2. 取消当前节点的当前状态
- currentNode.IsCurrent = false;
- await _sqlSugar.Updateable(currentNode)
- .UpdateColumns(n => new { n.IsCurrent })
- .ExecuteCommandAsync();
- // 3. 查找并激活下一个节点
- var nextNode = await _sqlSugar.Queryable<Grp_ProcessNode>()
- .Where(n => n.ProcessId == currentNode.ProcessId
- && n.NodeOrder == currentNode.NodeOrder + 1
- && n.IsDel == 0)
- .FirstAsync();
- if (nextNode != null)
- {
- // 激活下一个节点
- nextNode.IsCurrent = true;
- nextNode.OverallStatus = ProcessStatus.InProgress;
- //nextNode.Operator = currUserId;
- //nextNode.OperationTime = DateTime.Now;
- var updateCount = await _sqlSugar.Updateable(nextNode)
- .UpdateColumns(n => new
- {
- n.IsCurrent,
- n.OverallStatus,
- n.Operator,
- n.OperationTime
- })
- .ExecuteCommandAsync();
- if (updateCount == 0)
- {
- throw new BusinessException("激活下一节点失败");
- }
- // 更新流程状态为进行中
- process.OverallStatus = ProcessStatus.InProgress;
- }
- else
- {
- // 下一节点不存在,整个流程完成
- process.OverallStatus = ProcessStatus.Completed;
- process.EndTime = DateTime.Now;
- }
- // 4. 更新流程信息
- process.UpdatedUserId = currUserId;
- process.UpdatedTime = DateTime.Now;
- var processUpdateCount = await _sqlSugar.Updateable(process)
- .UpdateColumns(p => new
- {
- p.OverallStatus,
- p.EndTime,
- p.UpdatedUserId,
- p.UpdatedTime
- })
- .ExecuteCommandAsync();
- if (processUpdateCount == 0)
- {
- throw new BusinessException("流程状态更新失败。");
- }
- }
- /// <summary>
- /// 更新签证节点信息及状态
- /// </summary>
- /// <param name="dto">签证节点更新数据传输对象</param>
- /// <returns>操作结果</returns>
- public async Task<Result> UpdateVisaNodeDetailsAsync(GroupProcessUpdateVisaNodeDetailsDto dto)
- {
- // 1. 获取并验证节点和流程
- var node = await _sqlSugar.Queryable<Grp_ProcessNode>()
- .FirstAsync(n => n.Id == dto.NodeId && n.IsDel == 0)
- ?? throw new BusinessException("当前节点不存在或已被删除。");
- var process = await _sqlSugar.Queryable<Grp_ProcessOverview>()
- .FirstAsync(p => p.Id == node.ProcessId && p.IsDel == 0)
- ?? throw new BusinessException("当前流程不存在或已被删除。");
- if (process.ProcessType != GroupProcessType.Visa)
- {
- throw new BusinessException("当前流程节点不为签证流程,不可编辑。");
- }
- // 2. 检查签证子节点 字段信息是否全部填写
- var allSubNodesCompleted = dto.VisaSubNodes?.All(subNode => EntityExtensions.IsCompleted(subNode)) ?? false;
- // 3. 更新节点信息
- node.Remark = JsonConvert.SerializeObject(dto.VisaSubNodes);
- node.Operator = dto.CurrUserId;
- node.OperationTime = DateTime.Now;
- if (allSubNodesCompleted)
- {
- node.OverallStatus = ProcessStatus.Completed;
- // 更新流程状态
- await _sqlSugar.Updateable<Grp_ProcessOverview>()
- .SetColumns(p => new Grp_ProcessOverview
- {
- OverallStatus = ProcessStatus.Completed,
- EndTime = DateTime.Now,
- UpdatedUserId = dto.CurrUserId,
- UpdatedTime = DateTime.Now
- })
- .Where(p => p.Id == process.Id)
- .ExecuteCommandAsync();
- }
- // 4. 保存节点更新
- await _sqlSugar.Updateable(node)
- .UpdateColumns(n => new
- {
- n.Remark,
- n.Operator,
- n.OperationTime,
- n.OverallStatus
- })
- .ExecuteCommandAsync();
- return new Result { Code = 200, Msg = "节点信息更新成功。" };
- }
- }
- }
|