diff --git a/YLErpDAL/Modules/TradeModule/TradeOAService.cs b/YLErpDAL/Modules/TradeModule/TradeOAService.cs
index 08ca0ee4..29c670ea 100644
--- a/YLErpDAL/Modules/TradeModule/TradeOAService.cs
+++ b/YLErpDAL/Modules/TradeModule/TradeOAService.cs
@@ -405,11 +405,10 @@ namespace YLErp.Modules.TradeModule
continue;
}
- // 3. 判断用印是否完成:fj 字段为空表示未盖完章,有值表示已用印
- var fj = flowData.flowInfos?["fj"];
- if (fj == null || fj.Type == Newtonsoft.Json.Linq.JTokenType.Null)
+ // 3. 判断用印是否完成:检查 detailMap 中是否有用印文件
+ if (!HasStampFiles(flowData.flowInfos))
{
- logger.Info($"OA用印未完成,fj为空,requestid:{oa.oa_fileid}");
+ logger.Info($"OA用印未完成,detailMap 中无文件信息,requestid:{oa.oa_fileid}");
continue;
}
@@ -471,31 +470,55 @@ namespace YLErp.Modules.TradeModule
}
///
- /// 下载 OA 用印文件
+ /// 通过 OA 接口下载用印文件
///
- /// 文件下载地址
+ /// 文件 ID
/// 文件字节数组
- private byte[] DownloadOAFile(string fileUrl)
+ private byte[] DownloadOAFile(string fileId)
{
try
{
- if (string.IsNullOrEmpty(fileUrl))
+ if (string.IsNullOrEmpty(fileId))
{
return null;
}
- logger.Info($"下载OA用印文件: {fileUrl}");
+ var oaConfigSection = AppManager.GetConfiguration().GetSection("oa_confg");
+ var baseUrl = oaConfigSection["BaseUrl"];
+ var downloadFileUrl = oaConfigSection["DownloadFileUrl"];
+ var systemToken = oaConfigSection["SystemToken"];
+ var systemName = oaConfigSection["SystemName"];
- var response = _httpClient.GetAsync(fileUrl).Result;
- response.EnsureSuccessStatusCode();
- var fileBytes = response.Content.ReadAsByteArrayAsync().Result;
+ if (string.IsNullOrEmpty(baseUrl) || string.IsNullOrEmpty(downloadFileUrl))
+ {
+ logger.Info("OA下载接口配置不完整");
+ return null;
+ }
- logger.Info($"下载OA用印文件成功,大小: {fileBytes.Length} 字节");
- return fileBytes;
+ var requestUrl = $"{baseUrl.TrimEnd('/')}/{downloadFileUrl.TrimStart('/')}?fileid={Uri.EscapeDataString(fileId)}&systemToken={Uri.EscapeDataString(systemToken)}&systemName={Uri.EscapeDataString(systemName ?? string.Empty)}";
+ logger.Info($"通过OA接口下载用印文件: fileid={fileId}");
+
+ using (var httpClient = new System.Net.Http.HttpClient { Timeout = TimeSpan.FromMinutes(2) })
+ {
+ var response = httpClient.GetAsync(requestUrl).Result;
+ var fileBytes = response.Content.ReadAsByteArrayAsync().Result;
+
+ // 检查返回的是否为错误 JSON
+ if (response.Content.Headers.ContentType?.MediaType == "application/json" ||
+ (fileBytes.Length > 0 && fileBytes[0] == (byte)'{'))
+ {
+ var responseStr = System.Text.Encoding.UTF8.GetString(fileBytes);
+ logger.Error($"下载用印文件接口返回错误: {responseStr}");
+ return null;
+ }
+
+ logger.Info($"通过OA接口下载用印文件成功,大小: {fileBytes.Length} 字节");
+ return fileBytes;
+ }
}
catch (Exception ex)
{
- logger.Error($"下载OA用印文件失败: {fileUrl}, 错误:{ex.Message}", ex);
+ logger.Error($"通过OA接口下载用印文件失败: fileid={fileId}, 错误:{ex.Message}", ex);
return null;
}
}
@@ -518,16 +541,15 @@ namespace YLErp.Modules.TradeModule
return new TradeOAResult { TradeId = oa.trade_id, Success = false, Message = "未找到确认书文档" };
}
- // 从 fj 字段提取用印文件信息
- var fj = queryData.flowInfos?["fj"];
- if (!TryExtractFileFromFj(fj, out var fileUrl, out var fileName))
+ // 从 detailMap 中提取用印文件信息
+ if (!TryExtractFileFromDetailMap(queryData.flowInfos, out var fileId, out var fileName))
{
- logger.Info($"无法从 fj 中提取用印文件信息,contract_code:{oa.contract_code}");
+ logger.Info($"无法从 detailMap 中提取用印文件信息,contract_code:{oa.contract_code}");
return new TradeOAResult { TradeId = oa.trade_id, Success = false, Message = "无法提取用印文件信息" };
}
- // 下载用印文件
- var fileBytes = DownloadOAFile(fileUrl);
+ // 通过 OA 接口下载用印文件
+ var fileBytes = DownloadOAFile(fileId);
if (fileBytes == null || fileBytes.Length == 0)
{
logger.Info($"未获取到用印文件,contract_code:{oa.contract_code}");
@@ -597,47 +619,61 @@ namespace YLErp.Modules.TradeModule
}
///
- /// 从 fj 字段尝试提取文件下载地址和文件名
- /// fj 格式:{"annexId":"url1,url2","annexName":"name1,name2"}
+ /// 判断 flowInfos 中是否存在用印文件
///
- private bool TryExtractFileFromFj(Newtonsoft.Json.Linq.JToken fj, out string fileUrl, out string fileName)
+ private bool HasStampFiles(Newtonsoft.Json.Linq.JObject flowInfos)
{
- fileUrl = null;
- fileName = null;
-
- if (fj == null || fj.Type == Newtonsoft.Json.Linq.JTokenType.Null)
+ var detailMap = flowInfos?["detailMap"];
+ if (detailMap == null || !detailMap.Any())
{
return false;
}
- // 如果是字符串,直接当作 URL
- if (fj.Type == Newtonsoft.Json.Linq.JTokenType.String)
+ foreach (var detail in detailMap)
{
- fileUrl = fj.ToString();
- fileName = Path.GetFileName(fileUrl);
- return !string.IsNullOrEmpty(fileUrl);
+ var fileInfos = detail["gatewayFileRequestFileInfo"];
+ if (fileInfos != null && fileInfos.Any())
+ {
+ return true;
+ }
}
- // 解析 annexId(逗号分隔的 URL 数组)和 annexName(逗号分隔的文件名数组)
- var annexIdStr = fj["annexId"]?.ToString();
- var annexNameStr = fj["annexName"]?.ToString();
+ return false;
+ }
- if (!string.IsNullOrEmpty(annexIdStr))
+ ///
+ /// 从 detailMap 中提取用印文件 ID 和文件名
+ ///
+ private bool TryExtractFileFromDetailMap(Newtonsoft.Json.Linq.JObject flowInfos, out string fileId, out string fileName)
+ {
+ fileId = null;
+ fileName = null;
+
+ var detailMap = flowInfos?["detailMap"];
+ if (detailMap == null || !detailMap.Any())
{
- fileUrl = annexIdStr.Split(',').Select(s => s.Trim()).FirstOrDefault(s => !string.IsNullOrEmpty(s));
+ return false;
}
- if (!string.IsNullOrEmpty(annexNameStr))
+ foreach (var detail in detailMap)
{
- fileName = annexNameStr.Split(',').Select(s => s.Trim()).FirstOrDefault(s => !string.IsNullOrEmpty(s));
+ var fileInfos = detail["gatewayFileRequestFileInfo"];
+ if (fileInfos != null && fileInfos.Any())
+ {
+ var firstFile = fileInfos.FirstOrDefault();
+ if (firstFile != null)
+ {
+ fileId = firstFile["id"]?.ToString();
+ fileName = firstFile["fileName"]?.ToString();
+ if (!string.IsNullOrEmpty(fileId))
+ {
+ return true;
+ }
+ }
+ }
}
- if (string.IsNullOrEmpty(fileName) && !string.IsNullOrEmpty(fileUrl))
- {
- fileName = Path.GetFileName(fileUrl);
- }
-
- return !string.IsNullOrEmpty(fileUrl);
+ return false;
}
///