You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

820 lines
32 KiB
C#

9 months ago
using FluentScheduler;
using POSV.Entity;
using POSV.HandOver;
using POSV.HttpApi;
using POSV.HttpResponse;
using POSV.StoreBusiness;
using POSV.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
namespace POSV.Job
{
class HandOverUpLoadJob : BaseApi, IJob
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private bool isRunning = false;
public void Execute()
{
try
{
if (!Global.Instance.IsLogin)
{
logger.Debug("未登录忽略本次上传");
return;
}
if (!Global.Instance.Online)
{
logger.Debug("脱机状态,忽略本次上传");
return;
}
if (!Global.Instance.AllowUpload)
{
logger.Info("正在点单,暂不上传");
return;
}
if (isRunning)
{
logger.Debug("执行中,请稍候...");
return;
}
isRunning = true;
//上传交班单
InstallAndUploadHandover();
//上传熟客信息
InstallAndUploadVisitor(5);
//上传操作日志
InstallAndUploadBusLog(5);
}
catch (Exception ex)
{
logger.Error(ex, "交班单上传任务异常");
}
finally
{
isRunning = false;
}
}
#region 操作日志上传
private void InstallAndUploadBusLog(int limit)
{
var sw = new Stopwatch();
if (!Global.isHaveUpLoadBusLog)
{
//没有上传的数据之间返回
logger.Debug("没有需要上传的操作日志,isHaveUpLoadBusLog=false");
return;
}
List<StoreOperationLogEntity> lists = new List<StoreOperationLogEntity>();
try
{
sw.Start();
using (var db = Global.Instance.OpenDataBase)
{
//主单数据
lists = db.Query<StoreOperationLogEntity>("where uploadStatus = 0 order by uploadErrors limit @0;", limit).ToList();
if (lists.Count <= 0)
{
logger.Debug("没有需要上传的操作日志,isHaveUpLoadBusLog=false");
Global.isHaveUpLoadBusLog = false;
}
}
}
catch (Exception ex)
{
logger.Error(ex, "操作日志上传异常");
Global.Instance.BugReport(ex, "操作日志上传异常");
}
finally
{
if (lists.Count > 0)
{
ProcessBusLog(lists);
sw.Stop();
logger.Info("操作日志上传<{0}>条数据耗时<{1}>", lists.Count, sw.ElapsedMilliseconds);
}
this.isRunning = false;
}
}
private bool ProcessBusLog(List<StoreOperationLogEntity> logList)
{
bool isSuccess = true;
try
{
var uploadObject = BuilderUploadObject(logList);
string jsonString = JsonUtils.Serialize(uploadObject);
var uploadResult = this.Uploading(jsonString);
if (uploadResult.Item1)
{
foreach (StoreOperationLogEntity storeOperationLogEntity in logList)
{
storeOperationLogEntity.UploadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
//上传失败
isSuccess = true;
}
else
{
//上传失败
isSuccess = false;
}
foreach (StoreOperationLogEntity storeOperationLogEntity in logList)
{
storeOperationLogEntity.UploadStatus = uploadResult.Item2.Status;
storeOperationLogEntity.UploadMessage = uploadResult.Item2.Message;
storeOperationLogEntity.UploadErrMessage = uploadResult.Item2.ErrMessage;
}
}
catch (Exception ex)
{
isSuccess = false;
logger.Error(ex, "操作日志上传任务异常");
Global.Instance.BugReport(ex, "操作日志上传任务异常");
}
finally
{
if (!isSuccess)
{
foreach (StoreOperationLogEntity storeOperationLogEntity in logList)
{
storeOperationLogEntity.UploadErrors += 1;
}
}
lock (Global.Instance.SyncLock)
{
foreach (StoreOperationLogEntity storeOperationLogEntity in logList)
{
string sql = @"update pos_store_operation_log set uploadStatus = {0}, uploadMessage = '{1}', uploadErrors = {2}, uploadErrMessage = '{3}', uploadTime = '{4}' where id = '{5}';";
SqliteUtils.Execute(string.Format(sql, storeOperationLogEntity.UploadStatus, storeOperationLogEntity.UploadMessage, storeOperationLogEntity.UploadErrors, storeOperationLogEntity.UploadErrMessage, storeOperationLogEntity.UploadTime, storeOperationLogEntity.Id));
}
}
}
return isSuccess;
}
private List<Dictionary<string, object>> BuilderUploadObject(List<StoreOperationLogEntity> logList)
{
//耗料数据上传
var ticket_info = new List<Dictionary<string, object>>();
if (logList != null)
{
foreach (var log in logList)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = log.Id;
//企业编号
p["tenantId"] = log.TenantId;
//门店ID
p["storeId"] = log.StoreId;
//门店编号
p["storeNo"] = log.StoreNo;
//门店
p["storeName"] = log.StoreName;
//工号
p["workerNo"] = log.WorkerNo;
//班次编号
p["shiftNo"] = log.ShiftNo;
//班次名称
p["shiftName"] = log.ShiftName;
//设备名称
p["deviceName"] = log.DeviceName;
//设备MC
p["deviceMac"] = (!string.IsNullOrEmpty(log.DeviceMac) && log.DeviceMac.Length > 32) ? log.DeviceMac.Substring(0, 24) : log.DeviceMac;
//IP地址
p["deviceIp"] = log.DeviceIp;
//POS编号
p["posNo"] = log.PosNo;
//操作时间
p["operationTime"] = log.OperationTime;
//类型
p["type"] = log.Type;
//类型说明
p["typeTxt"] = log.TypeTxt;
//备注说明
p["memo"] = log.Memo;
ticket_info.Add(p);
}
}
return ticket_info;
}
private Tuple<bool, EntityResponse<UploadResult>> Uploading(string jsonString)
{
Tuple<bool, EntityResponse<UploadResult>> result = null;
try
{
logger.Debug("开始上传数据......");
OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business);
SortedList<string, string> parameters = OpenApiUtils.Instance.NewParameters(api);
parameters.Add("method", "upload.business.log");
parameters.Add("storeId", Global.Instance.Authc.StoreId);
parameters.Add("jsonString", jsonString);
var ignore = new List<string>();
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<EntityResponse<UploadResult>>(response);
if (status.Status == 1)
{
logger.Info(status.Message);
result = new Tuple<bool, EntityResponse<UploadResult>>(true, status);
}
else if (status.Status == 2)
{
logger.Info(status.Message);
result = new Tuple<bool, EntityResponse<UploadResult>>(false, status);
}
else
{
string message = string.Format("<{0}>-{1}-{2}", status.ErrCode, status.ErrMessage, status.Message);
logger.Info(string.Format("上传出错:{0}", message));
result = new Tuple<bool, EntityResponse<UploadResult>>(false, status);
}
}
else
{
string errorMessage = PaserErrors(response);
logger.Info(string.Format("报文解析出错:{0}", errorMessage));
//构建错误信息
var resp = new EntityResponse<UploadResult>();
resp.Status = 0;
resp.Message = errorMessage;
resp.ErrCode = string.Empty;
resp.ErrMessage = string.Empty;
resp.Data = null;
result = new Tuple<bool, EntityResponse<UploadResult>>(false, resp);
}
}
catch (Exception ex)
{
string message = string.Format("上传发生异常");
logger.Error(ex, message);
//构建异常错误
var resp = new EntityResponse<UploadResult>();
resp.Status = 0;
resp.Message = message;
resp.ErrCode = string.Empty;
resp.ErrMessage = string.Empty;
resp.Data = null;
result = new Tuple<bool, EntityResponse<UploadResult>>(false, resp);
}
return result;
}
#endregion
#region 熟客信息
private void InstallAndUploadVisitor(int limit)
{
var sw = new Stopwatch();
List<Visitor> visitorList = new List<Visitor>();
if (!Global.isHaveUpLoadVisitor)
{
//没有上传的数据之间返回
logger.Debug("没有需要上传的熟客数据,isHaveUpLoadVisitor=false");
return;
}
try
{
sw.Start();
List<VisitorAddress> visitorAddressList = new List<VisitorAddress>();
List<VisitorTag> visitorTagList = new List<VisitorTag>();
using (var db = Global.Instance.OpenDataBase)
{
visitorList = db.Fetch<Visitor>("where upload = 0");
if (visitorList.Count > 0)
{
var ids = string.Join("','", visitorList.ConvertAll(x => x.Id).ToArray());
var condition = " where visitorId in ('" + ids + "');";
visitorAddressList = db.Fetch<VisitorAddress>(condition);
visitorTagList = db.Fetch<VisitorTag>(condition);
}
else
{
//没有要上传的数据
logger.Debug("没有需要上传的熟客信息,isHaveUpLoadVisitor=false");
Global.isHaveUpLoadVisitor = false;
return;
}
}
foreach (var vi in visitorList)
{
var addList = visitorAddressList.FindAll(x => x.VisitorId == vi.Id);
var tagList = visitorTagList.FindAll(x => x.VisitorId == vi.Id);
var result = UploadVisitor(vi, addList, tagList);
if (result.Item1)
{
vi.Upload = 1;
lock (Global.Instance.SyncLock)
{
using (var db = Global.Instance.OpenDataBase)
{
using (var trans = db.GetTransaction())
{
db.Save(vi);
trans.Complete();
}
}
}
}
Thread.Sleep(10);
}
}
catch(Exception ex)
{
logger.Error(ex, "熟客信息上传异常");
Global.Instance.BugReport(ex, "熟客信息上传异常");
}
finally
{
sw.Stop();
logger.Info("熟客上传<{0}>条数据耗时<{1}>", visitorList.Count, sw.ElapsedMilliseconds);
}
}
private Tuple<bool, string, EntityResponse<UploadVisitorResult>> UploadVisitor(Visitor visitor, List<VisitorAddress> addressList, List<VisitorTag> tagList)
{
Tuple<bool, string, EntityResponse<UploadVisitorResult>> result = null;
try
{
var visitorObject = new Dictionary<string, object>();
visitorObject["id"] = visitor.Id;
visitorObject["tel"] = visitor.Tel;
visitorObject["name"] = visitor.Name;
visitorObject["spell"] = visitor.Spell;
visitorObject["sex"] = visitor.Sex;
visitorObject["title"] = visitor.Title;
visitorObject["position"] = visitor.Position;
visitorObject["fphone"] = visitor.Phone1;
visitorObject["sphone"] = visitor.Phone2;
visitorObject["description"] = visitor.Description;
visitorObject["createUser"] = visitor.CreateUser;
visitorObject["createDate"] = visitor.CreateDate;
visitorObject["modifyUser"] = visitor.ModifyUser;
visitorObject["modifyDate"] = visitor.ModifyDate;
//地址
List<Dictionary<string, object>> uploadAddList = new List<Dictionary<string, object>>();
foreach(var add in addressList)
{
var visitorAddObject = new Dictionary<string, object>();
visitorAddObject["name"] = add.Name;
visitorAddObject["telephone"] = add.Telephone;
visitorAddObject["areaName"] = add.AreaName;
visitorAddObject["address"] = add.Address;
visitorAddObject["description"] = add.Description;
visitorAddObject["createUser"] = add.CreateUser;
visitorAddObject["createDate"] = add.CreateDate;
visitorAddObject["modifyUser"] = add.ModifyUser;
visitorAddObject["modifyDate"] = add.ModifyDate;
uploadAddList.Add(visitorAddObject);
}
visitorObject["addressList"] = uploadAddList;
//标签
List<Dictionary<string, object>> uploadTagList = new List<Dictionary<string, object>>();
foreach(var tag in tagList)
{
var visitorTagObject = new Dictionary<string, object>();
visitorTagObject["name"] = tag.Name;
visitorTagObject["createUser"] = tag.CreateUser;
visitorTagObject["createDate"] = tag.CreateDate;
visitorTagObject["modifyUser"] = tag.ModifyUser;
visitorTagObject["modifyDate"] = tag.ModifyDate;
uploadTagList.Add(visitorTagObject);
}
visitorObject["tagList"] = uploadTagList;
OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business);
SortedList<string, string> parameters = OpenApiUtils.Instance.NewParameters(api);
parameters.Add("method", "visitor.add");
parameters.Add("storeId", Global.Instance.Authc.StoreId);
parameters.Add("jsonString", JsonUtils.Serialize(visitorObject));
logger.Debug("开始上传熟客数据......");
var ignore = new List<string>();
ignore.Add("jsonString");
parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters, ignore));
string response = HttpClientUtils.PostAsync(api, api.Url, parameters);
if (Constant.IsSuccessful(response))
{
var status = JsonUtils.Deserialize<EntityResponse<UploadVisitorResult>>(response);
if (status.Status == 1)
{
logger.Info(status.Message);
result = new Tuple<bool, string, EntityResponse<UploadVisitorResult>>(true, "上传成功!", status);
}
else
{
string message = string.Format("<{0}>-{1}", status.ErrCode, status.Message);
logger.Info(string.Format("熟客上传出错:{0}", message));
result = new Tuple<bool, string, EntityResponse<UploadVisitorResult>>(false, message, status);
}
}
else
{
string errorMessage = PaserErrors(response);
logger.Info(string.Format("熟客上传报文解析出错:{0}", errorMessage));
//构建错误信息
var resp = new EntityResponse<UploadVisitorResult>();
resp.Status = 0;
resp.Message = errorMessage;
resp.ErrCode = string.Empty;
resp.ErrMessage = string.Empty;
resp.Data = null;
result = new Tuple<bool, string, EntityResponse<UploadVisitorResult>>(false, "上传错误", resp);
}
}
catch (Exception ex)
{
logger.Error(ex, "熟客信息上传异常");
result = new Tuple<bool, string, EntityResponse<UploadVisitorResult>>(false, "上传错误", null);
}
return result;
}
#endregion
#region 交班单
private void InstallAndUploadHandover()
{
bool isSuccess = true;
//上传数据
UploadHandoverObject upload = null;
//交班单信息
HandOverTicket ticket = null;
try
{
if (!Global.isHaveUpLoadShift)
{
//没有上传的数据之间返回
logger.Debug("没有需要上传的交班数据,isHaveUpLoadShift=false");
return;
}
using (var db = Global.Instance.OpenDataBase)
{
upload = db.Query<UploadHandoverObject>().Where(x => x.SyncStatus == 0).OrderBy(x => x.UploadErrors).Limit(1).FirstOrDefault();
if (upload != null)
{
ticket = upload.HandOverTicket;
}
else
{
//没有要上传的数据
logger.Debug("没有需要上传的交班数据,isHaveUpLoadShift=false");
Global.isHaveUpLoadShift = false;
return;
}
}
if (ticket == null)
{
return;
}
var uploadObject = new Dictionary<string, object>();
//前台系统ID
uploadObject["id"] = ticket.Id;
uploadObject["no"] = ticket.No;// 单据编号
uploadObject["storeId"] = ticket.StoreId;// 门店ID
uploadObject["storeNo"] = ticket.StoreNo;// 门店编号
uploadObject["storeName"] = ticket.StoreName;// 门店名称
uploadObject["workId"] = ticket.WorkId;// 员工ID
uploadObject["workNo"] = ticket.WorkNo;// 员工编号
uploadObject["workName"] = ticket.WorkName;// 员工名称
uploadObject["shiftNo"] = ticket.ShiftNo;// 班次
uploadObject["shiftName"] = ticket.ShiftName;// 班次名称
uploadObject["datetimeBegin"] = ticket.DatetimeBegin;// 开始时间
uploadObject["datetimeEnd"] = ticket.DatetimeEnd;// 结束时间
uploadObject["datetimeShift"] = ticket.DatetimeShift;// 交班时间
uploadObject["acceptWorkerNo"] = ticket.AcceptWorkerNo;// 交单工号
uploadObject["posNo"] = ticket.PosNo;// 交单POS
uploadObject["memo"] = ticket.Memo;// 备注
uploadObject["peopleCount"] = ticket.PeopleCount;// 总人数
uploadObject["dealTicketCount"] = ticket.DealTicketCount;// 成交单数
uploadObject["dealAmount"] = ticket.DealAmount;// 成交金额
uploadObject["backTicketCount"] = ticket.BackTicketCount;// 退单次数
uploadObject["backAmount"] = ticket.BackAmount;// 退单金额
uploadObject["ticketCount"] = ticket.TicketCount;// 合计次数
uploadObject["amount"] = ticket.Amount;// 合计金额
uploadObject["discountMoney"] = ticket.DiscountMoney;// 优惠金额
uploadObject["couponDiscountMoney"] = ticket.CouponDiscountMoney;// 电子券优惠金额
uploadObject["otherDiscountMoney"] = ticket.OtherDiscountMoney;// 其他优惠金额
uploadObject["receivable"] = ticket.Receivable;// 应收金额
uploadObject["maling"] = ticket.Maling;// 抹零金额
uploadObject["paid"] = ticket.Paid;// 实收金额
uploadObject["cardCount"] = ticket.CardCount;// 充值笔数
uploadObject["cardRealMoney"] = ticket.CardRealMoney;// 卡充值金额
uploadObject["cardRefundCount"] = ticket.CardRefundCount;// 退卡笔数
uploadObject["cardRefundMoney"] = ticket.CardRefundMoney;// 退卡金额
uploadObject["sumRealMoney"] = ticket.SumRealMoney;// 总收入金额
uploadObject["inmoney"] = ticket.Inmoney;// 非营业收入
uploadObject["outmoney"] = ticket.Outmoney;// 非营业支出
uploadObject["distributionFee"] = ticket.DistributionFee;// 配送费信息
uploadObject["shiftAmount"] = ticket.ShiftAmount;// 班次总收入金额
uploadObject["imprest"] = ticket.Imprest;// 备用金
uploadObject["deviceName"] = ticket.DeviceName;// 设备名称
uploadObject["deviceMac"] = ticket.DeviceMac;// 设备MAC
uploadObject["deviceIp"] = ticket.DeviceIp;// 设备IP
//整单优惠明细
var detail = new List<Dictionary<string, object>>();
var ticktDetail = ticket.Detail;
if (ticktDetail != null)
{
foreach (var promotion in ticktDetail)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = promotion.Id;
// 收银方式编号
p["payModeNo"] = promotion.PayModeNo;
//收银方式名称
p["payModeName"] = promotion.PayModeName;
//数量
p["count"] = promotion.Count;
// 金额
p["money"] = promotion.Money;
// 手工金额
p["handsMoney"] = promotion.HandsMoney;
// 卡务次数
p["cardCount"] = promotion.CardCount;
// 卡务金额
p["cardMoney"] = promotion.CardMoney;
// 总金额
p["sumMoney"] = promotion.SumMoney;
detail.Add(p);
}
}
uploadObject["detail"] = detail;
//杯子盘点明细
var part = new List<Dictionary<string, object>>();
var ticktPart = ticket.Part;
if (ticktPart != null)
{
foreach (var promotion in ticktPart)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = promotion.Id;
//规格名称
p["specName"] = promotion.SpecName;
//初始数量
p["preCount"] = promotion.PreCount;
//系统数量
p["count"] = promotion.Count;
// 手工数量
p["handsCount"] = promotion.HandsCount;
// 差异数量
p["difCount"] = promotion.DifCount;
part.Add(p);
}
}
uploadObject["part"] = part;
//支付方式明细
var pay = new List<Dictionary<string, object>>();
var ticktPay = ticket.Pay;
if (ticktPay != null)
{
foreach (var pays in ticktPay)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = pays.Id;
//支付方式编号
p["payModeNo"] = pays.PayModeNo;
//支付方式名称
p["payModeName"] = pays.PayModeName;
//营业模式
p["busMode"] = pays.BusMode;
// 业务类型
p["busType"] = pays.BusType;
// 笔数
p["count"] = pays.Count;
//金额
p["money"] = pays.Money;
pay.Add(p);
}
}
uploadObject["pay"] = pay;
string jsonString = JsonUtils.Serialize(uploadObject);
this.UploadingHandover(upload, jsonString);
isSuccess = true;
}
catch (Exception ex)
{
isSuccess = false;
logger.Error(ex, "组装上传交班单信息异常");
}
finally
{
//zhhangy 2020-03-02 Add 修复因一行交班数据有问题,造成一直执行一行数据
if (upload != null && ticket != null)
{
if (!isSuccess)
{
upload.SyncStatus = 0;
upload.UploadErrors += 1;
}
else
{
upload.SyncStatus = 1;
upload.UploadErrors = +1;
}
lock (Global.Instance.SyncLock)
{
string sql = @"update pos_upload_handover_json set syncStatus = {0}, uploadErrors = {1} where id = '{2}';";
SqliteUtils.Execute(string.Format(sql, upload.SyncStatus, upload.UploadErrors, upload.Id));
}
}
}
}
private void UploadingHandover(UploadHandoverObject upload, string jsonString)
{
try
{
if (upload == null)
{
logger.Error(">>>>交班数据上传对象为空了...............");
return;
}
logger.Debug("开始上传数据......");
OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business);
SortedList<string, string> parameters = OpenApiUtils.Instance.NewParameters(api);
parameters.Add("method", "upload.business.handover");
parameters.Add("storeId", Global.Instance.Authc.StoreId);
parameters.Add("jsonString", jsonString);
var ignore = new List<string>();
ignore.Add("jsonString");
parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters, ignore));
string response = HttpClientUtils.PostAsync(api, api.Url, parameters);
if (Constant.IsSuccessful(response))
{
var result = JsonUtils.Deserialize<EntityResponse<UploadHandOverResult>>(response);
if (result.Status == 1)
{
logger.Info("上传交班数据:" + result.Message);
upload.SyncStatus = 1;
upload.UploadErrors = upload.UploadErrors + 1;
upload.ModifyDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
upload.ModifyUser = Constant.DEFAULT_SYNC_USER;
upload.Ext1 = result.Data.BusNo;
upload.Ext2 = result.Data.HandoverId;
upload.Ext3 = result.Message;
}
else
{
upload.SyncStatus = 0;
upload.UploadErrors = upload.UploadErrors + 1;
upload.ModifyDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
upload.ModifyUser = Constant.DEFAULT_SYNC_USER;
upload.Ext1 = "";
upload.Ext2 = "";
string message = string.Format("<{0}>-{1}", result.ErrCode, result.ErrMessage);
upload.Ext3 = message;
logger.Info(string.Format("交班数据上传出错:{0}", message));
}
using (var db = Global.Instance.OpenDataBase)
{
using (var trans = db.GetTransaction())
{
db.Update(upload);
trans.Complete();
}
}
}
else
{
string errorMessage = PaserErrors(response);
logger.Info(string.Format("报文解析出错:{0}", errorMessage));
}
}
catch (Exception ex)
{
logger.Error(ex, "上传交班发生异常");
Global.Instance.BugReport(ex, "上传交班发生异常");
}
}
#endregion
}
}