Files
coreshoppro/CoreCms.Net.RedisMQ/AfterSalesReviewForPointSubscribe.cs

176 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using InitQ.Abstractions;
using InitQ.Attributes;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
namespace CoreCms.Net.RedisMQ
{
/// <summary>
/// 售后审核通过后对积分的返还处理
/// </summary>
public class AfterSalesReviewForPointSubscribe : IRedisSubscribe
{
private readonly IServiceProvider _serviceProvider;
public AfterSalesReviewForPointSubscribe(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <summary>
/// 售后审核通过后对积分的返还处理
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
[Subscribe(RedisMessageQueueKey.AfterSalesReviewForPoint)]
private async Task AfterSalesReviewForPointSubscribeCommand(string msg)
{
try
{
if (string.IsNullOrEmpty(msg))
{
NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "售后审核通过后积分处理", "审核单编号获取失败");
return;
}
//使用服务驱动器取服务防止autofac出现循环注入
using var container = _serviceProvider.CreateScope();
var _aftersalesServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesServices>();
var _orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var _aftersalesItemServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesItemServices>();
var _productsServices = container.ServiceProvider.GetService<ICoreCmsProductsServices>();
var _settingServices = container.ServiceProvider.GetService<ICoreCmsSettingServices>();
var _userServices = container.ServiceProvider.GetService<ICoreCmsUserServices>();
var _userPointLogServices = container.ServiceProvider.GetService<ICoreCmsUserPointLogServices>();
var info = await _aftersalesServices.QueryByClauseAsync(p => p.aftersalesId == msg, true);
if (info != null)
{
var order = await _orderServices.QueryByClauseAsync(p => p.orderId == info.orderId, true);
if (order == null)
{
NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "售后审核通过后积分处理", "订单数据获取失败");
return;
}
if (order.point == 0)
{
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "售后审核通过后积分处理", "未使用积分无需处理");
return;
}
var userModel = await _userServices.QueryByClauseAsync(p => p.id == order.userId, true);
if (userModel == null)
{
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "售后审核通过后积分处理", "用户信息获取失败");
return;
}
//获取售后明细
var aftersalesItems = await _aftersalesItemServices.QueryListByClauseAsync(p => p.aftersalesId == info.aftersalesId, p => p.id, OrderByType.Asc, true);
if (aftersalesItems == null)
{
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "售后审核通过后积分处理", "售后明细获取失败");
return;
}
//获取售后货品信息
var productIds = aftersalesItems.Select(p => p.productId).ToList();
var products = await _productsServices.QueryListByClauseAsync(p => productIds.Contains(p.id), p => p.id, OrderByType.Asc, true);
var allConfigs = await _settingServices.GetConfigDictionaries();
var pointExchangeModel = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointExchangeModel).ObjectToInt(); //积分模式 1全局2单品
var pointDiscountedProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointDiscountedProportion).ObjectToInt(); //积分折现比例 多少积分等于1元钱。
//var ordersPointProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.OrdersPointProportion).ObjectToInt(); //积分使用比例 全局模式下一个订单最多可以使用多少比例的积分
decimal point = 0;
foreach (var p in aftersalesItems)
{
var aftersalesProduct = products.Find(x => x.id == p.productId);
if (aftersalesProduct == null)
{
continue;
};
//如果是全局模式(根据比例来退还积分)
if (pointExchangeModel == 1)
{
//可能存在就是根本不是全积分抵扣,而是订单实际在不够积分的情况下,抵扣了多少金额。那么统一就根据订单的比例来计算,更加精准,(这里的总金额是实际支付金额,去掉了优惠)
//如果订单实际支付金额是0的话那就是全积分。
var practicalProportion = order.orderAmount <= 0 ? 1 : Math.Round(order.pointMoney / order.orderAmount, 4);
//未发货的商品库存调整,如果订单未发货或者部分发货,并且用户未收到商品的情况下
if ((order.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No ||
order.shipStatus == (int)GlobalEnumVars.OrderShipStatus.PartialYes) &&
info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund && p.nums == 0)
{
point += aftersalesProduct.price * practicalProportion * pointDiscountedProportion;
}
else
{
//获取货品金额*积分使用比例*数量*积分折现比例=积分抵扣的金额应该可以兑换的积分。
point += aftersalesProduct.price * practicalProportion * p.nums * pointDiscountedProportion;
}
}
//如果是单品模式
else if (pointExchangeModel == 2)
{
//未发货的商品库存调整,如果订单未发货或者部分发货,并且用户未收到商品的情况下
if ((order.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No ||
order.shipStatus == (int)GlobalEnumVars.OrderShipStatus.PartialYes) &&
info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund && p.nums == 0)
{
point += aftersalesProduct.pointsDeduction * pointDiscountedProportion;
}
else
{
//单品模式只能是全积分抵扣或者全金额支付。所以直接按照扣掉的金额还原积分即可。
point += aftersalesProduct.pointsDeduction * p.nums * pointDiscountedProportion;
}
}
}
//为了计算比例情况下增加精度全局模式下用了4位小数。这里四色五入积分差异控制小点。
var practicalPoint = Convert.ToInt32(point);
var newPoint = practicalPoint + userModel.point;
var pointLog = new CoreCmsUserPointLog();
pointLog.userId = userModel.id;
pointLog.type = (int)GlobalEnumVars.UserPointSourceTypes.PointRefundReturn;
pointLog.num = practicalPoint;
pointLog.balance = newPoint;
pointLog.remarks = "售后单:" + info.aftersalesId + "退还积分";
pointLog.createTime = DateTime.Now;
var id = await _userPointLogServices.InsertAsync(pointLog);
if (id > 0)
{
await _userServices.UpdateAsync(p => new CoreCmsUser() { point = p.point + practicalPoint }, p => p.id == userModel.id);
}
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "售后审核通过后积分处理", msg);
}
else
{
NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "售后审核通过后积分处理", "售后单查询失败");
}
}
catch (Exception ex)
{
NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "售后审核通过后积分处理", msg, ex);
throw;
}
await Task.CompletedTask;
}
}
}