|
|
@@ -21,7 +21,6 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
_groupRep = groupRep;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 基础数据初始化-团组流程
|
|
|
/// </summary>
|
|
|
@@ -50,20 +49,22 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
string oaNode2Tips = "客户提供完整名单后,2周内取得邀请函(翻译件)。";
|
|
|
if (custInfo != null)
|
|
|
{
|
|
|
- oaNode2Tips = $"请于{custInfo.CreateTime.AddDays(14):yyyy年MM月dd日}内完成该项工作(客户提供完整名单后,2周内取得邀请函(翻译件)。)";
|
|
|
+ oaNode2Tips = $"请于{custInfo.CreateTime.AddDays(14):yyyy年MM月dd日}内完成该项工作(客户提供完整名单后,2周内取得邀请函(翻译件))";
|
|
|
}
|
|
|
|
|
|
- var oaNode4Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(按进度实际公务活动落实情况,出发前5日落实公务。)";
|
|
|
+ var oaNode4Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(按进度实际公务活动落实情况,出发前5日落实公务)";
|
|
|
+ var oaNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组结束前完成)";
|
|
|
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),
|
|
|
+ Grp_ProcessNode.Create(1, "报批基础资料准备","更新报批行程和请示,提供其他报批所需材料,4个工作日内完成。",ProcessStatus.InProgress, true,false,false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(2, "报批邀请函资料准备",oaNode2Tips, ProcessStatus.InProgress, false,false,false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(3, "获得批件","提供完整的报批全套资源。",ProcessStatus.InProgress, false,false,false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(4, "对接公务",oaNode4Tips,ProcessStatus.InProgress, false,false,false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5, "参与翻译对接","",ProcessStatus.InProgress, false,false,false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(6, "商邀文案配合","",ProcessStatus.InProgress, false,false,false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(7, "票据上传(相关票据)",oaNode7Tips,ProcessStatus.InProgress, false,false,true, currUserId),
|
|
|
}));
|
|
|
#endregion
|
|
|
|
|
|
@@ -80,10 +81,12 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
visaDefualtNodes.Add(VisaProcessNode.Info(i, visaCountries[i - 1].ToString()));
|
|
|
}
|
|
|
|
|
|
- visaNodes.Add(Grp_ProcessNode.Create(1, "签证", "", ProcessStatus.InProgress, true, currUserId, JsonConvert.SerializeObject(visaDefualtNodes)));
|
|
|
+ var visaNode2Tips = $"请于{groupInfo.VisitDate:yyyy年MM月dd日}内完成该项工作(按进度实际签证办理落实情况,团组出发前上传票据。)";
|
|
|
+ visaNodes.Add(Grp_ProcessNode.Create(1, "签证信息", "", ProcessStatus.InProgress, true, false, false, currUserId, JsonConvert.SerializeObject(visaDefualtNodes)));
|
|
|
+ visaNodes.Add(Grp_ProcessNode.Create(2, "票据上传(明细表、费用票据、保单及超支费用账单)", visaNode2Tips, ProcessStatus.InProgress, true, false, true, currUserId));
|
|
|
}
|
|
|
|
|
|
- processs.Add(Grp_ProcessOverview.Create(groupId, 2, GroupProcessType.Visa, ProcessStatus.InProgress, currUserId, visaNodes));
|
|
|
+ processs.Add(Grp_ProcessOverview.Create(groupId, 2, GroupProcessType.Visa, ProcessStatus.UnStarted, currUserId, visaNodes));
|
|
|
#endregion
|
|
|
|
|
|
#region 机票流程
|
|
|
@@ -97,16 +100,20 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
}
|
|
|
|
|
|
var airNode5Tips = $"请于{groupInfo.VisitDate.AddDays(-5):yyyy年MM月dd日}内完成该项工作(团组出发前5日)";
|
|
|
+ var airNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组归国后5个工作日内)";
|
|
|
+ var airNode8Tips = $"请于{groupInfo.VisitEndDate.AddDays(10):yyyy年MM月dd日}内完成该项工作(团组归国后10个工作日内) *按机票报价*0.999折扣出具机票报销蓝联、行程单及机票说明";
|
|
|
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)
|
|
|
+ Grp_ProcessNode.Create(1, "初步拟定航程方案及价格", airNode1Tips, ProcessStatus.InProgress, true,false,false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2, "机票占位、续位", "", ProcessStatus.UnStarted, false,false,false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3, "完成机票采购确认(含预算核对、出票确认等)", "", ProcessStatus.UnStarted,false,false,false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(4, "进行出票操作并核查信息", "", ProcessStatus.UnStarted, false,false,false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5, "机票已出", airNode5Tips, ProcessStatus.UnStarted, false,false,false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(6, "完成机票选座", "", ProcessStatus.UnStarted, false,false,false,currUserId),
|
|
|
+ Grp_ProcessNode.Create(7, "票据上传(机票超支费用账单)", airNode7Tips, ProcessStatus.UnStarted, false,false,true,currUserId),
|
|
|
+ Grp_ProcessNode.Create(8, "票据上传(机票报销蓝联、行程单及机票说明)", airNode8Tips, ProcessStatus.UnStarted, false,false,true,currUserId)
|
|
|
}
|
|
|
)
|
|
|
);
|
|
|
@@ -130,11 +137,11 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
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 ),
|
|
|
+ Grp_ProcessNode.Create(1, "筛选并按照预算标准,对目标酒店进行询价、比价、谈价", hotelNode1Tips, ProcessStatus.InProgress, true, false, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(2, "获取酒店确认函与入住名单核对", "", ProcessStatus.UnStarted, false, false, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3, "预订酒店并录入OA", "", ProcessStatus.UnStarted,false, false, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(4, "行前再次确认酒店订单、付款状态及入住安排", hotelNode4Tips,ProcessStatus.UnStarted, false, false, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(5, "行程结束后整理酒店发票(含超支费用发票)与结算", hotelNode5Tips, ProcessStatus.UnStarted, false, false, true, currUserId ),
|
|
|
}
|
|
|
)
|
|
|
);
|
|
|
@@ -164,16 +171,19 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
opNode5Tips = $"请于{dateTime.AddDays(-3):yyyy年MM月dd日}内完成该项工作(倒推表里开行前会 -3天)";
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ string opNode7Tips = $"请于{groupInfo.VisitEndDate.AddDays(5):yyyy年MM月dd日}内完成该项工作(团组归国后5个工作日内) *上传最终报批行程,确定城市间交通最终版报价分配;地接账单(清楚标注超时及其他项超支费用)、地接交通费用原始票据、城市间交通明细表;";
|
|
|
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 ),
|
|
|
+ Grp_ProcessNode.Create(1,"根据机票方案出框架行程", opNode1Tips,ProcessStatus.InProgress, true, false, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2,"联系并询价地接、餐厅、用车、景点等供应商", opNode2Tips,ProcessStatus.UnStarted, false, false, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3,"提交供应商报价及比价表", opNode3Tips, ProcessStatus.UnStarted, false, false, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(4,"执行采购流程", opNode4Tips, ProcessStatus.UnStarted, false, false, false, currUserId),
|
|
|
+ Grp_ProcessNode.Create(5,"制定最终《行程表》及《出行手册》", opNode5Tips, ProcessStatus.UnStarted, false, false, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(6,"送机", "", ProcessStatus.UnStarted, false, false, false, currUserId ),
|
|
|
+ Grp_ProcessNode.Create(7,"最终版报批行程、票据上传", opNode7Tips, ProcessStatus.UnStarted, false, false, true, currUserId )
|
|
|
}
|
|
|
)
|
|
|
);
|
|
|
@@ -181,12 +191,15 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
#endregion
|
|
|
|
|
|
#region 费用结算流程
|
|
|
+ var feeNode3Tips = $"请于{groupInfo.VisitEndDate.AddDays(12):yyyy年MM月dd日}内完成该项工作(团组归国后12个工作日内)";
|
|
|
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 ),
|
|
|
+ Grp_ProcessNode.Create(1, "城市间交通报批金额核定", "团组报批前", ProcessStatus.InProgress, true, true, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(2, "团组全程各段机票打票金额的核定", "团组报批后、订票前", ProcessStatus.UnStarted, false, false, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(3, "整理统计团组超支费用、三公报销资料给到各单位", feeNode3Tips, ProcessStatus.UnStarted, false, false, false,currUserId ),
|
|
|
+ Grp_ProcessNode.Create(4, "费用结算完毕", "", ProcessStatus.UnStarted, false, false, false,currUserId ),
|
|
|
}
|
|
|
)
|
|
|
);
|
|
|
@@ -235,7 +248,7 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
_sqlSugar.RollbackTran();
|
|
|
return new Result { Code = 400, Msg = "团组流程进度总览表添加失败!" };
|
|
|
}
|
|
|
-
|
|
|
+ item.Id = processId;
|
|
|
// 记录流程日志
|
|
|
await LogProcessOpAsync(null, item, "Create", currUserId);
|
|
|
|
|
|
@@ -248,6 +261,8 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
NodeDescTips = nodeDto.NodeDescTips,
|
|
|
//Country = nodeDto.Country,
|
|
|
IsCurrent = nodeDto.IsCurrent,
|
|
|
+ IsAssist = nodeDto.IsAssist,
|
|
|
+ IsFileUp = nodeDto.IsFileUp,
|
|
|
Remark = nodeDto.Remark
|
|
|
}).ToList();
|
|
|
|
|
|
@@ -258,6 +273,9 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
return new Result { Code = 400, Msg = "团组流程进度流程节点添加失败!" };
|
|
|
}
|
|
|
|
|
|
+ //设置节点ID
|
|
|
+ nodes = await _sqlSugar.Queryable<Grp_ProcessNode>().Where(x => x.IsDel == 0 && x.ProcessId == processId).ToListAsync();
|
|
|
+
|
|
|
//记录节点日志
|
|
|
foreach (var node in nodes)
|
|
|
{
|
|
|
@@ -302,40 +320,68 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
.Mapper(p => p.Nodes, p => p.Nodes.First().ProcessId)
|
|
|
.ToListAsync();
|
|
|
|
|
|
- var processes = processData.Select(p => new
|
|
|
+ // 预先构建用户字典,提升查询性能
|
|
|
+ var userDict = users.ToDictionary(u => u.Id, u => u.CnName);
|
|
|
+
|
|
|
+ var processes = processData.Select(p =>
|
|
|
{
|
|
|
- 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;
|
|
|
+ var orderedNodes = p.Nodes.OrderBy(n => n.NodeOrder).ToList();
|
|
|
+ var totalNodes = orderedNodes.Count;
|
|
|
|
|
|
- if (p.ProcessType == GroupProcessType.Visa)
|
|
|
- {
|
|
|
- visaSubNodes = JsonConvert.DeserializeObject<List<VisaProcessNode>>(n.Remark);
|
|
|
- }
|
|
|
- return new
|
|
|
+ return new
|
|
|
+ {
|
|
|
+ p.Id,
|
|
|
+ p.GroupId,
|
|
|
+ p.ProcessType,
|
|
|
+ ProcessName = p.ProcessType.GetEnumDescription(),
|
|
|
+ Nodes = orderedNodes.Select((n, index) =>
|
|
|
{
|
|
|
- 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") : "-",
|
|
|
- ActualDone = n.ActualDone?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
|
|
|
- n.NodeDescTips,
|
|
|
- //节点类型为签证时使用
|
|
|
- visaSubNodes
|
|
|
- };
|
|
|
- }).OrderBy(n => n.NodeOrder).ToList()
|
|
|
+ var isLastNode = index == totalNodes - 1;
|
|
|
+ var isSecondLastNode = index == totalNodes - 2;
|
|
|
+
|
|
|
+ /* 计算按钮状态
|
|
|
+ * 1 所有流程节点最后一步骤显示上传按钮
|
|
|
+ * 2 机票流程倒数第二步骤显示上传按钮
|
|
|
+ * 3 费用结算流程第一步骤显示协助按钮
|
|
|
+ */
|
|
|
+ bool isEnaAssistBtn = p.ProcessType == GroupProcessType.FeeSettle && n.NodeOrder == 1;
|
|
|
+ bool isEnaFileUpBtn = isLastNode || (p.ProcessType == GroupProcessType.AirTicket && isSecondLastNode);
|
|
|
+
|
|
|
+ // 处理签证子节点
|
|
|
+ List<VisaProcessNode> visaSubNodes = new();
|
|
|
+ if (p.ProcessType == GroupProcessType.Visa && n.NodeOrder == 1)
|
|
|
+ {
|
|
|
+ visaSubNodes = JsonConvert.DeserializeObject<List<VisaProcessNode>>(n.Remark ?? "[]")
|
|
|
+ ?? new List<VisaProcessNode>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取操作人姓名(使用字典提升性能)
|
|
|
+ string operatorName = "-";
|
|
|
+ if (n.Operator.HasValue && userDict.TryGetValue(n.Operator.Value, out var name))
|
|
|
+ {
|
|
|
+ operatorName = name;
|
|
|
+ }
|
|
|
+
|
|
|
+ return new
|
|
|
+ {
|
|
|
+ n.Id,
|
|
|
+ n.ProcessId,
|
|
|
+ n.NodeOrder,
|
|
|
+ n.NodeName,
|
|
|
+ n.OverallStatus,
|
|
|
+ StatusText = n.OverallStatus.GetEnumDescription(),
|
|
|
+ Operator = operatorName,
|
|
|
+ OpeateTime = n.OperationTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-",
|
|
|
+ ActualDone = n.ActualDone?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
|
|
|
+ n.NodeDescTips,
|
|
|
+ isEnaAssistBtn, // 是否启用财务流程首节点协助按钮
|
|
|
+ n.IsAssist, // 财务流程首节点 存储值
|
|
|
+ isEnaFileUpBtn, // 是否启用上传文件按钮
|
|
|
+ n.IsFileUp, // 票据上传节点 存储值
|
|
|
+ visaSubNodes // 签证节点类型使用
|
|
|
+ };
|
|
|
+ }).ToList()
|
|
|
+ };
|
|
|
}).ToList();
|
|
|
|
|
|
return new Result { Code = 200, Data = processes, Msg = "查询成功!" };
|
|
|
@@ -357,21 +403,11 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
{
|
|
|
// 1. 获取并验证节点
|
|
|
var node = await _sqlSugar.Queryable<Grp_ProcessNode>()
|
|
|
- .FirstAsync(n => n.Id == nodeId && n.IsDel == 0);
|
|
|
-
|
|
|
- if (node == null)
|
|
|
- {
|
|
|
- throw new BusinessException("当前节点不存在或已被删除。");
|
|
|
- }
|
|
|
+ .FirstAsync(n => n.Id == nodeId && n.IsDel == 0) ?? 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("关联的流程不存在。");
|
|
|
- }
|
|
|
+ .FirstAsync(p => p.Id == node.ProcessId && p.IsDel == 0) ?? throw new BusinessException("关联的流程不存在。");
|
|
|
|
|
|
// 3. 节点操作验证
|
|
|
ValidateNodeOperation(node, processStatus);
|
|
|
@@ -705,8 +741,14 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
/// </summary>
|
|
|
/// <param name="dto">签证节点更新数据传输对象</param>
|
|
|
/// <returns>操作结果</returns>
|
|
|
- public async Task<Result> SetActualDoneAsync(int nodeId, DateTime dt, int currUserId)
|
|
|
+ public async Task<Result> SetActualDoneAsync(GroupProcessSetActualDoneDto dto )
|
|
|
{
|
|
|
+ int nodeId = dto.NodeId;
|
|
|
+ DateTime dt = dto.ActualDone;
|
|
|
+ int currUserId = dto.CurrUserId;
|
|
|
+ bool isAssist = dto.IsAssist;
|
|
|
+ bool isFileUp = dto.IsFileUp;
|
|
|
+
|
|
|
// 1. 获取并验证节点和流程
|
|
|
var node = await _sqlSugar.Queryable<Grp_ProcessNode>()
|
|
|
.FirstAsync(n => n.Id == nodeId && n.IsDel == 0)
|
|
|
@@ -726,16 +768,20 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
OverallStatus = node.OverallStatus,
|
|
|
Operator = node.Operator,
|
|
|
OperationTime = node.OperationTime,
|
|
|
- IsCurrent = node.IsCurrent,
|
|
|
+ IsCurrent = node.IsCurrent
|
|
|
};
|
|
|
|
|
|
node.ActualDone = dt;
|
|
|
+ node.IsAssist = isAssist;
|
|
|
+ node.IsFileUp = isFileUp;
|
|
|
|
|
|
// 3. 保存节点更新
|
|
|
await _sqlSugar.Updateable(node)
|
|
|
.UpdateColumns(n => new
|
|
|
{
|
|
|
- n.ActualDone
|
|
|
+ n.ActualDone,
|
|
|
+ n.IsAssist,
|
|
|
+ n.IsFileUp,
|
|
|
})
|
|
|
.ExecuteCommandAsync();
|
|
|
//记录节点日志
|
|
|
@@ -1077,5 +1123,77 @@ namespace OASystem.Infrastructure.Repositories.Groups
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
+
|
|
|
+ #region 节点按钮策略
|
|
|
+ // 定义按钮状态计算策略接口
|
|
|
+ public interface IButtonStateStrategy
|
|
|
+ {
|
|
|
+ (bool IsEnaAssistBtn, bool IsEnaFileUpBtn) Calculate(Grp_ProcessOverview process, Grp_ProcessNode node, int index);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 通用策略
|
|
|
+ public class DefaultButtonStateStrategy : IButtonStateStrategy
|
|
|
+ {
|
|
|
+ public (bool IsEnaAssistBtn, bool IsEnaFileUpBtn) Calculate(Grp_ProcessOverview process, Grp_ProcessNode node, int index)
|
|
|
+ {
|
|
|
+ var totalNodes = process.Nodes.Count();
|
|
|
+ var isLastNode = index == totalNodes - 1;
|
|
|
+
|
|
|
+ return (false, isLastNode); // 默认只有最后一步启用文件上传
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 财务流程策略
|
|
|
+ public class FeeSettleButtonStateStrategy : IButtonStateStrategy
|
|
|
+ {
|
|
|
+ public (bool IsEnaAssistBtn, bool IsEnaFileUpBtn) Calculate(Grp_ProcessOverview process, Grp_ProcessNode node, int index)
|
|
|
+ {
|
|
|
+ var totalNodes = process.Nodes.Count();
|
|
|
+ var isLastNode = index == totalNodes - 1;
|
|
|
+
|
|
|
+ bool isEnaAssistBtn = node.NodeOrder == 1; // 首节点启用协助
|
|
|
+ bool isEnaFileUpBtn = isLastNode; // 最后一步启用文件上传
|
|
|
+
|
|
|
+ return (isEnaAssistBtn, isEnaFileUpBtn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 机票流程策略
|
|
|
+ public class FlightButtonStateStrategy : IButtonStateStrategy
|
|
|
+ {
|
|
|
+ public (bool IsEnaAssistBtn, bool IsEnaFileUpBtn) Calculate(Grp_ProcessOverview process, Grp_ProcessNode node, int index)
|
|
|
+ {
|
|
|
+ var totalNodes = process.Nodes.Count();
|
|
|
+ var isLastNode = index == totalNodes - 1;
|
|
|
+ var isSecondLastNode = index == totalNodes - 2;
|
|
|
+
|
|
|
+ bool isEnaAssistBtn = false;
|
|
|
+ bool isEnaFileUpBtn = isLastNode || isSecondLastNode; // 倒数两步都启用文件上传
|
|
|
+
|
|
|
+ return (isEnaAssistBtn, isEnaFileUpBtn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 策略工厂
|
|
|
+ public static class ButtonStateStrategyFactory
|
|
|
+ {
|
|
|
+ private static readonly Dictionary<GroupProcessType, IButtonStateStrategy> _strategies = new()
|
|
|
+ {
|
|
|
+ [GroupProcessType.Invitation] = new DefaultButtonStateStrategy(),
|
|
|
+ [GroupProcessType.Visa] = new DefaultButtonStateStrategy(),
|
|
|
+ [GroupProcessType.AirTicket] = new FlightButtonStateStrategy(),
|
|
|
+ [GroupProcessType.Hotel] = new DefaultButtonStateStrategy(),
|
|
|
+ [GroupProcessType.LocalGuide] = new DefaultButtonStateStrategy(),
|
|
|
+ [GroupProcessType.FeeSettle] = new FeeSettleButtonStateStrategy()
|
|
|
+ };
|
|
|
+
|
|
|
+ public static IButtonStateStrategy GetStrategy(GroupProcessType processType)
|
|
|
+ {
|
|
|
+ return _strategies.TryGetValue(processType, out var strategy)
|
|
|
+ ? strategy
|
|
|
+ : new DefaultButtonStateStrategy();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
}
|
|
|
}
|