using System; using System.Collections.Generic; using FluentScheduler; using POSV.Entity; using POSV.HttpApi; using POSV.HttpResponse; using POSV.ShoppingCart; using POSV.Utils; using System.Linq; using System.Diagnostics; using System.Threading; using System.Text; namespace POSV.Job { public class SplitPayUploadJob : BaseApi, IJob { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private readonly object _lock = new object(); private bool isRunning = false; public void Execute() { //lock (_lock) //{ //} var sw = new Stopwatch(); if (!Global.Instance.IsLogin) { logger.Debug("未登录忽略本次上传"); return; } if (!Global.Instance.Online) { logger.Debug("脱机状态,忽略本次上传"); return; } if (!Global.Instance.AllowUpload) { logger.Info("正在点单,暂不上传"); return; } if (isRunning) { logger.Info("营业分账数据上传中,请稍候..."); return; } if (!Global.isHaveUpLoadSplitPay) { logger.Debug("没有需要上传的营业分账数据,isHaveUpLoadSplitPay=false"); return; } UploadSplitPay(10); } private List UploadSplitPay(int limit) { this.isRunning = true; var sw = new Stopwatch(); var lists = new List(); var lists2 = new List(); try { sw.Start(); using (var db = Global.Instance.OpenDataBase) { //主单数据 //lists = db.Query("where syncStatus = 0 and uploadErrors < 3000 order by uploadErrors limit @0;", limit).ToList(); //if (lists.Count <= 0) //{ // //var ids = string.Join("','", lists.ConvertAll(x => x.Id).ToArray()); // logger.Info("没有需要上传的营业分账数据,isHaveUpLoadSplitPay=false"); // Global.isHaveUpLoadSplitPay = false; //} //else //{ // //StringBuilder sqlBuld = new StringBuilder(); // //sqlBuld.Append("SELECT ssp.* FROM pos_split_store_pay ssp "); // //sqlBuld.Append("LEFT JOIN pos_order ord ON ssp.busNo=ord.tradeNo "); // //sqlBuld.Append("WHERE ord.ticketId !='' AND ssp.syncStatus = 0 and ssp.uploadErrors < 3000 order by ssp.uploadErrors limit {0}; "); // //string sql = string.Format(sqlBuld.ToString(), limit); // //lists = db.Query(sql).ToList(); // StringBuilder strBil = new StringBuilder(); // strBil.Append("select ord.ticketId as ordTicketId,ord.tableNo,ord.people,ord.workerNo,oi.price as unitPrice,oi.productId as goodid,ssp.* from pos_split_store_pay ssp "); // strBil.Append("left join pos_order_item oi on oi.id=ssp.orderItemId and oi.productId=ssp.productId "); // strBil.Append("left join pos_order ord on ord.id=ssp.orderId "); // strBil.Append("where ord.ticketId !='' and ssp.syncStatus = 0 and ssp.uploadErrors < 3000 order by ssp.uploadErrors limit {0}; "); // string sql = string.Format(strBil.ToString(), limit); // lists2 = db.Fetch(sql); //} StringBuilder strBil = new StringBuilder(); strBil.Append("select ord.ticketId as ordTicketId,ord.tableNo,ord.people,ord.workerNo,oi.price as unitPrice,oi.productId as goodid,ssp.* from pos_split_store_pay ssp "); strBil.Append("left join pos_order_item oi on oi.id=ssp.orderItemId and oi.productId=ssp.productId "); strBil.Append("left join pos_order ord on ord.id=ssp.orderId "); strBil.Append("where ord.ticketId !='' and ssp.syncStatus = 0 and ssp.uploadErrors < 3000 order by ssp.uploadErrors limit {0}; "); string sql = string.Format(strBil.ToString(), limit); lists2 = db.Fetch(sql); if (lists2.Count <= 0) { //var ids = string.Join("','", lists.ConvertAll(x => x.Id).ToArray()); logger.Info("没有需要上传的营业分账数据,isHaveUpLoadSplitPay=false"); Global.isHaveUpLoadSplitPay = false; } } } catch (Exception ex) { logger.Error(ex, "加载未上传营业分账异常"); } finally { if (lists2.Count > 0) { //foreach (var splitPay in lists2) //{ // splitPay.TicketId = splitPay.OrdTicketId; // ProcessSplitPay(splitPay); // Thread.Sleep(10); //} foreach (var splitPay in lists2) { splitPay.TicketId = splitPay.OrdTicketId; } ProcessSplitPayLst(lists2); sw.Stop(); logger.Info("营业分账数据上传<{0}>条数据耗时<{1}>", lists2.Count, sw.ElapsedMilliseconds); } this.isRunning = false; } return lists2; } //组装单条分账数据 private bool ProcessSplitPay(SplitStorePayEntity splitPay) { bool isSuccess = true; try { //using (var db = Global.Instance.OpenDataBase) //{ // var _ticket = db.FirstOrDefault(string.Format("where tradeNo = '{0}'", splitPay.BusNo)); // if (_ticket != null) // { // splitPay.TicketId = _ticket.TicketId; // } //} //if (string.IsNullOrEmpty(splitPay.TicketId)) //{ // isSuccess = false; //} var uploadObject = BuilderUploadObject(splitPay); string jsonString = JsonUtils.Serialize(uploadObject); var uploadResult = this.Uploading(jsonString); if (uploadResult.Item1) { splitPay.SyncStatus = 1; //splitPay.TicketId = uploadResult.Item2.Data.TicketId; splitPay.UploadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //上传失败 isSuccess = true; } else { splitPay.SyncStatus = 0; splitPay.TicketId = string.Empty; //上传失败 isSuccess = false; } splitPay.UploadStatus = uploadResult.Item2.Status; splitPay.UploadMessage = uploadResult.Item2.Message; splitPay.UploadErrCode = uploadResult.Item2.ErrCode; splitPay.UploadErrMessage = uploadResult.Item2.ErrMessage; } catch (Exception ex) { isSuccess = false; logger.Error(ex, "营业分账数据上传任务异常"); Global.Instance.BugReport(ex, "营业分账数据上传任务异常"); } finally { if (!isSuccess) { splitPay.UploadErrors += 1; } lock (Global.Instance.SyncLock) { string sql = @"update pos_split_store_pay set syncStatus = {0}, uploadErrors = {1}, ticketId = '{2}', uploadTime = '{3}', uploadStatus = {4}, uploadMessage = '{5}', uploadErrCode = '{6}', uploadErrMessage = '{7}' where id = '{8}';"; //索引损坏根据id更新 //string sql = @"update pos_order set syncStatus = {0}, uploadErrors = {1}, ticketId = '{2}', uploadTime = '{3}', uploadStatus = {4}, uploadMessage = '{5}', uploadErrCode = '{6}', uploadErrMessage = '{7}' where id like '{8}';"; SqliteUtils.Execute(string.Format(sql, splitPay.SyncStatus, splitPay.UploadErrors, splitPay.TicketId, splitPay.UploadTime, splitPay.UploadStatus, splitPay.UploadMessage, splitPay.UploadErrCode, splitPay.UploadErrMessage, splitPay.Id)); } } return isSuccess; } private bool ProcessSplitPayLst(List list) { bool isSuccess = true; try { var uploadObject = BuilderUploadObject(list); string jsonString = JsonUtils.Serialize(uploadObject); var uploadResult = this.Uploading(jsonString); var uploadIds = new List(); if (uploadResult.Item1) { var result = uploadResult.Item2; var _clientIds = result.Data.ClientIds; if (!string.IsNullOrEmpty(_clientIds)) { _clientIds = _clientIds.Substring(0, _clientIds.Length - 1); var str = _clientIds.Replace(",", "','"); uploadIds = _clientIds.Split(',').ToList(); //var sql = $"update pos_split_store_pay set syncStatus=1, uploadErrors = {0} , uploadTime = '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'," + // $" uploadStatus = {result.Status}, uploadMessage = '{result.Message}', uploadErrCode = '{result.ErrCode}', uploadErrMessage = '{result.ErrMessage}' " + // $"where id in ('{str}');"; //SqliteUtils.Execute(sql); foreach (var item in uploadIds) { var oldData = list.FirstOrDefault(m => m.Id == item); var sql = $"update pos_split_store_pay set ticketId = '{oldData.TicketId}', syncStatus=1, uploadErrors = {0} , uploadTime = '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'," + $" uploadStatus = {result.Status}, uploadMessage = '{result.Message}', uploadErrCode = '{result.ErrCode}', uploadErrMessage = '{result.ErrMessage}' " + $"where id in ('{str}');"; SqliteUtils.Execute(sql); } logger.Info("营业分账LIST数据上传成功,已上传Ids:{0}", _clientIds); } } else { var result = uploadResult.Item2; var diff = list.Where(m => !uploadIds.Exists(t => t == m.Id)).ToList(); if (diff != null) { var diffIdLst = diff.Select(item => item.Id); if (diffIdLst.Count() > 0) { var diffIds = string.Join(",", diffIdLst); var diffIdsStr = diffIds.Replace(",", "','"); var sql = $"update pos_split_store_pay set syncStatus=1, uploadErrors = (uploadErrors+1) , uploadTime = '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}'," + $" uploadStatus = {0}, uploadMessage = '{result.Message}', uploadErrCode = '{result.ErrCode}', uploadErrMessage = '{result.ErrMessage}' " + $"where id in ('{diffIdsStr}');"; SqliteUtils.Execute(sql); logger.Info("营业分账LIST数据上传失败,未上传Ids:{0}", diffIds); } } //上传失败 isSuccess = false; } } catch (Exception ex) { isSuccess = false; logger.Error(ex, "营业分账LIST数据上传任务异常"); Global.Instance.BugReport(ex, "营业分账LIST数据上传任务异常"); } return isSuccess; } private Dictionary BuilderUploadObject(SplitStorePayEntity splitPay) { try { var uploadObject = new Dictionary(); ////上传订单 //splitPay.isUpLoadTicket = true; //uploadObject["Id"] = splitPay.Id; //租户ID uploadObject["tenantId"] = splitPay.TenantId; //前台系统ID uploadObject["clientId"] = splitPay.Id; //设置ID if (string.IsNullOrEmpty(splitPay.ProgramId)) { uploadObject["programId"] = "-1"; } else { uploadObject["programId"] = splitPay.ProgramId; } //门店ID uploadObject["storeId"] = splitPay.StoreId; //分店ID uploadObject["splitStoreId"] = splitPay.SplitStoreId; //门店编号 uploadObject["storeNo"] = splitPay.StoreNo; //付款单号 uploadObject["payNo"] = splitPay.PayNo; //销售单号 uploadObject["busNo"] = splitPay.BusNo; //付款方式编号 uploadObject["payTypeNo"] = splitPay.PayTypeNo; //付款方式 uploadObject["payType"] = splitPay.PayType; //实收金额 uploadObject["paid"] = splitPay.Paid; //找零金额 uploadObject["rchange"] = splitPay.Rchange; //已收金额 uploadObject["money"] = splitPay.Money; //溢出金额 uploadObject["overAmount"] = splitPay.OverAmount; //凭证号 uploadObject["voucherNo"] = splitPay.VoucherNo; //付款时间 uploadObject["payDate"] = splitPay.PayDate; //付款卡号 uploadObject["cardNo"] = splitPay.CardNo; //是否实收 uploadObject["incomeFlag"] = splitPay.IncomeFlag; //第三方扣费类型 uploadObject["otherRateType"] = splitPay.OtherRateType; //第三方扣费值 uploadObject["otherRateValue"] = splitPay.OtherRateValue; //第三方扣费 uploadObject["otherRate"] = splitPay.OtherRate; //支付客户端类型 uploadObject["payClientType"] = splitPay.PayClientType; //支付渠道 uploadObject["payChannel"] = splitPay.PayChannel; //扣率 uploadObject["deductionRate"] = splitPay.DeductionRate; //扣款 uploadObject["chargeBack"] = splitPay.ChargeBack; //备注 uploadObject["memo"] = splitPay.Memo; uploadObject["isInvalid"] = splitPay.IsInvalid; uploadObject["createUser"] = splitPay.CreateUser; uploadObject["createDate"] = splitPay.CreateDate; uploadObject["ticketId"] = splitPay.TicketId; uploadObject["fromBizUserId"] = splitPay.FromBizUserld; uploadObject["refundAmount"] = splitPay.RefundAmount; uploadObject["orderType"] = splitPay.OrderType.ToString(); uploadObject["isRefund"] = splitPay.IsRefund; uploadObject["tableNo"] = splitPay.TableNo; uploadObject["people"] = splitPay.People; uploadObject["workNo"] = splitPay.WorkerNo; uploadObject["unitPrice"] = splitPay.UnitPrice; uploadObject["goodid"] = splitPay.ProductId; uploadObject["number"] = splitPay.Quantity; uploadObject["rnumber"] = splitPay.RefundQuantity; uploadObject["fee"] = splitPay.fee * 100; return uploadObject; } catch (Exception ex) { logger.Error(ex, "组装营业分账上传数据异常:"); return null; } } private List> BuilderUploadObject(List list) { try { //var newUploadObject = new Dictionary(); var newLst = new List>(); foreach (var splitPay in list) { var uploadObject = new Dictionary(); //租户ID uploadObject["tenantId"] = splitPay.TenantId; //前台系统ID uploadObject["clientId"] = splitPay.Id; //设置ID if (string.IsNullOrEmpty(splitPay.ProgramId)) { uploadObject["programId"] = "-1"; } else { uploadObject["programId"] = splitPay.ProgramId; } //门店ID uploadObject["storeId"] = splitPay.StoreId; //分店ID uploadObject["splitStoreId"] = splitPay.SplitStoreId; //门店编号 uploadObject["storeNo"] = splitPay.StoreNo; //付款单号 uploadObject["payNo"] = splitPay.PayNo; //销售单号 uploadObject["busNo"] = splitPay.BusNo; //付款方式编号 uploadObject["payTypeNo"] = splitPay.PayTypeNo; //付款方式 uploadObject["payType"] = splitPay.PayType; //实收金额 uploadObject["paid"] = splitPay.Paid; //找零金额 uploadObject["rchange"] = splitPay.Rchange; //已收金额 uploadObject["money"] = splitPay.Money; //溢出金额 uploadObject["overAmount"] = splitPay.OverAmount; //凭证号 uploadObject["voucherNo"] = splitPay.VoucherNo; //付款时间 uploadObject["payDate"] = splitPay.PayDate; //付款卡号 uploadObject["cardNo"] = splitPay.CardNo; //是否实收 uploadObject["incomeFlag"] = splitPay.IncomeFlag; //第三方扣费类型 uploadObject["otherRateType"] = splitPay.OtherRateType; //第三方扣费值 uploadObject["otherRateValue"] = splitPay.OtherRateValue; //第三方扣费 uploadObject["otherRate"] = splitPay.OtherRate; //支付客户端类型 uploadObject["payClientType"] = splitPay.PayClientType; //支付渠道 uploadObject["payChannel"] = splitPay.PayChannel; //扣率 uploadObject["deductionRate"] = splitPay.DeductionRate; //扣款 uploadObject["chargeBack"] = splitPay.ChargeBack; //备注 uploadObject["memo"] = splitPay.Memo; uploadObject["isInvalid"] = splitPay.IsInvalid; uploadObject["createUser"] = splitPay.CreateUser; uploadObject["createDate"] = splitPay.CreateDate; uploadObject["ticketId"] = splitPay.TicketId; uploadObject["fromBizUserId"] = splitPay.FromBizUserld; uploadObject["refundAmount"] = splitPay.RefundAmount; uploadObject["orderType"] = splitPay.OrderType.ToString(); uploadObject["isRefund"] = splitPay.IsRefund; uploadObject["tableNo"] = splitPay.TableNo; uploadObject["people"] = splitPay.People; uploadObject["workNo"] = splitPay.WorkerNo; uploadObject["unitPrice"] = splitPay.UnitPrice; uploadObject["goodid"] = splitPay.ProductId; uploadObject["number"] = splitPay.Quantity; uploadObject["rnumber"] = splitPay.RefundQuantity; uploadObject["fee"] = splitPay.fee * 100; newLst.Add(uploadObject); } //newUploadObject["list"] = newLst; return newLst; } catch (Exception ex) { logger.Error(ex, "组装营业分账LIST上传数据异常:"); return null; } } private Tuple> Uploading(string jsonString) { Tuple> result = null; var isTest = false; #region 模拟上传操作 if (isTest) { logger.Debug("开始构建上传成功模拟数据......"); //构建上传成功模拟数据 var resp2 = new EntityResponse(); resp2.Status = 1; resp2.Message = "模拟上传"; resp2.ErrCode = string.Empty; resp2.ErrMessage = string.Empty; resp2.Data = new UploadResult { TicketId = "11112211", UploadDate = DateTime.Now }; logger.Info("模拟上传返回结果:{0}", resp2); result = new Tuple>(false, resp2); return result; } #endregion try { logger.Debug("开始上传营业分账数据......"); OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business); SortedList parameters = OpenApiUtils.Instance.NewParameters(api); parameters.Add("method", "upload.business.splitorder"); parameters.Add("storeId", Global.Instance.Authc.StoreId); parameters.Add("jsonString", jsonString); var ignore = new List(); ignore.Add("jsonString"); parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters, ignore)); string response = HttpClientUtils.PostAsync(api, api.Url, parameters); logger.Info("上传返回结果:{0}", response); if (Constant.IsSuccessful(response)) { var status = JsonUtils.Deserialize>(response); if (status.Status == 1) { logger.Info(status.Message); result = new Tuple>(true, status); } else if (status.Status == 2) { logger.Info(status.Message); result = new Tuple>(false, status); } else { string message = string.Format("<{0}>-{1}-{2}", status.ErrCode, status.ErrMessage, status.Message); logger.Error(string.Format("调用接口上传出错:{0}", message)); result = new Tuple>(false, status); } } else { string errorMessage = PaserErrors(response); logger.Error(string.Format("报文<{0}>解析出错:{1}", response, errorMessage)); //构建错误信息 var resp = new EntityResponse(); resp.Status = 0; resp.Message = errorMessage; resp.ErrCode = string.Empty; resp.ErrMessage = string.Empty; resp.Data = null; result = new Tuple>(false, resp); } } catch (Exception ex) { string message = string.Format("上传营业分账数据发生异常"); logger.Error(ex, message); //构建异常错误 var resp = new EntityResponse(); resp.Status = 0; resp.Message = message; resp.ErrCode = string.Empty; resp.ErrMessage = string.Empty; resp.Data = null; result = new Tuple>(false, resp); } return result; } } }