diff --git a/YLErpDAL/Modules/TradeModule/TradeApprovalOAService.cs b/YLErpDAL/Modules/TradeModule/TradeApprovalOAService.cs index afd3e342..a138e831 100644 --- a/YLErpDAL/Modules/TradeModule/TradeApprovalOAService.cs +++ b/YLErpDAL/Modules/TradeModule/TradeApprovalOAService.cs @@ -219,20 +219,19 @@ namespace YLErp.Modules.TradeModule { var messages = new List(); var staleAt = DateTime.Now.AddMinutes(-5); - var syncInstance = $"{Environment.MachineName}/pid:{Environment.ProcessId}/run:{Guid.NewGuid():N}"; var pending = DbContext.tradeApprovalOaResult .Where(x => x.is_valid && !string.IsNullOrWhiteSpace(x.oa_fileid) && (string.IsNullOrWhiteSpace(requestId) || x.oa_fileid == requestId) && (x.status == Pending || (x.status == Syncing && (x.last_query_time == null || x.last_query_time < staleAt)))) .ToList(); - _logger.Info($"开始轮询 OA 移动审批状态,requestId:{requestId ?? "全部"},待查询数量:{pending.Count},实例:{syncInstance}"); + _logger.Info($"开始轮询 OA 移动审批状态,requestId:{requestId ?? "全部"},待查询数量:{pending.Count},同步中超时阈值:{staleAt:yyyy-MM-dd HH:mm:ss.fff}"); foreach (var record in pending) { var claimed = false; try { - _logger.Info($"查询 OA 移动审批状态,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},本地状态:{record.status},上次查询:{record.last_query_time:yyyy-MM-dd HH:mm:ss.fff},实例:{syncInstance}"); + _logger.Info($"查询 OA 移动审批状态,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},本地状态:{record.status},上次查询:{record.last_query_time:yyyy-MM-dd HH:mm:ss.fff}"); var response = Query(record.oa_fileid); record.last_response = response.ToString(); var flow = response["data"] is JArray data @@ -252,34 +251,37 @@ namespace YLErp.Modules.TradeModule var isReturned = flowStatusType == "0" && flowNode == "退回"; var isApproved = flowStatusType == "3" && (flowNode == "结束" || flowNode == "强制归档"); - _logger.Info($"OA 移动审批查询结果,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},flowStatusType:{flowStatusType},flowNode:{flowNode},判定:{(isReturned ? "退回" : isApproved ? "通过" : "等待")}"); + _logger.Info($"OA 移动审批查询结果,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},是否命中流程:{flow != null},flowStatusType:{flowStatusType},flowNode:{flowNode},是否退回:{isReturned},是否通过:{isApproved},判定:{(isReturned ? "退回" : isApproved ? "通过" : "等待")}"); if (!isApproved && !isReturned) { - _logger.Info($"OA 移动审批继续等待,不会推进本地流程,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},flowStatusType:{flowStatusType},flowNode:{flowNode},实例:{syncInstance}"); + _logger.Info($"OA 移动审批继续等待,更新最近查询时间但不修改本地审批流程,OA记录:{record.id},requestId:{record.oa_fileid},本地状态保持:{record.status}"); record.last_query_time = DateTime.Now; DbContext.SaveChanges(); continue; } DbContext.SaveChanges(); - _logger.Info($"OA 审批结果满足回写条件,准备抢占同步记录,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},本地状态:{record.status},实例:{syncInstance}"); - if (!TryClaimForSync(record.id)) + _logger.Info($"OA 审批结果满足回写条件,准备将记录设为同步中,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},当前本地状态:{record.status}"); + var claimAffectedRows = ClaimForSync(record.id); + if (claimAffectedRows != 1) { - _logger.Info($"OA 审批结果同步未抢占记录,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},实例:{syncInstance}"); + _logger.Info($"OA 审批结果未能将记录设为同步中,OA记录:{record.id},requestId:{record.oa_fileid},更新行数:{claimAffectedRows}"); continue; } claimed = true; - _logger.Info($"OA 审批结果已抢占记录并置为同步中,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},实例:{syncInstance}"); + _logger.Info($"OA 审批结果已将记录设为同步中,OA记录:{record.id},requestId:{record.oa_fileid},更新行数:{claimAffectedRows}"); var trade = DbContext.trade.Find(record.trade_id); if (trade == null) { - SetClaimedStatus(record.id, "同步失败", "交易不存在"); + var statusAffectedRows = SetClaimedStatus(record.id, "同步失败", "交易不存在"); + _logger.Error($"OA 审批结果不再回写,交易不存在,OA记录:{record.id},requestId:{record.oa_fileid},目标状态:同步失败,更新行数:{statusAffectedRows}"); continue; } if (GetCurrentNode(trade)?.id != record.approval_process_id) { - SetClaimedStatus(record.id, "同步忽略", "当前审批节点已变化,忽略 OA 结果"); + var statusAffectedRows = SetClaimedStatus(record.id, "同步忽略", "当前审批节点已变化,忽略 OA 结果"); + _logger.Info($"OA 审批结果不再回写,当前审批节点已变化,OA记录:{record.id},requestId:{record.oa_fileid},目标状态:同步忽略,更新行数:{statusAffectedRows}"); continue; } var result = new TradeOpenService(this).UpdateTradeProcessLog(new TradeOpenReqModel @@ -292,13 +294,14 @@ namespace YLErp.Modules.TradeModule }); if (!string.IsNullOrWhiteSpace(result.ErrorMsg)) { - SetClaimedStatus(record.id, Pending, result.ErrorMsg); - _logger.Error($"OA 审批结果回写本地失败,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},原因:{result.ErrorMsg},实例:{syncInstance}"); + var statusAffectedRows = SetClaimedStatus(record.id, Pending, result.ErrorMsg); + _logger.Error($"OA 审批结果回写本地失败,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},目标状态:{Pending},更新行数:{statusAffectedRows},原因:{result.ErrorMsg}"); } else { - SetClaimedStatus(record.id, isReturned ? "退回" : "通过", null); - _logger.Info($"OA 审批结果回写本地成功,交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},结果:{(isReturned ? "退回" : "通过")},实例:{syncInstance}"); + var targetStatus = isReturned ? "退回" : "通过"; + var statusAffectedRows = SetClaimedStatus(record.id, targetStatus, null); + _logger.Info($"OA 审批结果回写本地成功,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},本地审批结果:{(isReturned ? "拒绝" : "通过")},OA记录目标状态:{targetStatus},更新行数:{statusAffectedRows}"); } messages.Add(record.trade_id + ":" + (string.IsNullOrWhiteSpace(result.ErrorMsg) ? (isReturned ? "退回" : "通过") : Pending)); } @@ -306,7 +309,8 @@ namespace YLErp.Modules.TradeModule { if (claimed) { - SetClaimedStatus(record.id, Pending, ex.Message); + var statusAffectedRows = SetClaimedStatus(record.id, Pending, ex.Message); + _logger.Error($"OA 轮询异常后恢复记录状态,OA记录:{record.id},requestId:{record.oa_fileid},目标状态:{Pending},更新行数:{statusAffectedRows}", ex); } else { @@ -314,10 +318,10 @@ namespace YLErp.Modules.TradeModule record.oa_msg = ex.Message; DbContext.SaveChanges(); } - _logger.Error($"轮询 OA 审批状态失败,requestId:{record.oa_fileid}", ex); + _logger.Error($"轮询 OA 审批状态失败,OA记录:{record.id},交易:{record.trade_id},节点:{record.approval_process_id},requestId:{record.oa_fileid},是否已设为同步中:{claimed}", ex); } } - _logger.Info($"OA 移动审批状态轮询结束,已处理数量:{messages.Count},实例:{syncInstance}"); + _logger.Info($"OA 移动审批状态轮询结束,已处理数量:{messages.Count}"); return messages; } @@ -369,13 +373,13 @@ namespace YLErp.Modules.TradeModule || trade.TradeStatus == ConsTrade.互换待复核; } - private bool TryClaimForSync(int recordId) + private int ClaimForSync(int recordId) { var now = DateTime.Now; return DbContext.Database.ExecuteSqlRaw( "UPDATE trade_approval_oa_result SET status = {0}, last_query_time = {1} " + "WHERE id = {2} AND is_valid = 1 AND (status = {3} OR (status = {0} AND (last_query_time IS NULL OR last_query_time < {4})))", - Syncing, now, recordId, Pending, now.AddMinutes(-5)) == 1; + Syncing, now, recordId, Pending, now.AddMinutes(-5)); } private bool TryChangeStatus(int recordId, string expectedStatus, string targetStatus, string message) @@ -385,9 +389,9 @@ namespace YLErp.Modules.TradeModule targetStatus, message, recordId, expectedStatus) == 1; } - private void SetClaimedStatus(int recordId, string status, string message) + private int SetClaimedStatus(int recordId, string status, string message) { - DbContext.Database.ExecuteSqlRaw( + return DbContext.Database.ExecuteSqlRaw( "UPDATE trade_approval_oa_result SET status = {0}, oa_msg = {1} WHERE id = {2} AND is_valid = 1 AND status = {3}", status, message, recordId, Syncing); }