380 lines
16 KiB
C#
380 lines
16 KiB
C#
|
using Common.DbExtends.Extends;
|
|||
|
using Common.Models.Enums;
|
|||
|
using Common.Models.SubTables;
|
|||
|
using Common.Models.UnqTables;
|
|||
|
using Common.Requests.Lianmengs;
|
|||
|
using Common.Utils;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using Server.Events;
|
|||
|
using Server.MyClass.Caches;
|
|||
|
using SqlSugar;
|
|||
|
using System;
|
|||
|
using System.Collections.Concurrent;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Server.Timers
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 京东订单定时读取
|
|||
|
/// </summary>
|
|||
|
public class JDOrderTimer : MyTimer
|
|||
|
{
|
|||
|
public JDOrderTimer()
|
|||
|
{
|
|||
|
JingdongRequest.OrderNoticeEvent += JingdongRequest_OrderNoticeEvent;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
readonly Client Client = Client.SingleClient;
|
|||
|
private SqlSugar.SqlSugarClient Db => Client.Db;
|
|||
|
private readonly ConcurrentDictionary<int, bool> IsUpdateing = new ConcurrentDictionary<int, bool>();
|
|||
|
|
|||
|
protected override void Run(object state, bool timedOut)
|
|||
|
{
|
|||
|
var lianmengs = this.Db.Queryable<Lianmeng>().Where(w => w.LianmengType == Common.Models.Enums.LianmengType.京东联盟 && w.ExpirationTime > DateTime.Now).ToList();
|
|||
|
foreach (var lianmeng in lianmengs)
|
|||
|
{
|
|||
|
//防止重复读取
|
|||
|
if (IsUpdateing.ContainsKey(lianmeng.Id))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
var lastDateTime = GetLastDateTime(lianmeng.Id + "");
|
|||
|
if ((DateTime.Now - lastDateTime).TotalSeconds <= 60)//60秒间隔读取
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
//启动线程读取
|
|||
|
ThreadPool.QueueUserWorkItem((o) =>
|
|||
|
{
|
|||
|
HandleOrderLianmeng(o as Lianmeng);
|
|||
|
}, lianmeng);
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 读取订单
|
|||
|
/// </summary>
|
|||
|
/// <param name="lianmeng"></param>
|
|||
|
private void HandleOrderLianmeng(Lianmeng lianmeng)
|
|||
|
{
|
|||
|
//防止重复读取
|
|||
|
if (IsUpdateing.ContainsKey(lianmeng.Id))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
//标记防止重复读取
|
|||
|
IsUpdateing[lianmeng.Id] = true;
|
|||
|
try
|
|||
|
{
|
|||
|
var req = new JingdongRequest(lianmeng);
|
|||
|
//上次读取时间
|
|||
|
var lastDateTime = GetLastDateTime(lianmeng.Id + "");
|
|||
|
if (lastDateTime == DateTime.MinValue)
|
|||
|
{
|
|||
|
//如果没有时间,读取最近1个月的数据
|
|||
|
lastDateTime = DateTime.Now.AddDays(-30);
|
|||
|
}
|
|||
|
//本次读取时间
|
|||
|
var datetime = DateTime.Now;
|
|||
|
|
|||
|
//处理订单
|
|||
|
HandleOrder(lianmeng, req, lastDateTime, datetime);
|
|||
|
|
|||
|
//记录本次读取时间
|
|||
|
SetLastDateTime(lianmeng.Id + "", datetime);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Db.OnLog("京东订单同步2", ex);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
//删除防止重复读取标记
|
|||
|
IsUpdateing.TryRemove(lianmeng.Id, out _);
|
|||
|
if (lianmeng.ExpirationTime < DateTime.Now)
|
|||
|
{
|
|||
|
Db.Updateable(lianmeng).UpdateColumns(s => new { s.ExpirationTime }).ExecuteCommand();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 京东订单车处理请求
|
|||
|
/// </summary>
|
|||
|
/// <param name="lianmeng"></param>
|
|||
|
/// <param name="req"></param>
|
|||
|
/// <param name="lastDateTime"></param>
|
|||
|
/// <param name="datetime"></param>
|
|||
|
private void HandleOrder(Lianmeng lianmeng, JingdongRequest req, DateTime lastDateTime, DateTime datetime)
|
|||
|
{
|
|||
|
lastDateTime = lastDateTime.AddMinutes(-1);
|
|||
|
req.OrderQuery(lastDateTime, datetime, (items) =>
|
|||
|
{
|
|||
|
var db = this.Db;
|
|||
|
var orderChangeEventArgsList = new List<OrderChangeEventArgs>();
|
|||
|
db.UseTran(() =>
|
|||
|
{
|
|||
|
foreach (var item in items)
|
|||
|
{
|
|||
|
var id = item["id"].Value<string>();
|
|||
|
var orderTime = item["orderTime"].Value<DateTime>();
|
|||
|
var modifyTime = item["modifyTime"].Value<string>();
|
|||
|
var orderStatus = (JDOrderCodeEnum)item["validCode"].Value<int>();
|
|||
|
var tablenames = db.GetTableName<JdOrder>(orderTime);
|
|||
|
var info = db.Queryable<JdOrder>().Where(w => w.UniqueId == id).SplitTable(t => t.InTableNames(tablenames)).First();
|
|||
|
if (info != null)
|
|||
|
{
|
|||
|
if (info.modifyTime == modifyTime)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
else if ((int)info.SystemOrderStatus > 3000)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
//旧的订单状态
|
|||
|
var oldSystemOrderStatus = info.SystemOrderStatus;
|
|||
|
//复制对象
|
|||
|
Util.CopyToObj(item, info);
|
|||
|
//设置订单状态
|
|||
|
SetOrderState(db, lianmeng, orderStatus, info);
|
|||
|
//修改数据
|
|||
|
db.Updateable(info).SplitTable(t => t.InTableNames(tablenames)).ExecuteCommand();
|
|||
|
orderChangeEventArgsList.Add(new OrderChangeEventArgs()
|
|||
|
{
|
|||
|
LianmengType = lianmeng.LianmengType,
|
|||
|
NewStatus = info.SystemOrderStatus,
|
|||
|
OldStatus = oldSystemOrderStatus,
|
|||
|
OrderId = info.Id,
|
|||
|
UserId = info.UserId
|
|||
|
});
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
info = new JdOrder();
|
|||
|
info.LianmengId = lianmeng.Id;
|
|||
|
info.Id = Util.CreateID(orderTime);
|
|||
|
info.UniqueId = id;
|
|||
|
Util.CopyToObj(item, info);
|
|||
|
SetOrderState(db, lianmeng, orderStatus, info);
|
|||
|
db.Insertable(info).SplitTable().ExecuteCommand();
|
|||
|
orderChangeEventArgsList.Add(new OrderChangeEventArgs()
|
|||
|
{
|
|||
|
LianmengType = lianmeng.LianmengType,
|
|||
|
NewStatus = info.SystemOrderStatus,
|
|||
|
OldStatus = SystemOrderStatus.未知,
|
|||
|
OrderId = info.Id,
|
|||
|
UserId = info.UserId
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}, ex =>
|
|||
|
{
|
|||
|
Db.OnLog("京东订单同步", ex);
|
|||
|
throw ex;
|
|||
|
});
|
|||
|
//触发事件
|
|||
|
foreach (var orderArgs in orderChangeEventArgsList)
|
|||
|
{
|
|||
|
Client.Events.OnOrderChange(this, orderArgs);
|
|||
|
}
|
|||
|
return false;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 设置订单状态
|
|||
|
/// </summary>
|
|||
|
/// <param name="lianmeng"></param>
|
|||
|
/// <param name="orderStatus"></param>
|
|||
|
/// <param name="info"></param>
|
|||
|
private void SetOrderState(SqlSugarClient db, Lianmeng lianmeng, JDOrderCodeEnum orderStatus, JdOrder info)
|
|||
|
{
|
|||
|
switch (orderStatus)
|
|||
|
{
|
|||
|
case JDOrderCodeEnum.未知:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.未知;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效拆单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效取消:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效京东帮帮主订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效账号异常:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效赠品类目不返佣:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效校园订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效企业订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效团购订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效乡村推广员下单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效违规订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效来源与备案网址不符:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.待付款:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单创建;
|
|||
|
CreateUserId(db, lianmeng, info);
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.已付款:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单付款;
|
|||
|
CreateUserId(db, lianmeng, info);
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.已完成:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单收货;
|
|||
|
CreateComplete(db, info);
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效佣金比例为0:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效此复购订单对应的首购订单无效:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效云店订单:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效PLUS会员佣金比例为0:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.无效支付有礼:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
|||
|
break;
|
|||
|
case JDOrderCodeEnum.已付定金:
|
|||
|
info.SystemOrderStatus = SystemOrderStatus.订单付款;
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
//判断是否退货
|
|||
|
if (info.frozenSkuNum == 1 && info.actualCosPrice <= 0 && info.actualFee <= 0)
|
|||
|
{
|
|||
|
if (info.PayStatus == OrderPayStatus.已支付)
|
|||
|
{
|
|||
|
db.PayPoint(info, info.QueryCache, info.Id, info.skuName, true);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 生成订单完成信息
|
|||
|
/// </summary>
|
|||
|
/// <param name="info"></param>
|
|||
|
private void CreateComplete(SqlSugarClient db, JdOrder info)
|
|||
|
{
|
|||
|
if (info.UserId <= 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
if (info.PayStatus == OrderPayStatus.未支付)
|
|||
|
{
|
|||
|
info.PayStatus = OrderPayStatus.支付中;
|
|||
|
if (string.IsNullOrWhiteSpace(info.finishTime))
|
|||
|
{
|
|||
|
info.finishTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
|
|||
|
}
|
|||
|
//时间截取
|
|||
|
var TimeConsuming = DateTime.Parse(info.finishTime) - info.orderTime;
|
|||
|
DateTime ThawingTime = DateTime.Now;
|
|||
|
if (TimeConsuming.TotalDays < 1)
|
|||
|
{
|
|||
|
var pubConfig = db.GetPubConfig();
|
|||
|
if (pubConfig != null && pubConfig.ExtendDay > 0)
|
|||
|
{
|
|||
|
ThawingTime = DateTime.Parse(info.finishTime).AddDays(pubConfig.ExtendDay);
|
|||
|
}
|
|||
|
}
|
|||
|
var frozen = new FinishOrder()
|
|||
|
{
|
|||
|
CreateTime = DateTime.Now,
|
|||
|
LianmengType = LianmengType.京东联盟,
|
|||
|
OrderId = info.Id,
|
|||
|
ThawingTime = ThawingTime,
|
|||
|
UserId = info.UserId
|
|||
|
};
|
|||
|
db.Insertable(frozen).ExecuteCommand();
|
|||
|
//发送通知
|
|||
|
var tablenames = db.GetTableName<JdOrder>(info.orderTime);
|
|||
|
if (info.UserId > 0 && info.QueryCache != null)
|
|||
|
{
|
|||
|
bool IsFreeze = (frozen.ThawingTime > DateTime.Now);
|
|||
|
Client.SendClientMsg(info.QueryCache.RobotId, DeviceMessageType.京东订单更新, new { OrderId = info.Id, TableName = tablenames, IsFreeze = IsFreeze });
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 创建用户ID,跟单用户
|
|||
|
/// </summary>
|
|||
|
/// <param name="lianmeng"></param>
|
|||
|
/// <param name="info"></param>
|
|||
|
private void CreateUserId(SqlSugarClient db, Lianmeng lianmeng, JdOrder info)
|
|||
|
{
|
|||
|
if (info.UserId > 0)
|
|||
|
return;
|
|||
|
|
|||
|
string positionId = info.positionId + "";
|
|||
|
var cache = db.GetQueryHist(f => f.ItemId == info.skuId && f.Pid == positionId && f.LianmegnId == lianmeng.Id && f.ItemType == LianmengType.京东联盟);
|
|||
|
if (cache != null)
|
|||
|
{
|
|||
|
info.QueryCache = cache;
|
|||
|
info.UserId = cache.UserId;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//京东商品有多类型,该商品id的最后一位是不一样的直接截取最后一个数
|
|||
|
var skuIdTmp = info.skuId.Substring(0, info.skuId.Length - 1);
|
|||
|
//如果查询出来,只有一条记录
|
|||
|
var cacheTmp = db.GetQueryHist(f => f.ItemId.StartsWith(skuIdTmp) && f.Pid == positionId && f.LianmegnId == lianmeng.Id && f.ItemType == LianmengType.京东联盟);
|
|||
|
if (cacheTmp != null)
|
|||
|
{
|
|||
|
info.QueryCache = cacheTmp;
|
|||
|
info.UserId = cacheTmp.UserId;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 获取上次时间
|
|||
|
/// </summary>
|
|||
|
/// <param name="id"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private DateTime GetLastDateTime(string id)
|
|||
|
{
|
|||
|
return Client.Config.RuntimeCache.GetPublicValue("订单同步" + id, () => DateTime.MinValue);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 记录上次时间
|
|||
|
/// </summary>
|
|||
|
/// <param name="id"></param>
|
|||
|
/// <param name="now"></param>
|
|||
|
private void SetLastDateTime(string id, DateTime now)
|
|||
|
{
|
|||
|
Client.Config.RuntimeCache.SetPublicValue("订单同步" + id, now);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void JingdongRequest_OrderNoticeEvent(Lianmeng lianmeng, DateTime start, DateTime end)
|
|||
|
{
|
|||
|
HandleOrder(lianmeng, new JingdongRequest(lianmeng), start, end);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|