feat: 优化OA用印文件下载逻辑,改进文件提取和错误处理
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载 OA 用印文件
|
||||
/// 通过 OA 接口下载用印文件
|
||||
/// </summary>
|
||||
/// <param name="fileUrl">文件下载地址</param>
|
||||
/// <param name="fileId">文件 ID</param>
|
||||
/// <returns>文件字节数组</returns>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 fj 字段尝试提取文件下载地址和文件名
|
||||
/// fj 格式:{"annexId":"url1,url2","annexName":"name1,name2"}
|
||||
/// 判断 flowInfos 中是否存在用印文件
|
||||
/// </summary>
|
||||
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))
|
||||
/// <summary>
|
||||
/// 从 detailMap 中提取用印文件 ID 和文件名
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user