484 lines
15 KiB
C#
484 lines
15 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using YLErp.Abstract;
|
|
using YLErp.DBModels;
|
|
using YLErp.DBModels.Abstract;
|
|
using YLErp.Modules.TradeModule.DealModule;
|
|
using System.Net.Http;
|
|
using BaseOUDAL;
|
|
using YLErp.Modules;
|
|
using Qdp.Pricing.Base.Enums;
|
|
using System.Threading.Channels;
|
|
using YLErp.Model;
|
|
using Org.BouncyCastle.Asn1.Ocsp;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Helpers;
|
|
using Qdp.Pricing.Library.Base.Utilities;
|
|
using YLErp.Modules.SuperviseReportModule.SAC.Service;
|
|
using NPOI.POIFS.Crypt;
|
|
using YLErp.Models;
|
|
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
|
using YLErp.Modules.ApiModule;
|
|
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
|
|
using YLErp.Model.Enum;
|
|
using Qdp.Foundation.Utilities;
|
|
using static YLErp.ConsGlobal;
|
|
using System.Net.Http.Headers;
|
|
using NPOI.HPSF;
|
|
using YieldChain.Security;
|
|
|
|
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
|
{
|
|
/// <summary>
|
|
/// 自动用印业务类
|
|
/// </summary>
|
|
public class SealTaskHandleService : YLBaseService, ISealTaskHandler
|
|
{
|
|
/// <summary>
|
|
/// 用印队列
|
|
/// </summary>
|
|
private static readonly Queue<SealTask> ContractQueue = new Queue<SealTask>();
|
|
private Thread _thread = null;
|
|
private bool _runStatus = false;
|
|
private readonly object _obj = new object();
|
|
|
|
private readonly IYcLogger _logger;
|
|
|
|
private HttpClientWrap _httpClient = null;
|
|
|
|
private HttpClientWrap httpClient
|
|
{
|
|
get
|
|
{
|
|
if (_httpClient == null)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (_httpClient == null)
|
|
{
|
|
_httpClient = new HttpClientWrap(PS.GetErpConfig().SealApi,60);
|
|
}
|
|
}
|
|
}
|
|
return _httpClient;
|
|
}
|
|
}
|
|
|
|
private OptUserInfo _systemUser = new OptUserInfo(0, "系统用印", OptUserFrom.System);
|
|
|
|
//private readonly string _sealApi = ;
|
|
//private readonly IHttpClientFactory _httpClientFactory;
|
|
|
|
public SealTaskHandleService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
_logger = LogFactory.GetLogger("确认书用印");
|
|
|
|
|
|
}
|
|
|
|
public void AddQueue(ITradeContractDocument confirmDoc, List<int> tradeIds)
|
|
{
|
|
|
|
try
|
|
{
|
|
lock (_obj)
|
|
{
|
|
|
|
UpdateTradeContractDocument(confirmDoc, (int)SealResultEnum.用印等待中, null);
|
|
|
|
_logger.Info("等待进入排队序列...");
|
|
|
|
tradeIds.ForEach(tId =>
|
|
{
|
|
SaveTradeAuditLog(tId, "", "开始排队", DateTime.Now);
|
|
_logger.Info($"交易编号:{tId}开始排队,等待用印");
|
|
});
|
|
|
|
StartSealTask(confirmDoc, tradeIds);
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Info($"排队失败,错误信息:{ex.Message}");
|
|
}
|
|
|
|
//ExecuteSealTask();
|
|
}
|
|
|
|
private void StartSealTask(ITradeContractDocument confirmDoc, List<int> tradeids)
|
|
{
|
|
var sealTask = new SealTask();
|
|
sealTask.Document = confirmDoc;
|
|
sealTask.TradeIds = tradeids;
|
|
ContractQueue.Enqueue(sealTask);
|
|
|
|
if (!_runStatus)
|
|
{
|
|
_runStatus = true;
|
|
_thread = new Thread(new ThreadStart(ExecuteSealTask));
|
|
_thread.Start();
|
|
_logger.Info($"线程成功开启");
|
|
}
|
|
}
|
|
|
|
public void AddQueue(ITradeContractDocument confirmDoc, int tradeId)
|
|
{
|
|
try
|
|
{
|
|
lock (_obj)
|
|
{
|
|
_logger.Info("等待进入排队序列...");
|
|
UpdateTradeContractDocument(confirmDoc, (int)SealResultEnum.用印等待中, null);
|
|
|
|
SaveTradeAuditLog(tradeId, "", "开始排队", DateTime.Now);
|
|
|
|
StartSealTask(confirmDoc, new List<int>() { tradeId });
|
|
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Info($"排队失败,错误信息:{ex.Message}");
|
|
}
|
|
|
|
}
|
|
|
|
public void RemoveQueue(int tradeId)
|
|
{
|
|
lock (_obj)
|
|
{
|
|
for (int i = 0; i < ContractQueue.Count; i++)
|
|
{
|
|
var obj = ContractQueue.Dequeue();
|
|
if (obj.TradeIds.Contains(tradeId))
|
|
{
|
|
obj.TradeIds.Remove(tradeId);
|
|
}
|
|
ContractQueue.Enqueue(obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void ExecuteSealTask()
|
|
{
|
|
//SetLog(tradeIds,"开始用印");
|
|
|
|
while (true)
|
|
{
|
|
SealTask obj = null;
|
|
lock (_obj)
|
|
{
|
|
if (!ContractQueue.TryPeek(out obj))
|
|
{
|
|
_runStatus = false;
|
|
_logger.Info($"线程执行结束");
|
|
break;
|
|
}
|
|
_logger.Info($"线程成功取到对象");
|
|
}
|
|
|
|
//发送用印到接口
|
|
var (success, result, fileBytesStr) = await UploadApiAsync(obj.Document, PS.GetErpConfig().SealKeyWord);
|
|
lock (_obj)
|
|
{
|
|
ContractQueue.TryPeek(out var temp);
|
|
//if (obj != temp)
|
|
//{
|
|
// continue;
|
|
//}
|
|
if (!success)
|
|
{
|
|
UpdateTradeContractDocument(obj.Document, (int)SealResultEnum.失败, result);
|
|
}
|
|
else
|
|
{
|
|
//上传
|
|
var ms = new MemoryStream();
|
|
if (!string.IsNullOrWhiteSpace(fileBytesStr))
|
|
{
|
|
|
|
var fileBytes = Convert.FromBase64String(fileBytesStr);
|
|
|
|
ms.Write(fileBytes, 0, fileBytes.Length);
|
|
|
|
//OptUser.UserId = 0;
|
|
|
|
//OptUser.UserName = "系统用印";
|
|
}
|
|
|
|
var (flag, msg, optDate,stampPath) = new ConfirmationGenerateService(_systemUser).UploadContractFile(obj.Document.EncryptId, obj.Document.Comments, obj.Document.Code, true, false, new UploadFileModel
|
|
{
|
|
Length = ms.Length,
|
|
ContentType = "application/pdf",
|
|
FileName = obj.Document.FileName,
|
|
OpenReadStream = () => ms
|
|
});
|
|
|
|
if (flag)
|
|
{
|
|
UpdateTradeContractDocument(obj.Document, (int)SealResultEnum.成功, result);
|
|
}
|
|
else
|
|
{
|
|
UpdateTradeContractDocument(obj.Document, (int)SealResultEnum.失败, msg);
|
|
}
|
|
|
|
foreach (var tId in temp.TradeIds)
|
|
{
|
|
if (!success)
|
|
{
|
|
//记日志
|
|
_logger.Error($"交易编号:{tId}用印失败:{result}");
|
|
|
|
SaveTradeAuditLog(tId, result, "用印失败", DateTime.Now);
|
|
continue;
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
//记日志
|
|
_logger.Info($"交易编号:{tId}用印文件上传成功");
|
|
|
|
SaveTradeAuditLog(tId, result, "用印成功", optDate);
|
|
}
|
|
else
|
|
{
|
|
//记日志
|
|
_logger.Error($"交易编号:{tId}用印文件上传失败:{msg}");
|
|
|
|
SaveTradeAuditLog(tId, msg, "用印失败", optDate);
|
|
}
|
|
}
|
|
}
|
|
|
|
ContractQueue.Dequeue();
|
|
|
|
_logger.Info("用印结束");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="document"></param>
|
|
/// <param name="keyword"></param>
|
|
/// <returns>
|
|
/// <para>1:用印是否成功</para>
|
|
/// <para>2:用印接口返回信息</para>
|
|
/// <para>3:用印文件base64字符串</para>
|
|
/// </returns>
|
|
public async Task<(bool, string, string)> UploadApiAsync(ITradeContractDocument document, string keyword)
|
|
{
|
|
var msg = "";
|
|
try
|
|
{
|
|
_logger.Info("请求用印接口token");
|
|
|
|
|
|
var res = await httpClient.PostMultipartFormDataAsync("es/v1/getToken", new Dictionary<string, HttpContent>
|
|
{
|
|
["appid"] = new StringContent("zqsy_api_yl"),
|
|
["secretkey"] = new StringContent("8PyrLMVxT1=WzTmr")
|
|
}, null);
|
|
|
|
var tokenModel = JsonHelper.Deserialize<ZQTokenApiResponseModel>(res);
|
|
|
|
var token = "";
|
|
|
|
if (tokenModel.success)
|
|
{
|
|
token = tokenModel.data.token;
|
|
_logger.Info("请求用印接口token成功");
|
|
}
|
|
else
|
|
{
|
|
msg = "请求用印接口token失败";
|
|
|
|
return (false, msg, null);
|
|
}
|
|
|
|
var path = Path.ChangeExtension(document.AbsolutePath, "pdf");
|
|
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
|
|
|
var fileBytes = new byte[fs.Length];
|
|
|
|
fs.Read(fileBytes, 0, fileBytes.Length);
|
|
|
|
//file = Encoding.UTF8.GetString(fileBytes);
|
|
|
|
|
|
|
|
var postData = new Dictionary<string, HttpContent>
|
|
{
|
|
["file"] = new ByteArrayContent(fileBytes)
|
|
{
|
|
Headers =
|
|
{
|
|
ContentDisposition = new ContentDispositionHeaderValue("form-data")
|
|
{
|
|
Name = "file",
|
|
FileName = document.FileName,
|
|
}
|
|
}
|
|
},
|
|
["typeCode"] = new StringContent("MM")
|
|
};
|
|
|
|
//if(!string.IsNullOrWhiteSpace(keyword))
|
|
//{
|
|
|
|
|
|
postData.Add("keywords", new StringContent(keyword));
|
|
//}
|
|
|
|
|
|
//res = _httpClient.PostJson("es/v1/sign", postData, req =>
|
|
//{
|
|
// var content = new MultipartFormDataContent();
|
|
|
|
// var boundary = string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));
|
|
|
|
// content.Headers.Add("ContentType", $"multipart/form-data, boundary={boundary}");
|
|
|
|
// req.Content = content;
|
|
// req.Headers.Add("token", token);
|
|
//});
|
|
|
|
res = await httpClient.PostMultipartFormDataAsync("es/v1/sign", postData, req =>
|
|
{
|
|
req.Headers.Add("token", token);
|
|
});
|
|
|
|
var sealModel = JsonHelper.Deserialize<ZQSealApiResponseModel>(res);
|
|
|
|
var fileBytesStr = "";
|
|
|
|
if (sealModel.success)
|
|
{
|
|
fileBytesStr = sealModel.data.fileByte;
|
|
msg = sealModel.msg;
|
|
}
|
|
else
|
|
{
|
|
msg = sealModel.msg;
|
|
|
|
|
|
return (false, msg, null);
|
|
}
|
|
|
|
return (true, msg, fileBytesStr);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
msg = $"用印失败:{ex.Message}";
|
|
|
|
|
|
return (false, msg, null);
|
|
}
|
|
|
|
}
|
|
|
|
public bool IsQueueExistsCode(string code)
|
|
{
|
|
return ContractQueue.Any(c => c.Document.Code == code);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 记日志
|
|
/// </summary>
|
|
/// <param name="log"></param>
|
|
/// <returns></returns>
|
|
public void SaveTradeAuditLog(int tradeId, string changes, string optType, DateTime optDate)
|
|
{
|
|
|
|
|
|
var tradeAuditLog = new TradeAuditLog
|
|
{
|
|
TradeId = tradeId,
|
|
Changes = changes,
|
|
DataType = "00",
|
|
OptId = 0,
|
|
OptName = "系统用印",
|
|
OptDate = optDate,
|
|
OptType = optType,
|
|
AuditFlag = TradeAuditFlag.operation
|
|
};
|
|
try
|
|
{
|
|
using var db = DbContextFactory.GetYLDbContext();
|
|
|
|
db.TradeAuditLog.Add(tradeAuditLog);
|
|
|
|
db.SaveChanges();
|
|
|
|
|
|
|
|
_logger.Info($"交易编号:{tradeId},trade_audit_log保存成功");
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"交易编号:{tradeId},trade_audit_log保存失败,错误信息:{ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public void UpdateTradeContractDocument(ITradeContractDocument document, int sealResult, string errMsg)
|
|
{
|
|
|
|
try
|
|
{
|
|
using var db = DbContextFactory.GetYLDbContext();
|
|
|
|
var contractDocument = db.trade_contract_document.FirstOrDefault(x => x.Code == document.Code);
|
|
|
|
if (contractDocument != null)
|
|
{
|
|
contractDocument.SealResult = sealResult;
|
|
|
|
if (sealResult == 1)
|
|
{
|
|
contractDocument.SealErrMsg = errMsg;
|
|
_logger.Info($"确认书编号{document.Code}trade_contract_document error message:{errMsg}");
|
|
}else if (sealResult == 0)
|
|
{
|
|
contractDocument.OptDate = DateTime.Now;
|
|
_logger.Info($"确认书编号{document.Code}trade_contract_document用印成功");
|
|
}
|
|
|
|
db.SaveChanges();
|
|
|
|
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
_logger.Info($"确认书编号{document.Code}trade_contract_document保存失败,错误信息:查不到相关数据");
|
|
}
|
|
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"确认书编号{document.Code}trade_contract_document保存失败,错误信息:{ex.Message}");
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|