liaoxujun@qq.com
2024-03-26 f87ea6675b5899d045a243fdd6510f47201e7e11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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 _orderItemServices = container.ServiceProvider.GetService<ICoreCmsOrderItemServices>();
                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 orderItem = await _orderItemServices.QueryListByClauseAsync(p => p.orderId == order.orderId, p => p.id, OrderByType.Asc, true);
                    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 pointDiscounted = Math.Round(pointDiscountedProportion / 100, 4);
 
                    //var ordersPointProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.OrdersPointProportion).ObjectToInt();    //积分使用比例  全局模式下一个订单最多可以使用多少比例的积分
                    decimal point = 0;
                    foreach (var p in aftersalesItems)
                    {
                        var orderProduct = orderItem.Find(x => x.productId == p.productId);
                        if (orderProduct == null)
                        {
                            continue;
                        };
                        var product = products.Find(x => x.id == p.productId);
                        if (product == null)
                        {
                            continue;
                        };
                        //如果是全局模式(根据比例来退还积分)
                        if (pointExchangeModel == 1)
                        {
                            //可能存在就是根本不是全积分抵扣,而是订单实际在不够积分的情况下,抵扣了多少金额。那么统一就根据订单的比例来计算,更加精准,(这里的总金额是实际支付金额,去掉了优惠)
                            //如果订单实际支付金额是0的话,那就是全积分。
                            var practicalProportion = order.orderAmount <= 0 ? 1 : Math.Round(order.pointMoney / order.goodsAmount, 4);
 
                            //未发货的商品库存调整,如果订单未发货或者部分发货,并且用户未收到商品的情况下
                            if (order.shipStatus is (int)GlobalEnumVars.OrderShipStatus.No or (int)GlobalEnumVars.OrderShipStatus.PartialYes &&
                                info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund && p.nums == 0)
                            {
                                point += orderProduct.price * practicalProportion * orderProduct.nums * pointDiscountedProportion;
                            }
                            else
                            {
                                //获取货品金额*积分使用比例*数量*积分折现比例=积分抵扣的金额应该可以兑换的积分。
                                point += orderProduct.price * practicalProportion * p.nums * pointDiscountedProportion;
                            }
 
                        }
                        //如果是单品模式
                        else if (pointExchangeModel == 2)
                        {
                            //未发货的商品库存调整,如果订单未发货或者部分发货,并且用户未收到商品的情况下
                            if (order.shipStatus is (int)GlobalEnumVars.OrderShipStatus.No or (int)GlobalEnumVars.OrderShipStatus.PartialYes &&
                                info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund && p.nums == 0)
                            {
                                point += product.pointsDeduction * orderProduct.nums * pointDiscountedProportion;
                            }
                            else
                            {
                                //单品模式只能是全积分抵扣或者全金额支付。所以直接按照扣掉的金额还原积分即可。
                                point += product.pointsDeduction * p.nums * pointDiscountedProportion;
                            }
                        }
                    }
 
                    //为了计算比例情况下,增加精度,全局模式下用了4位小数。这里四色五入积分差异控制小点。
                    var practicalPoint = Convert.ToInt32(point);
 
                    var newPoint = practicalPoint + userModel.point;
 
                    var pointLog = new CoreCmsUserPointLog
                    {
                        userId = userModel.id,
                        type = (int)GlobalEnumVars.UserPointSourceTypes.PointRefundReturn,
                        num = practicalPoint,
                        balance = newPoint,
                        remarks = "售后单:" + info.aftersalesId + "退还积分",
                        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;
        }
 
 
 
 
    }
}