|
|
@@ -3,6 +3,7 @@ using Newtonsoft.Json;
|
|
|
using OASystem.Domain;
|
|
|
using OASystem.Domain.Dtos.Groups;
|
|
|
using OASystem.Domain.Entities.Groups;
|
|
|
+using OASystem.Domain.Entities.Resource;
|
|
|
using System.Reflection;
|
|
|
|
|
|
namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
@@ -20,6 +21,180 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
_groupRep = groupRep;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 基础数据初始化-团组流程
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="groupId"></param>
|
|
|
+ /// <param name="currUserId"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task<List<Grp_ProcessOverview>> ProcessDataInitAsync(int groupId, int currUserId, List<string> visaCountries)
|
|
|
+ {
|
|
|
+ var processs = new List<Grp_ProcessOverview>();
|
|
|
+
|
|
|
+ //团组验证
|
|
|
+ var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(g => g.Id == groupId);
|
|
|
+ if (groupInfo == null) return processs;
|
|
|
+
|
|
|
+ // 检查是否已存在流程
|
|
|
+ var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>()
|
|
|
+ .Where(p => p.IsDel == 0 && p.GroupId == groupId)
|
|
|
+ .ToListAsync();
|
|
|
+ if (existingProcesses.Any()) return processs;
|
|
|
+
|
|
|
+ #region 商邀报批流程
|
|
|
+ var custInfo = await _sqlSugar.Queryable<Grp_TourClientList>()
|
|
|
+ .Where(c => c.DiId == groupId && c.IsDel == 0)
|
|
|
+ .OrderByDescending(c => c.CreateTime)
|
|
|
+ .FirstAsync();
|
|
|
+ string oaNode2Tips = "客户提供完整名单后,2周内取得邀请函(翻译件)。";
|
|
|
+ if (custInfo != null)
|
|
|
+ {
|
|
|
+ oaNode2Tips = $"请于{custInfo.CreateTime.AddDays(14):yyyy年MM月dd日}内完成该项工作(客户提供完整名单后,2周内取得邀请函(翻译件)。)";
|
|
|
+ }
|
|
|
+
|
|
|
+ var oaNode4Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(按进度实际公务活动落实情况,出发前5日落实公务。)";
|
|
|
+ processs.Add(
|
|
|
+ Grp_ProcessOverview.Create(groupId, 1, GroupProcessType.Invitation, ProcessStatus.InProgress, currUserId,
|
|
|
+ new List<Grp_ProcessNode>()
|
|
|
+ {
|
|
|
+ Grp_ProcessNode.Create(1, "报批基础资料准备","更新报批行程和请示,提供其他报批所需材料,4个工作日内完成。",ProcessStatus.InProgress, true,currUserId),
|
|
|
+ Grp_ProcessNode.Create(2, "报批邀请函资料准备",oaNode2Tips, ProcessStatus.InProgress, false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(3, "获得批件","提供完整的报批全套资源。",ProcessStatus.InProgress, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(4, "对接公务",oaNode4Tips,ProcessStatus.InProgress, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5, "参与翻译对接","",ProcessStatus.InProgress, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(6, "商邀文案配合","",ProcessStatus.InProgress, false, currUserId),
|
|
|
+ }));
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 签证流程
|
|
|
+
|
|
|
+ //单独处理签证流程节点
|
|
|
+ var visaNodes = new List<Grp_ProcessNode>();
|
|
|
+
|
|
|
+ if (visaCountries != null && visaCountries.Count > 0)
|
|
|
+ {
|
|
|
+ var visaDefualtNodes = new List<VisaProcessNode>();
|
|
|
+ for (int i = 1; i < visaCountries.Count + 1; i++)
|
|
|
+ {
|
|
|
+ visaDefualtNodes.Add(VisaProcessNode.Info(i, visaCountries[i - 1].ToString()));
|
|
|
+ }
|
|
|
+
|
|
|
+ visaNodes.Add(Grp_ProcessNode.Create(1, "签证", "", ProcessStatus.InProgress, true, currUserId, JsonConvert.SerializeObject(visaDefualtNodes)));
|
|
|
+ }
|
|
|
+
|
|
|
+ processs.Add(Grp_ProcessOverview.Create(groupId, 2, GroupProcessType.Visa, ProcessStatus.InProgress, currUserId, visaNodes));
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 机票流程
|
|
|
+ string airNode1Tips = "建团后打勾确认出团的时候开始24小时内。";
|
|
|
+ if (groupInfo.Step == 1 || groupInfo.Step == 2)
|
|
|
+ {
|
|
|
+ if (groupInfo.StepOperationTime.HasValue)
|
|
|
+ {
|
|
|
+ airNode1Tips = $"请于{groupInfo.StepOperationTime.Value.AddDays(1):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始24小时内)";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var airNode5Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5日)";
|
|
|
+ processs.Add(
|
|
|
+ Grp_ProcessOverview.Create(groupId, 3, GroupProcessType.AirTicket, ProcessStatus.InProgress, currUserId,
|
|
|
+ new List<Grp_ProcessNode>()
|
|
|
+ {
|
|
|
+ Grp_ProcessNode.Create(1, "初步拟定航程方案及价格", airNode1Tips, ProcessStatus.InProgress, true,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2, "机票占位、续位", "", ProcessStatus.UnStarted, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3, "完成机票采购确认(含预算核对、出票确认等)", "", ProcessStatus.UnStarted,false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(4, "进行出票操作并核查信息", "", ProcessStatus.UnStarted, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5, "机票已出", airNode5Tips, ProcessStatus.UnStarted, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(6, "完成机票选座", "", ProcessStatus.UnStarted, false,currUserId)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ );
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 酒店流程
|
|
|
+
|
|
|
+ string hotelNode1Tips = "建团后打勾确认出团的时候开始2个工作日。";
|
|
|
+ if (groupInfo.Step == 1 || groupInfo.Step == 2)
|
|
|
+ {
|
|
|
+ if (groupInfo.StepOperationTime.HasValue)
|
|
|
+ {
|
|
|
+ hotelNode1Tips = $"请于{groupInfo.StepOperationTime.Value.AddDays(2):yyyy年MM月dd日}内完成该项工作(建团后打勾确认出团的时候开始2个工作日)";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var hotelNode4Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5天)";
|
|
|
+ var hotelNode5Tips = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组结束后5天内)";
|
|
|
+
|
|
|
+ processs.Add(
|
|
|
+ Grp_ProcessOverview.Create(groupId, 4, GroupProcessType.Hotel, ProcessStatus.InProgress, currUserId,
|
|
|
+ new List<Grp_ProcessNode>()
|
|
|
+ {
|
|
|
+ Grp_ProcessNode.Create(1, "筛选并按照预算标准,对目标酒店进行询价、比价、谈价", hotelNode1Tips, ProcessStatus.InProgress, true, currUserId),
|
|
|
+ Grp_ProcessNode.Create(2, "获取酒店确认函与入住名单核对", "", ProcessStatus.UnStarted, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3, "预订酒店并录入OA", "", ProcessStatus.UnStarted,false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(4, "行前再次确认酒店订单、付款状态及入住安排", hotelNode4Tips,ProcessStatus.UnStarted, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(5, "行程结束后整理酒店发票与结算", hotelNode5Tips, ProcessStatus.UnStarted, false, currUserId ),
|
|
|
+ }
|
|
|
+ )
|
|
|
+ );
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 地接流程
|
|
|
+ var airTripCodeInfo = await _sqlSugar.Queryable<Air_TicketBlackCode>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.DiId == groupId)
|
|
|
+ .OrderByDescending(x => x.CreateTime)
|
|
|
+ .FirstAsync();
|
|
|
+ string opNode1Tips = $"机票行程代码最后一段录入后1个工作日内。";
|
|
|
+ if (airTripCodeInfo != null)
|
|
|
+ {
|
|
|
+ opNode1Tips = $"请于{airTripCodeInfo.CreateTime.AddDays(1):yyyy年MM月dd日}内完成该项工作(机票行程代码最后一段录入后1个工作日内)";
|
|
|
+ }
|
|
|
+
|
|
|
+ string opNode2Tips = $"请于{groupInfo.CreateTime.AddDays(7):yyyy年MM月dd日}内完成该项工作(建团完成后7个工作日内)";
|
|
|
+ string opNode3Tips = $"请于{groupInfo.CreateTime.AddDays(10):yyyy年MM月dd日}内完成该项工作(上一步往后3个工作日内)";
|
|
|
+ string opNode4Tips = $"请于{groupInfo.CreateTime.AddDays(12):yyyy年MM月dd日}内完成该项工作(上一步往后2个工作日内)";
|
|
|
+
|
|
|
+ var backListInfo = await _sqlSugar.Queryable<Grp_InvertedList>().Where(x => x.DiId == groupId && x.IsDel == 0).FirstAsync();
|
|
|
+ string opNode5Tips = $"倒推表里开行前会 -3天。";
|
|
|
+ if (backListInfo != null) {
|
|
|
+
|
|
|
+ if (DateTime.TryParse(backListInfo.PreTripMeetingDt,out DateTime dateTime))
|
|
|
+ {
|
|
|
+ opNode5Tips = $"请于{dateTime.AddDays(-3):yyyy年MM月dd日}内完成该项工作(倒推表里开行前会 -3天)";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ processs.Add(
|
|
|
+ Grp_ProcessOverview.Create(groupId, 5, GroupProcessType.LocalGuide, ProcessStatus.InProgress, currUserId,
|
|
|
+ new List<Grp_ProcessNode>()
|
|
|
+ {
|
|
|
+ Grp_ProcessNode.Create(1,"根据机票方案出框架行程", opNode1Tips,ProcessStatus.InProgress, true, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2,"联系并询价地接、餐厅、用车、景点等供应商", opNode2Tips,ProcessStatus.UnStarted, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3,"提交供应商报价及比价表", opNode3Tips, ProcessStatus.UnStarted, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(4,"执行采购流程", opNode4Tips, ProcessStatus.UnStarted, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5,"制定最终《行程表》及《出行手册》", opNode5Tips, ProcessStatus.UnStarted, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(6,"送机", "", ProcessStatus.UnStarted, false, currUserId ),
|
|
|
+ }
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 费用结算流程
|
|
|
+ processs.Add(
|
|
|
+ Grp_ProcessOverview.Create(groupId, 6, GroupProcessType.FeeSettle, ProcessStatus.InProgress, currUserId,
|
|
|
+ new List<Grp_ProcessNode>()
|
|
|
+ {
|
|
|
+ Grp_ProcessNode.Create(1, "费用结算中", "", ProcessStatus.InProgress, true,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2, "费用结算完毕", "", ProcessStatus.UnStarted, false,currUserId ),
|
|
|
+ }
|
|
|
+ )
|
|
|
+ );
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ return processs;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 团组流程初始化
|
|
|
/// </summary>
|
|
|
@@ -35,7 +210,9 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
}
|
|
|
|
|
|
// 检查是否已存在流程
|
|
|
- var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>().Where(p => p.GroupId == groupId).ToListAsync();
|
|
|
+ var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>()
|
|
|
+ .Where(p => p.IsDel == 0 && p.GroupId == groupId)
|
|
|
+ .ToListAsync();
|
|
|
if (existingProcesses.Any())
|
|
|
{
|
|
|
return new Result { Code = 400, Msg = "该团组的流程已存在" };
|
|
|
@@ -45,7 +222,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
var visaCountries = _groupRep.GroupSplitCountry(groupInfo.VisitCountry);
|
|
|
|
|
|
// 定义默认的流程节点
|
|
|
- var processs = Grp_ProcessOverview.ProcessInit(groupId, currUserId, visaCountries);
|
|
|
+ var processs = await ProcessDataInitAsync(groupId, currUserId, visaCountries);
|
|
|
|
|
|
_sqlSugar.BeginTran();
|
|
|
|
|
|
@@ -68,6 +245,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
NodeName = nodeDto.NodeName,
|
|
|
NodeOrder = nodeDto.NodeOrder,
|
|
|
OverallStatus = nodeDto.OverallStatus,
|
|
|
+ NodeDescTips = nodeDto.NodeDescTips,
|
|
|
//Country = nodeDto.Country,
|
|
|
IsCurrent = nodeDto.IsCurrent,
|
|
|
Remark = nodeDto.Remark
|
|
|
@@ -106,7 +284,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
}
|
|
|
|
|
|
// 检查是否已存在流程
|
|
|
- var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>().Where(p => p.GroupId == groupId).ToListAsync();
|
|
|
+ var existingProcesses = await _sqlSugar.Queryable<Grp_ProcessOverview>().Where(p => p.IsDel == 0 && p.GroupId == groupId).ToListAsync();
|
|
|
if (!existingProcesses.Any())
|
|
|
{
|
|
|
//新建团组流程
|
|
|
@@ -117,7 +295,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- var users = await _sqlSugar.Queryable<Sys_Users>().ToListAsync();
|
|
|
+ var users = await _sqlSugar.Queryable<Sys_Users>().Select(x => new {x.Id,x.CnName }).ToListAsync();
|
|
|
|
|
|
var processData = await _sqlSugar.Queryable<Grp_ProcessOverview>()
|
|
|
.Where(p => p.GroupId == groupId && p.IsDel == 0)
|
|
|
@@ -152,6 +330,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
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") : "-",
|
|
|
+ ActualDone = n.ActualDone?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
|
|
|
+ n.NodeDescTips,
|
|
|
//节点类型为签证时使用
|
|
|
visaSubNodes
|
|
|
};
|
|
|
@@ -184,11 +364,21 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
throw new BusinessException("当前节点不存在或已被删除。");
|
|
|
}
|
|
|
|
|
|
- // 新增验证:当前节点已完成,不可操作
|
|
|
+ // 2. 获取流程信息,检查ProcessType
|
|
|
+ var process = await _sqlSugar.Queryable<Grp_ProcessOverview>()
|
|
|
+ .FirstAsync(p => p.Id == node.ProcessId && p.IsDel == 0);
|
|
|
+
|
|
|
+ if (process == null)
|
|
|
+ {
|
|
|
+ throw new BusinessException("关联的流程不存在。");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 节点操作验证
|
|
|
ValidateNodeOperation(node, processStatus);
|
|
|
|
|
|
- //存储更新前的值
|
|
|
- var before = new Grp_ProcessNode() {
|
|
|
+ // 4. 存储更新前的值
|
|
|
+ var before = new Grp_ProcessNode()
|
|
|
+ {
|
|
|
Id = node.Id,
|
|
|
ProcessId = node.ProcessId,
|
|
|
NodeName = node.NodeName,
|
|
|
@@ -199,7 +389,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
IsCurrent = node.IsCurrent,
|
|
|
};
|
|
|
|
|
|
- // 2. 更新节点状态
|
|
|
+ // 5. 更新节点状态
|
|
|
node.OverallStatus = processStatus;
|
|
|
node.Operator = currUserId;
|
|
|
node.OperationTime = DateTime.Now;
|
|
|
@@ -218,11 +408,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
throw new BusinessException("节点状态更新失败。");
|
|
|
}
|
|
|
|
|
|
- //记录节点日志
|
|
|
+ // 6. 记录节点日志
|
|
|
await LogNodeOpAsync(before, node, "Update", currUserId);
|
|
|
|
|
|
- // 3. 如果是完成当前节点,处理流程流转
|
|
|
- if (processStatus == ProcessStatus.Completed && node.IsCurrent)
|
|
|
+ // 7. 如果是完成当前节点,处理流程流转
|
|
|
+ // 当前节点或者流程类型为商邀可进入状态流转
|
|
|
+ if (processStatus == ProcessStatus.Completed && (node.IsCurrent || process.ProcessType == GroupProcessType.Invitation))
|
|
|
{
|
|
|
await ProcessCurrentNodeCompletionAsync(node, currUserId);
|
|
|
}
|
|
|
@@ -262,10 +453,10 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
}
|
|
|
|
|
|
// 验证状态流转是否合法(可选)
|
|
|
- if (targetStatus != ProcessStatus.Completed)
|
|
|
- {
|
|
|
- throw new BusinessException("未开始或者进行中的节点只能重新完成,不可进行其他操作。");
|
|
|
- }
|
|
|
+ //if (targetStatus != ProcessStatus.Completed)
|
|
|
+ //{
|
|
|
+ // throw new BusinessException("未开始或者进行中的节点只能重新完成,不可进行其他操作。");
|
|
|
+ //}
|
|
|
|
|
|
// 验证是否尝试将已完成节点改为其他状态
|
|
|
if (node.OverallStatus == ProcessStatus.Completed && targetStatus != ProcessStatus.Completed)
|
|
|
@@ -320,59 +511,76 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
// 2.1 记录节点日志 取消当前节点状态
|
|
|
await LogNodeOpAsync(before, currentNode, "Update", currUserId);
|
|
|
|
|
|
- // 3. 查找并激活下一个节点
|
|
|
- var nextNode = await _sqlSugar.Queryable<Grp_ProcessNode>()
|
|
|
+ // 3. 查找并激活下一个节点 商邀节点单独处理
|
|
|
+ if (process.ProcessType == GroupProcessType.Invitation)
|
|
|
+ {
|
|
|
+ var invitaNodeStatus = await _sqlSugar.Queryable<Grp_ProcessNode>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.ProcessId == currentNode.ProcessId)
|
|
|
+ .ToListAsync();
|
|
|
+
|
|
|
+ int completedCount = invitaNodeStatus.Count(n => n.OverallStatus == ProcessStatus.Completed);
|
|
|
+ int nodeCount = invitaNodeStatus.Count;
|
|
|
+ if (completedCount == nodeCount) //全部子节点完成,该流程完成
|
|
|
+ {
|
|
|
+ process.OverallStatus = ProcessStatus.Completed;
|
|
|
+ process.EndTime = DateTime.Now;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ 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)
|
|
|
- {
|
|
|
- var nextNodeBefore = new Grp_ProcessNode()
|
|
|
+ if (nextNode != null)
|
|
|
{
|
|
|
- Id = nextNode.Id,
|
|
|
- ProcessId = nextNode.ProcessId,
|
|
|
- NodeName = nextNode.NodeName,
|
|
|
- NodeOrder = nextNode.NodeOrder,
|
|
|
- OverallStatus = nextNode.OverallStatus,
|
|
|
- Operator = nextNode.Operator,
|
|
|
- OperationTime = nextNode.OperationTime,
|
|
|
- IsCurrent = nextNode.IsCurrent,
|
|
|
- };
|
|
|
+ var nextNodeBefore = new Grp_ProcessNode()
|
|
|
+ {
|
|
|
+ Id = nextNode.Id,
|
|
|
+ ProcessId = nextNode.ProcessId,
|
|
|
+ NodeName = nextNode.NodeName,
|
|
|
+ NodeOrder = nextNode.NodeOrder,
|
|
|
+ OverallStatus = nextNode.OverallStatus,
|
|
|
+ Operator = nextNode.Operator,
|
|
|
+ OperationTime = nextNode.OperationTime,
|
|
|
+ IsCurrent = nextNode.IsCurrent,
|
|
|
+ };
|
|
|
|
|
|
- // 激活下一个节点
|
|
|
- nextNode.IsCurrent = true;
|
|
|
- nextNode.OverallStatus = ProcessStatus.InProgress;
|
|
|
- //nextNode.Operator = currUserId;
|
|
|
- //nextNode.OperationTime = DateTime.Now;
|
|
|
+ // 激活下一个节点
|
|
|
+ nextNode.IsCurrent = true;
|
|
|
+ nextNode.OverallStatus = ProcessStatus.InProgress;
|
|
|
+ //nextNode.Operator = currUserId;
|
|
|
+ //nextNode.OperationTime = DateTime.Now;
|
|
|
|
|
|
- var updateCount = await _sqlSugar.Updateable(nextNode)
|
|
|
- .UpdateColumns(n => new
|
|
|
+ var updateCount = await _sqlSugar.Updateable(nextNode)
|
|
|
+ .UpdateColumns(n => new
|
|
|
+ {
|
|
|
+ n.IsCurrent,
|
|
|
+ n.OverallStatus,
|
|
|
+ n.Operator,
|
|
|
+ n.OperationTime
|
|
|
+ })
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (updateCount == 0)
|
|
|
{
|
|
|
- n.IsCurrent,
|
|
|
- n.OverallStatus,
|
|
|
- n.Operator,
|
|
|
- n.OperationTime
|
|
|
- })
|
|
|
- .ExecuteCommandAsync();
|
|
|
+ throw new BusinessException("激活下一节点失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.1 记录节点日志 激活下一节点当前节点状态
|
|
|
+ await LogNodeOpAsync(nextNodeBefore, nextNode, "Start", currUserId);
|
|
|
|
|
|
- if (updateCount == 0)
|
|
|
+ // 更新流程状态为进行中
|
|
|
+ process.OverallStatus = ProcessStatus.InProgress;
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- throw new BusinessException("激活下一节点失败");
|
|
|
+ // 下一节点不存在,整个流程完成
|
|
|
+ process.OverallStatus = ProcessStatus.Completed;
|
|
|
+ process.EndTime = DateTime.Now;
|
|
|
}
|
|
|
-
|
|
|
- // 1.1 记录节点日志 激活下一节点当前节点状态
|
|
|
- await LogNodeOpAsync(nextNodeBefore, nextNode, "Start", currUserId);
|
|
|
-
|
|
|
- // 更新流程状态为进行中
|
|
|
- process.OverallStatus = ProcessStatus.InProgress;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // 下一节点不存在,整个流程完成
|
|
|
- process.OverallStatus = ProcessStatus.Completed;
|
|
|
- process.EndTime = DateTime.Now;
|
|
|
}
|
|
|
|
|
|
// 4. 更新流程信息
|
|
|
@@ -492,6 +700,50 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
return new Result { Code = 200, Msg = "节点信息更新成功。" };
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 更新签证节点信息及状态
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto">签证节点更新数据传输对象</param>
|
|
|
+ /// <returns>操作结果</returns>
|
|
|
+ public async Task<Result> SetActualDoneAsync(int nodeId, DateTime dt, int currUserId)
|
|
|
+ {
|
|
|
+ // 1. 获取并验证节点和流程
|
|
|
+ var node = await _sqlSugar.Queryable<Grp_ProcessNode>()
|
|
|
+ .FirstAsync(n => n.Id == 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("当前流程不存在或已被删除。");
|
|
|
+
|
|
|
+ // 2.1 存储更新前流程及节点信息
|
|
|
+ var nodeBefore = new Grp_ProcessNode()
|
|
|
+ {
|
|
|
+ Id = node.Id,
|
|
|
+ ProcessId = node.ProcessId,
|
|
|
+ NodeName = node.NodeName,
|
|
|
+ NodeOrder = node.NodeOrder,
|
|
|
+ OverallStatus = node.OverallStatus,
|
|
|
+ Operator = node.Operator,
|
|
|
+ OperationTime = node.OperationTime,
|
|
|
+ IsCurrent = node.IsCurrent,
|
|
|
+ };
|
|
|
+
|
|
|
+ node.ActualDone = dt;
|
|
|
+
|
|
|
+ // 3. 保存节点更新
|
|
|
+ await _sqlSugar.Updateable(node)
|
|
|
+ .UpdateColumns(n => new
|
|
|
+ {
|
|
|
+ n.ActualDone
|
|
|
+ })
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+ //记录节点日志
|
|
|
+ await LogNodeOpAsync(nodeBefore, node, "Update", currUserId);
|
|
|
+
|
|
|
+ return new Result { Code = 200, Msg = "实际操作时间设置成功。" };
|
|
|
+ }
|
|
|
+
|
|
|
#region 操作日志
|
|
|
|
|
|
/// <summary>
|