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 { /// /// 自动用印业务类 /// public class SealTaskHandleService : YLBaseService, ISealTaskHandler { /// /// 用印队列 /// private static readonly Queue ContractQueue = new Queue(); 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 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 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() { 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("用印结束"); } } } /// /// /// /// /// /// /// 1:用印是否成功 /// 2:用印接口返回信息 /// 3:用印文件base64字符串 /// 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 { ["appid"] = new StringContent("zqsy_api_yl"), ["secretkey"] = new StringContent("8PyrLMVxT1=WzTmr") }, null); var tokenModel = JsonHelper.Deserialize(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 { ["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(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); } /// /// 记日志 /// /// /// 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}"); } } } }