You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
429 lines
16 KiB
429 lines
16 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using Volo.Abp.BackgroundWorkers;
|
|
using Volo.Abp.Guids;
|
|
using Volo.Abp.Threading;
|
|
using Volo.Abp.Uow;
|
|
using Win_in.Sfs.Wms.DataExchange.Domain.Shared;
|
|
using Win_in.Sfs.Wms.DataExchange.MesAgent.ReadFiles;
|
|
|
|
namespace Win_in.Sfs.Wms.DataExchange.MesAgent;
|
|
|
|
public class JisFileReadingWorker : AsyncPeriodicBackgroundWorkerBase
|
|
{
|
|
private readonly IOptions<DataExchangeOptions> _options;
|
|
|
|
/// <summary>
|
|
/// 配置
|
|
/// </summary>
|
|
private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;
|
|
|
|
/// <summary>
|
|
/// GUID生成
|
|
/// </summary>
|
|
private readonly IGuidGenerator _guidGenerator;
|
|
|
|
#region 变量
|
|
|
|
/// <summary>
|
|
/// 错误信息前缀
|
|
/// </summary>
|
|
private static string _errorMessagePrefix => System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType?.Name + ".";
|
|
|
|
private int _transferFileCountPerTime;
|
|
|
|
/// <summary>
|
|
/// 每次传输文件数量(工作目录到备份目录)
|
|
/// </summary>
|
|
public int TransferFileCountPerTime
|
|
{
|
|
get
|
|
{
|
|
if (_transferFileCountPerTime == 0)
|
|
{
|
|
_transferFileCountPerTime = _configuration["ConfigDic:TransferFileCountPerTime"].TryToInt() ?? 50;
|
|
}
|
|
return _transferFileCountPerTime;
|
|
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
public JisFileReadingWorker(
|
|
AbpAsyncTimer timer,
|
|
IOptions<DataExchangeOptions> options,
|
|
Microsoft.Extensions.Configuration.IConfiguration configuration,
|
|
IGuidGenerator guidGenerator,
|
|
IServiceScopeFactory serviceScopeFactory
|
|
) : base(timer, serviceScopeFactory)
|
|
{
|
|
_options = options;
|
|
|
|
Timer.Period = options.Value.ReadingFilesOptions.PeriodSeconds * 1000; //default 5 minutes
|
|
|
|
_configuration = configuration;
|
|
_guidGenerator = guidGenerator;
|
|
}
|
|
|
|
[UnitOfWork]
|
|
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
|
|
{
|
|
Logger.LogInformation("GetFiles:Starting: Handling Jis File Reading...");
|
|
if (!_options.Value.ReadingFilesOptions.Active)
|
|
{
|
|
Logger.LogInformation("GetFiles:Jis File Reading is not active!");
|
|
return;
|
|
}
|
|
|
|
//Timer.Stop(); //运行期间,暂定计时
|
|
|
|
await GetEdiData(workerContext).ConfigureAwait(false);
|
|
|
|
//Timer.Start(); //运行结束,开启计时
|
|
Logger.LogInformation("GetFiles:Completed: Handling Jis File Reading...");
|
|
}
|
|
|
|
#region 私有方法
|
|
|
|
public virtual async Task<PathConfigInfo> GetEdiData(PeriodicBackgroundWorkerContext workerContext)
|
|
{
|
|
//初始化目录
|
|
PathConfigInfo cfgInfo = ReadConfig();
|
|
//接收目录到工作目录
|
|
int fileCnt = ReceToWorkDir(cfgInfo);
|
|
//工作目录报文保存到数据库
|
|
var lst = await WorkDirFileToDatabase(cfgInfo, workerContext).ConfigureAwait(false);
|
|
|
|
Logger.LogInformation("GetFiles:接收{0}个报文,其中入库{1}个!", fileCnt, lst.Count);
|
|
|
|
return cfgInfo;
|
|
}
|
|
|
|
private PathConfigInfo ReadConfig()
|
|
{
|
|
_ = new PathConfigInfo("", "", "", "", "");
|
|
PathConfigInfo ret;
|
|
#region 取目录配置
|
|
try
|
|
{
|
|
string receiveDir = _configuration["ConfigDic:PathRead:接收目录"];
|
|
string workDir = _configuration["ConfigDic:PathRead:工作目录"];
|
|
string bakDir = _configuration["ConfigDic:PathRead:备份目录"];
|
|
string errorDir = _configuration["ConfigDic:PathRead:错误目录"];
|
|
string waitDir = _configuration["ConfigDic:PathRead:等待目录"];
|
|
|
|
string pathReadType = _configuration["ConfigDic:PathReadType"];
|
|
if (pathReadType != null && pathReadType == "绝对")
|
|
{
|
|
ret = new PathConfigInfo(receiveDir, workDir, bakDir, errorDir, waitDir);
|
|
}
|
|
else
|
|
{
|
|
ret = new PathConfigInfo(
|
|
GetAbsPath(receiveDir),
|
|
GetAbsPath(workDir),
|
|
GetAbsPath(bakDir),
|
|
GetAbsPath(errorDir),
|
|
GetAbsPath(waitDir)
|
|
);
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = "文件传输-取目录配置时出错:" + ex.Message;
|
|
throw new Exception(errorMsg);
|
|
}
|
|
#endregion
|
|
|
|
#region 创建目录
|
|
try
|
|
{
|
|
if (!Directory.Exists(ret.ReceivePath))
|
|
{
|
|
Directory.CreateDirectory(ret.ReceivePath);
|
|
}
|
|
if (!Directory.Exists(ret.WorkPath))
|
|
{
|
|
Directory.CreateDirectory(ret.WorkPath);
|
|
}
|
|
if (!Directory.Exists(ret.BakPath))
|
|
{
|
|
Directory.CreateDirectory(ret.BakPath);
|
|
}
|
|
if (!Directory.Exists(ret.ErrorPath))
|
|
{
|
|
Directory.CreateDirectory(ret.ErrorPath);
|
|
}
|
|
if (!Directory.Exists(ret.WaitPath))
|
|
{
|
|
Directory.CreateDirectory(ret.WaitPath);
|
|
}
|
|
string ymd = DateTime.Now.ToString("yyyy-MM-dd");
|
|
string bakChildPath = Path.Combine(ret.BakPath, ymd);
|
|
if (!Directory.Exists(bakChildPath))
|
|
{
|
|
Directory.CreateDirectory(bakChildPath);
|
|
}
|
|
|
|
//string ymdRepeat = "重复文件" + DateTime.Now.ToString("yyyy-MM-dd");
|
|
//string bakRepeatChildPath = Path.Combine(ret.BakPath, ymd);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = "文件传输-创建目录出错:" + ex.Message;
|
|
throw new Exception(errorMsg);
|
|
}
|
|
#endregion
|
|
|
|
#region 取报文过滤关键字
|
|
try
|
|
{
|
|
string fileFilterKeyword = _configuration["ConfigDic:FileFilterKeyword"];
|
|
ret.SetFileFilterKeyword(fileFilterKeyword);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = "文件传输-取报文过滤关键字配置时出错或没有配置数据:" + ex.Message;
|
|
throw new Exception(errorMsg);
|
|
}
|
|
#endregion
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将报文从接收目录移动到工作目录
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private int ReceToWorkDir(PathConfigInfo cfgInfo)
|
|
{
|
|
int ret = 0;
|
|
DirectoryInfo receiveDir = new DirectoryInfo(cfgInfo.ReceivePath);
|
|
FileInfo[] receiveFileLst = receiveDir.GetFiles(cfgInfo.FileFilterKeyword, SearchOption.TopDirectoryOnly); //批量读取接收目录文件
|
|
try
|
|
{
|
|
if (receiveFileLst.Length > 0)
|
|
{
|
|
receiveFileLst = receiveFileLst.Where(itm => itm.Length > 0).OrderBy(itm => itm.LastWriteTime).ToArray(); //Take(TransferFileCountPerTime)
|
|
ret = receiveFileLst.Length;
|
|
foreach (FileInfo receiveFileObj in receiveFileLst) //遍历接收目录文件
|
|
{
|
|
string workFileFullName = Path.Combine(cfgInfo.WorkPath, receiveFileObj.Name);
|
|
receiveFileObj.MoveTo(workFileFullName, true);
|
|
}
|
|
}
|
|
else //接收目录没有文件时从等待目录接收
|
|
{
|
|
DirectoryInfo waitDir = new DirectoryInfo(cfgInfo.WaitPath);
|
|
FileInfo[] waitFileLst = waitDir.GetFiles(cfgInfo.FileFilterKeyword, SearchOption.TopDirectoryOnly);
|
|
if (waitFileLst.Length > 0)
|
|
{
|
|
waitFileLst = waitFileLst.OrderBy(itm => itm.LastWriteTime).Take(TransferFileCountPerTime).ToArray();
|
|
foreach (FileInfo waitFileItm in waitFileLst) //遍历接收目录文件
|
|
{
|
|
string workFileFullName = Path.Combine(cfgInfo.WorkPath, waitFileItm.Name);
|
|
waitFileItm.MoveTo(workFileFullName, true);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = $"将多个报文从接收目录移动到工作目录时报错:{ex.Message}";
|
|
throw new Exception(errorMsg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 工作目录中文件保存到数据库
|
|
/// </summary>
|
|
/// <param name="cfgInfo"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<List<MessageReceiveDTO>> WorkDirFileToDatabase(PathConfigInfo cfgInfo, PeriodicBackgroundWorkerContext workerContext)
|
|
{
|
|
|
|
List<MessageReceiveDTO> retLst = new List<MessageReceiveDTO>();
|
|
|
|
//批量读取工作目录文件
|
|
DirectoryInfo workDir = new DirectoryInfo(cfgInfo.WorkPath);
|
|
FileInfo[] workFileLst = workDir.GetFiles(cfgInfo.FileFilterKeyword, SearchOption.TopDirectoryOnly);
|
|
workFileLst = workFileLst.OrderBy(itm => itm.LastWriteTime).Take(TransferFileCountPerTime).ToArray();
|
|
|
|
//遍历【工作目录】文件
|
|
foreach (FileInfo workFileObj in workFileLst)
|
|
{
|
|
string fileName = workFileObj.Name;
|
|
|
|
Logger.LogInformation($"GetFiles:{fileName}=>WorkDirFileToDatabase,开始加载IMessageReceiveAppService。。。");
|
|
|
|
//Resolve dependencies
|
|
var messageReceiveAppService = workerContext
|
|
.ServiceProvider
|
|
.GetRequiredService<QAD.IMessageReceiveAppService>();
|
|
|
|
Logger.LogInformation($"GetFiles:{fileName}=>WorkDirFileToDatabase,加载IMessageReceiveAppService完毕!");
|
|
|
|
if (fileName.TrimEnd(workFileObj.Extension.ToCharArray()).EndsWith(((int)EnumFileTypeStatus.Add).ToString()))
|
|
{
|
|
var exsitFileInfo = await messageReceiveAppService.GetByFileNameAsync(fileName).ConfigureAwait(false);
|
|
|
|
//确认文件是否已经的读取过,已经读取过就把文件放到备份目录的重复文件夹
|
|
if (exsitFileInfo != null)
|
|
{
|
|
WorkDirToBakRepeatDir(cfgInfo, fileName); ////将文件从【工作目录】移动到【备份目录的重复文件夹】
|
|
|
|
Logger.LogInformation($"GetFiles:{fileName}=>文件已经保存过,将文件从【工作目录】移动到【备份目录的重复文件夹】。");
|
|
|
|
continue;
|
|
}
|
|
|
|
}
|
|
Logger.LogInformation($"GetFiles:{fileName}=>GetByFileNameAsync 获取结束,无此文件的历史信息,可以继续读取数据!");
|
|
|
|
string fileSimpleName = workFileObj.Name.Replace(workFileObj.Extension, "");
|
|
|
|
string upinsetType = fileSimpleName.Substring(fileSimpleName.Length - 2);
|
|
|
|
try
|
|
{
|
|
//读取工作文件内容
|
|
StreamReader sr = workFileObj.OpenText();
|
|
var text = await sr.ReadToEndAsync().ConfigureAwait(false);
|
|
sr.Close();
|
|
//保存到报文接收表
|
|
var msgReceiveObj = new MessageReceiveInput()
|
|
{
|
|
TraceId = _guidGenerator.Create().ToString(),
|
|
MessageFileName = fileName,
|
|
MessageContent = text,
|
|
ReceiveStatus = EnumReceiveStatus.Received,
|
|
ReceiveTime = DateTime.Now,
|
|
LastUpdateTime = workFileObj.LastWriteTime,
|
|
Type = upinsetType,
|
|
ErrorCount = 0,
|
|
ErrorMessage = "",
|
|
|
|
};
|
|
|
|
Logger.LogInformation($"GetFiles:{fileName}=>WorkDirFileToDatabase,开始保存文件{fileName}信息。。。");
|
|
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 TraceId,值={msgReceiveObj.TraceId}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 MessageFileName,值={fileName}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 MessageContent,值={text}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 ReceiveStatus,值={EnumReceiveStatus.Received}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 ReceiveTime,值={msgReceiveObj.ReceiveTime}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 Type,值={upinsetType}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 ErrorCount,值={0}");
|
|
Logger.LogInformation($"GetFiles:{fileName}=>变量 ErrorMessage,值={""}");
|
|
|
|
var succObj = await messageReceiveAppService.AddAsync(msgReceiveObj).ConfigureAwait(false);
|
|
Logger.LogInformation($"GetFiles:{fileName}=>WorkDirFileToDatabase,保存文件{fileName}信息结束");
|
|
|
|
if (succObj != null)
|
|
{
|
|
WorkDirToBakDir(cfgInfo, fileName); //将文件从【工作目录】移动到【备份目录】
|
|
retLst.Add(succObj);
|
|
}
|
|
else
|
|
{
|
|
WorkDirToErrorDir(cfgInfo, fileName); //将文件从【工作目录】移动到【错误目录】
|
|
string msg = $"将报文{fileName}保存到数据库时失败";
|
|
//_logRemindDomainService.WriteLogRemind("报文传输", msg, LogTypeEnum.None);
|
|
Logger.LogError(_errorMessagePrefix + msg);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = $"调用WorkDirFileToDatabase方法时报错:{fileName}:{ex.Message}";
|
|
string errorMsg2 = $"调用WorkDirFileToDatabase方法时报错:{fileName}:{ex.ToString()}";
|
|
//_logRemindDomainService.WriteLogRemind("报文保存到数据库", errorMsg, LogTypeEnum.None);
|
|
Logger.LogError(_errorMessagePrefix + errorMsg);
|
|
|
|
Logger.LogError(_errorMessagePrefix + errorMsg2);
|
|
|
|
}
|
|
|
|
}//循环);
|
|
return retLst.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将报文从工作目录移动到备份目录
|
|
/// </summary>
|
|
/// <param name="workFileFullName"></param>
|
|
/// <param name="bakFileFullName"></param>
|
|
private static void WorkDirToBakDir(PathConfigInfo cfgInfo, string fileName)
|
|
{
|
|
string ymd = DateTime.Now.ToString("yyyy-MM-dd");
|
|
string bakChildPath = Path.Combine(cfgInfo.BakPath, ymd); //备份目录每天创建一个子目录
|
|
string workFileFullName = Path.Combine(cfgInfo.WorkPath, fileName);
|
|
string bakFileFullName = Path.Combine(bakChildPath, fileName);
|
|
if (File.Exists(workFileFullName))
|
|
{
|
|
File.Move(workFileFullName, bakFileFullName, true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将报文从工作目录移动到备份目录的重复文件夹
|
|
/// </summary>
|
|
/// <param name="workFileFullName"></param>
|
|
/// <param name="bakFileFullName"></param>
|
|
private static void WorkDirToBakRepeatDir(PathConfigInfo cfgInfo, string fileName)
|
|
{
|
|
string ymd = "重复文件" + DateTime.Now.ToString("yyyy-MM-dd");
|
|
string bakChildPath = Path.Combine(cfgInfo.BakPath, ymd); //备份目录每天创建一个子目录
|
|
string workFileFullName = Path.Combine(cfgInfo.WorkPath, fileName);
|
|
string bakFileFullName = Path.Combine(bakChildPath, fileName);
|
|
|
|
if (!Directory.Exists(bakChildPath))
|
|
{
|
|
Directory.CreateDirectory(bakChildPath);
|
|
}
|
|
|
|
if (File.Exists(workFileFullName))
|
|
{
|
|
File.Move(workFileFullName, bakFileFullName, true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将报文从工作目录移动到错误目录
|
|
/// </summary>
|
|
/// <param name="workFileFullName"></param>
|
|
/// <param name="bakFileFullName"></param>
|
|
private static void WorkDirToErrorDir(PathConfigInfo cfgInfo, string fileName)
|
|
{
|
|
string workFileFullName = Path.Combine(cfgInfo.WorkPath, fileName);
|
|
string errFileFullName = Path.Combine(cfgInfo.ErrorPath, fileName);
|
|
if (File.Exists(workFileFullName))
|
|
{
|
|
File.Move(workFileFullName, errFileFullName, true);
|
|
}
|
|
}
|
|
|
|
private static string GetAbsPath(string sourcePath)
|
|
{
|
|
if (sourcePath.Trim().StartsWith("."))
|
|
{
|
|
string childPath = sourcePath.Trim().Replace("/", "\\").Replace(".\\", "");
|
|
string rootPath = System.Environment.CurrentDirectory;
|
|
string ret = Path.Combine(rootPath, childPath);
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return sourcePath;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|