367 lines
15 KiB
C#
367 lines
15 KiB
C#
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
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.MyClass.Caches;
|
||
using SqlSugar;
|
||
|
||
namespace Server.Timers
|
||
{
|
||
/// <summary>
|
||
/// 唯品会订单同步
|
||
/// </summary>
|
||
public class WeiPinHuiTimer : MyTimer
|
||
{
|
||
public WeiPinHuiTimer()
|
||
{
|
||
WeipinhuiRequest.OrderNoticeEvent += WeipinhuiRequest_OrderNoticeEvent;
|
||
}
|
||
|
||
private void WeipinhuiRequest_OrderNoticeEvent(Lianmeng lianmeng, DateTime start, DateTime end)
|
||
{
|
||
HandleOrder(lianmeng, new WeipinhuiRequest(lianmeng), start, end);
|
||
}
|
||
|
||
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);
|
||
//HandleOrderLianmeng(lianmeng);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 读取订单
|
||
/// </summary>
|
||
/// <param name="lianmeng"></param>
|
||
private void HandleOrderLianmeng(Lianmeng lianmeng)
|
||
{
|
||
//防止重复读取
|
||
if (IsUpdateing.ContainsKey(lianmeng.Id))
|
||
{
|
||
return;
|
||
}
|
||
//标记防止重复读取
|
||
IsUpdateing.TryAdd(lianmeng.Id, true);
|
||
try
|
||
{
|
||
var req = new WeipinhuiRequest(lianmeng);
|
||
//上次读取时间
|
||
var lastDateTime = GetLastDateTime(lianmeng.Id + "");
|
||
if (lastDateTime == DateTime.MinValue)
|
||
{
|
||
//如果没有时间,读取最近1个月的数据
|
||
lastDateTime = DateTime.Now.AddDays(-30);
|
||
}
|
||
//req.CreatePosition("测试推广位");
|
||
//本次读取时间
|
||
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, WeipinhuiRequest req, DateTime lastDateTime, DateTime datetime)
|
||
{
|
||
lastDateTime = lastDateTime.AddMinutes(-1);
|
||
req.OrderQuery(lastDateTime, datetime, (items) =>
|
||
{
|
||
var db = Db;
|
||
db.UseTran(() =>
|
||
{
|
||
foreach (var item in items)
|
||
{
|
||
var detailListTokens = item["detailList"].Children();
|
||
foreach (var detailListToken in detailListTokens)
|
||
{
|
||
//goodsId 商品ID
|
||
var orderSn = item["orderSn"].Value<string>();
|
||
var goodsId = detailListToken["goodsId"].Value<string>();
|
||
var orderId = orderSn;
|
||
var orderTime = Util.TimespanToDatatime(item["orderTime"].Value<string>());
|
||
//afterSaleInfo
|
||
JToken afterSaleInfoToken = null;
|
||
if (detailListToken["afterSaleInfo"] != null)//退货
|
||
{
|
||
afterSaleInfoToken = detailListToken["afterSaleInfo"].Children().First();
|
||
}
|
||
var lastUpdateTime = item["lastUpdateTime"].Value<long>();
|
||
var tablenames = db.GetTableName<WphOrder>(orderTime);
|
||
var info = db.Queryable<WphOrder>()
|
||
.Where(w => w.OrderId == orderId)
|
||
.SplitTable(t => t.InTableNames(tablenames))
|
||
.First();
|
||
if (info != null)
|
||
{
|
||
if (lastUpdateTime == info.lastUpdateTime)
|
||
{
|
||
continue;
|
||
}
|
||
else if ((int)info.SystemOrderStatus > 3000)
|
||
{
|
||
continue;
|
||
}
|
||
Util.CopyToObj(item, info);
|
||
Util.CopyToObj(detailListToken, info);
|
||
Util.CopyToObj(afterSaleInfoToken, info);
|
||
SetOrderState(db, lianmeng, info.orderSubStatusName, info);
|
||
//修改数据
|
||
db.Updateable(info).SplitTable(t => t.InTableNames(tablenames)).ExecuteCommand();
|
||
}
|
||
else
|
||
{
|
||
info = new WphOrder();
|
||
info.Id = Util.CreateID(orderTime);
|
||
info.OrderId = orderId;
|
||
info.LianmengId = lianmeng.Id;
|
||
Util.CopyToObj(item, info);
|
||
Util.CopyToObj(detailListToken, info);
|
||
Util.CopyToObj(afterSaleInfoToken, info);
|
||
SetOrderState(db,lianmeng, info.orderSubStatusName, info);
|
||
db.Insertable(info).SplitTable().ExecuteCommand();
|
||
}
|
||
}
|
||
}
|
||
}, ex => Db.OnLog("唯品会订单同步", ex));
|
||
return false;
|
||
});
|
||
}
|
||
/// <summary>
|
||
/// 设置订单状态
|
||
/// </summary>
|
||
/// <param name="lianmeng"></param>
|
||
/// <param name="infoOrderSubStatusName"></param>
|
||
/// <param name="info"></param>
|
||
private void SetOrderState(SqlSugarClient db, Lianmeng lianmeng, Wph_OrderSubStatusNameType infoOrderSubStatusName, WphOrder info)
|
||
{
|
||
switch (infoOrderSubStatusName)
|
||
{
|
||
case Wph_OrderSubStatusNameType.已下单:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单创建;
|
||
|
||
break;
|
||
case Wph_OrderSubStatusNameType.已付款:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单付款;
|
||
DocumentaryUser(db,info);
|
||
break;
|
||
case Wph_OrderSubStatusNameType.已签收:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单收货;
|
||
DocumentaryUser(db, info);
|
||
break;
|
||
case Wph_OrderSubStatusNameType.待结算:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单付款;
|
||
DocumentaryUser(db, info);
|
||
break;
|
||
case Wph_OrderSubStatusNameType.已结算:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单结算;
|
||
CreateComplete(db, info);
|
||
break;
|
||
case Wph_OrderSubStatusNameType.已失效:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
//退货处理
|
||
SalesReturn(db, lianmeng, info);
|
||
break;
|
||
case Wph_OrderSubStatusNameType.维权中:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单退款中;
|
||
break;
|
||
case Wph_OrderSubStatusNameType.维权完成:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
break;
|
||
case Wph_OrderSubStatusNameType.手动失效:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
break;
|
||
}
|
||
switch (info.afterSaleType)
|
||
{
|
||
case Wph_SfterSaleType.无:
|
||
break;
|
||
case Wph_SfterSaleType.退货:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
break;
|
||
case Wph_SfterSaleType.换货:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
break;
|
||
}
|
||
switch (info.afterSaleStatus)
|
||
{
|
||
case Wph_AfterSaleStatusType.无:
|
||
break;
|
||
case Wph_AfterSaleStatusType.售后中:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单退款中;
|
||
break;
|
||
case Wph_AfterSaleStatusType.售后完成:
|
||
info.SystemOrderStatus = SystemOrderStatus.订单失效;
|
||
break;
|
||
case Wph_AfterSaleStatusType.售后取消:
|
||
break;
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 跟单用户
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
private void DocumentaryUser(SqlSugarClient db, WphOrder info)
|
||
{
|
||
if (info.UserId > 0)
|
||
{
|
||
return;
|
||
}
|
||
//通过扩展ID,查到了用户
|
||
if (long.TryParse(info.statParam, out var queryId))
|
||
{
|
||
var queryTabName = db.GetTableName<QueryHist>(queryId);
|
||
QueryHist cache = db.Queryable<QueryHist>().SplitTable(tab => tab.InTableNames(queryTabName))
|
||
.Single(f => f.Id == queryId);
|
||
if (cache != null)
|
||
{
|
||
info.UserId = cache.UserId;
|
||
info.QueryCache = cache;
|
||
var user = db.GetUserData(info.UserId);
|
||
user.PayOrderCount++;
|
||
db.Save(user);
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 退货判断处理
|
||
/// </summary>
|
||
/// <param name="lianmeng"></param>
|
||
/// <param name="info"></param>
|
||
private void SalesReturn(SqlSugarClient db, Lianmeng lianmeng, WphOrder info)
|
||
{
|
||
if (info.UserId <= 0)
|
||
{
|
||
return;
|
||
}
|
||
if (info.PayStatus != OrderPayStatus.已支付)
|
||
{
|
||
return;
|
||
}
|
||
db.PayPoint(info, info.QueryCache, info.Id, info.goodsName, true);
|
||
}
|
||
/// <summary>
|
||
/// 生成订单完成信息
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
private void CreateComplete(SqlSugarClient db, WphOrder info)
|
||
{
|
||
if (info.UserId <= 0)
|
||
{
|
||
return;
|
||
}
|
||
if (info.settledTime <= 0)
|
||
{
|
||
return;
|
||
}
|
||
if (info.orderTime <= DateTime.MinValue)
|
||
{
|
||
return;
|
||
}
|
||
if (info.PayStatus == OrderPayStatus.未支付)
|
||
{
|
||
info.PayStatus = OrderPayStatus.支付中;
|
||
var startTime = Util.TimespanToDatatime(info.settledTime + "");
|
||
var endTime = Util.TimespanToDatatime(info.orderTime + "");
|
||
//时间截取
|
||
var timeConsuming = startTime - endTime;
|
||
DateTime thawingTime = DateTime.Now;
|
||
if (timeConsuming.TotalDays < 1)
|
||
{
|
||
var pubConfig = Db.GetPubConfig();
|
||
if (pubConfig != null && pubConfig.ExtendDay > 0)
|
||
{
|
||
thawingTime = startTime.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<WphOrder>(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>
|
||
/// 获取上次时间
|
||
/// </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);
|
||
}
|
||
|
||
}
|
||
}
|