Exemple #1
0
        /// <summary>
        /// 处理
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task Handle(CustomerRelationEvent notification, CancellationToken cancellationToken)
        {
            if (notification.ParentId == notification.ChildrenId)
            {
                return;
            }
            try
            {
                var customerRelations = new List <CustomerRelation>()
                {
                    new CustomerRelation(notification.ParentId, notification.ChildrenId, 1)
                };

                var relations = await _customerRelationRepository.Query().Where(e => e.ChildrenId == notification.ParentId).ToListAsync();

                if (relations.Count > 0)
                {
                    foreach (var item in relations)
                    {
                        customerRelations.Add(new CustomerRelation(item.ParentId, notification.ChildrenId, item.Level + 1));
                    }
                }

                using (var transaction = _customerRelationRepository.BeginTransaction())
                {
                    foreach (var item in customerRelations)
                    {
                        _customerRelationRepository.Insert(item, false);
                    }

                    await _customerRelationRepository.SaveAsync();

                    transaction.Commit();
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
            }
        }
        public async Task <Result> Create([FromBody] AdminGoodsCreateRequest request)
        {
            var goodsMedias = new List <GoodsMedia>();

            if (request.GoodsMediaIds != null && request.GoodsMediaIds.Count > 0)
            {
                foreach (var mediaId in request.GoodsMediaIds)
                {
                    goodsMedias.Add(new GoodsMedia(mediaId));
                }
            }
            var goods = new Goods
            {
                Name             = request.Name,
                Description      = request.Description,
                Price            = request.Price,
                ThumbnailImageId = request.ThumbnailImageId,
                IsPublished      = request.IsPublished,
                HasOptions       = true,
                IsVisible        = false,
                BranchDiscount   = request.BranchDiscount,
                CityDiscount     = request.CityDiscount,
                DisplayOrder     = request.DisplayOrder,
                GoodsMedias      = goodsMedias,
                Createat         = DateTime.Now
            };

            if (request.IsPublished)
            {
                goods.PublishedOn = DateTime.Now;
            }

            List <GoodsOptionValue> goodsOptionValues = new List <GoodsOptionValue>();

            foreach (var option in request.Options.Distinct())
            {
                foreach (var item in option.Values.Distinct())
                {
                    goodsOptionValues.Add(new GoodsOptionValue(option.Id, item.Value, item.DisplayOrder));
                }
            }
            goods.OptionValues = goodsOptionValues;

            List <Goods> childrens  = new List <Goods>();
            var          variations = request.Variations.Distinct();

            foreach (var variation in variations)
            {
                var optionCombinations = new List <GoodsOptionCombination>();
                var coms = variation.OptionCombinations.Distinct();
                foreach (var combination in coms)
                {
                    if (!goods.OptionValues.Any(c => c.OptionId == combination.OptionId))
                    {
                        return(Result.Fail(ResultCodes.RequestParamError, "商品组合中的选项不存在"));
                    }
                    if (!goods.OptionValues.Any(c => c.Value == combination.Value))
                    {
                        return(Result.Fail(ResultCodes.RequestParamError, "商品组合中的选项值不存在"));
                    }
                    if (optionCombinations.Any(c => c.OptionId == combination.OptionId && c.Value == combination.Value))
                    {
                        continue;
                    }

                    optionCombinations.Add(new GoodsOptionCombination(combination.OptionId, combination.DisplayOrder, combination.Value));
                }
                var child = new Goods
                {
                    Name               = goods.Name + variation.NormalizedName,
                    NormalizedName     = variation.NormalizedName,
                    Price              = variation.Price,
                    HasOptions         = false,
                    IsVisible          = true,
                    StockQuantity      = variation.StockQuantity,
                    Createat           = DateTime.Now,
                    OptionCombinations = optionCombinations
                };
                if (request.IsPublished)
                {
                    child.IsPublished = true;
                    child.PublishedOn = DateTime.Now;
                }
                childrens.Add(child);
            }
            goods.Childrens = childrens;

            _goodsRepository.Insert(goods, false);

            using (var transaction = _goodsRepository.BeginTransaction())
            {
                await _goodsRepository.SaveAsync();

                transaction.Commit();
            }

            return(Result.Ok());
        }
        public async Task <Result> Create(AdminOrderCreateRequest request)
        {
            var customer = await _customerRepository.Query()
                           .Include(e => e.Parent)
                           .FirstOrDefaultAsync(e => e.Id == request.CustomerId);

            if (customer == null)
            {
                return(Result.Fail(ResultCodes.IdInvalid));
            }
            if (customer.Role == PartnerRole.Default && request.PartnerRole == PartnerRole.Default)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "请选择合伙人角色"));
            }
            if (customer.Role != PartnerRole.Default && request.Goods.Count == 0)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "请选择商品"));
            }

            var now             = DateTime.Now;
            var isFirstOrder    = false;
            var totalFee        = 0;
            var actuallyAmount  = 0;
            var extendParams    = string.Empty;
            var totalCommission = 0;
            var commissionRatio = 0f;
            var orderItems      = new List <OrderItem>();
            var parentUser      = customer.Parent;

            if (request.PartnerRole != PartnerRole.Default)
            {
                if (customer.Role != PartnerRole.Default)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"用户:{customer.NickName} 为{customer.Role.GetDescription()} 不能重复设置角色"));
                }
                var partner = await _partnerApplyRepository.Query()
                              .Include(e => e.PartnerApplyGoods).ThenInclude(e => e.Goods).ThenInclude(e => e.ThumbnailImage)
                              .Where(e => e.PartnerRole == request.PartnerRole)
                              .FirstOrDefaultAsync();

                if (partner == null)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"角色{request.PartnerRole.GetDescription()}未设置商品"));
                }
                if (partner.PartnerApplyGoods.Count == 0)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, "没有商品"));
                }

                if (parentUser != null)
                {
                    if (parentUser.Role == partner.PartnerRole)
                    {
                        if (partner.ReferralCommissionRatio > 0)
                        {
                            commissionRatio = partner.ReferralCommissionRatio / 100f;
                        }
                    }
                    else
                    {
                        var ratio = await _partnerApplyRepository.Query()
                                    .Where(e => e.PartnerRole == parentUser.Role)
                                    .Select(e => e.RepurchaseCommissionRatio)
                                    .FirstOrDefaultAsync();

                        if (ratio > 0)
                        {
                            commissionRatio = ratio / 100f;
                        }
                    }
                }

                isFirstOrder   = true;
                customer.Role  = request.PartnerRole;
                extendParams   = Enum.GetName(typeof(PartnerRole), request.PartnerRole);
                totalFee       = partner.OriginalPrice == 0 ? partner.TotalAmount : partner.OriginalPrice;
                actuallyAmount = partner.TotalAmount;
                var goodsQuantity = partner.PartnerApplyGoods.Sum(e => e.Quantity);
                var averagePrice  = partner.TotalAmount / goodsQuantity;
                var quantity      = 0;
                foreach (var item in partner.PartnerApplyGoods)
                {
                    quantity += item.Quantity;
                    if (quantity == goodsQuantity)
                    {
                        averagePrice = partner.TotalAmount - ((quantity - 1) * averagePrice);
                    }
                    var commission = (int)(averagePrice * commissionRatio);
                    totalCommission = item.Quantity * commission;
                    for (int i = 0; i < item.Quantity; i++)
                    {
                        var orderItem = new OrderItem
                        {
                            GoodsId           = item.GoodsId,
                            GoodsName         = item.Goods.Name,
                            GoodsPrice        = item.Goods.Price,
                            DiscountAmount    = item.Goods.Price,
                            GoodsMediaUrl     = item.Goods.ThumbnailImage?.Url,
                            Quantity          = 1,
                            Remarks           = string.Empty,
                            Status            = OrderItemStatus.Default,
                            Createat          = now,
                            IsFirstBatchGoods = true
                        };

                        orderItem.SetCommissionHistory(customer.ParentId, commission, (int)(commissionRatio * 100), CommissionStatus.Complete);

                        orderItems.Add(orderItem);
                    }
                }
            }
            else if (request.Goods.Count > 0)
            {
                if (customer.Role == PartnerRole.Default)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"用户:{customer.NickName} 为未设置合伙人角色"));
                }
                if (parentUser != null)
                {
                    var ratio = await _partnerApplyRepository.Query()
                                .Where(e => e.PartnerRole == parentUser.Role)
                                .Select(e => e.RepurchaseCommissionRatio)
                                .FirstOrDefaultAsync();

                    if (ratio > 0)
                    {
                        commissionRatio = ratio / 100f;
                    }
                }
                var goodsIds = request.Goods.Select(e => e.Id).Distinct();
                var goodses  = await _goodsRepository.Query()
                               .Include(e => e.ThumbnailImage)
                               .Where(e => goodsIds.Contains(e.Id))
                               .ToListAsync();

                foreach (var item in goodses)
                {
                    var first = request.Goods.FirstOrDefault(e => e.Id == item.Id);
                    if (first == null)
                    {
                        return(Result.Fail(ResultCodes.RequestParamError, $"产品{item.Name}不存在"));
                    }
                    if (!item.IsPublished)
                    {
                        return(Result.Fail(ResultCodes.RequestParamError, $"产品{item.Name}未发布"));
                    }

                    var discountRate = 100f;
                    if (customer.Role == PartnerRole.CityPartner && item.CityDiscount > 0)
                    {
                        discountRate = item.CityDiscount;
                    }
                    else if (customer.Role == PartnerRole.BranchPartner && item.BranchDiscount > 0)
                    {
                        discountRate = item.BranchDiscount;
                    }

                    var amount     = (int)(item.Price * (discountRate / 100f));
                    var commission = (int)(amount * commissionRatio);
                    totalCommission += first.Quantity * commission;

                    for (int i = 0; i < first.Quantity; i++)
                    {
                        var orderItem = new OrderItem
                        {
                            GoodsId        = item.Id,
                            GoodsName      = item.Name,
                            GoodsPrice     = item.Price,
                            DiscountAmount = amount, //折扣
                            GoodsMediaUrl  = item.ThumbnailImage?.Url,
                            Quantity       = 1,
                            Remarks        = first.Remarks,
                            Status         = OrderItemStatus.Default,
                            Createat       = now,
                        };

                        orderItem.SetCommissionHistory(customer.ParentId, commission, (int)(commissionRatio * 100), CommissionStatus.PendingSettlement);

                        orderItems.Add(orderItem);
                    }
                }
                totalFee       = orderItems.Sum(e => e.Quantity * e.GoodsPrice);
                actuallyAmount = orderItems.Sum(e => e.Quantity * e.DiscountAmount);
            }

            var order = new Orders(GenerateHelper.GenOrderNo())
            {
                CustomerId     = customer.Id,
                OrderStatus    = OrderStatus.PaymentReceived,
                PaymentType    = request.PaymentType,
                PaymentMethod  = request.PaymentMethod,
                PaymentFee     = actuallyAmount,
                PaymentTime    = now,
                Remarks        = request.Remarks,
                Createat       = now,
                TotalFee       = totalFee,
                ActuallyAmount = actuallyAmount,
                ExtendParams   = extendParams,
                IsFirstOrder   = isFirstOrder,
                OrderItems     = orderItems
            };

            _orderRepository.Insert(order, false);

            using (var transaction = _orderRepository.BeginTransaction())
            {
                await _orderRepository.SaveAsync();

                if (parentUser != null && totalCommission > 0)
                {
                    if (isFirstOrder)
                    {
                        await _customerManager.UpdateAssets(parentUser.Id, 0, totalCommission, "下级首单返佣金");
                    }
                    else
                    {
                        await _customerManager.UpdateCommission(parentUser.Id, totalCommission);
                    }
                }

                if (isFirstOrder)
                {
                    await _customerRepository.UpdateAsync(customer);
                }

                transaction.Commit();
            }

            return(Result.Ok());
        }
        public async Task <Result> PayBank([FromBody] WithdrawalPayBankRequest request)
        {
            var userId   = HttpContext.GetUserId();
            var bankCard = await _bankCardRepository.FirstOrDefaultAsync(request.Id);

            // var user = await _customerRepository.Query().Include(e => e.Assets).FirstOrDefaultAsync(e => e.Id == userId);
            var assets = await _assetsRepository.Query().FirstOrDefaultAsync(e => e.CustomerId == userId);

            if (assets == null)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "可提现金额不足"));
            }
            if (assets.AvailableAmount <= 0)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "可提现金额不足"));
            }
            if (assets.AvailableAmount < request.Amount)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "金额不足"));
            }
            if (request.Amount < 100000)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "金额不足1000,不可提现"));
            }

            var reservedAmount = (int)(request.Amount * 0.2);     //保留20%的金额
            var amount         = request.Amount - reservedAmount; //提现金额
            var handlingFee    = (int)(request.Amount * 0.001);   //微信手续费0.1%

            if (handlingFee < 100)
            {
                handlingFee = 100;
            }
            else if (handlingFee > 2500)
            {
                handlingFee = 2500;
            }

            string partnerTradeNo = DateTime.Now.ToString("yyyyMMdd") + GenerateHelper.GenOrderNo();

            var payBankRequest = new PayBankRequest
            {
                PartnerTradeNo = partnerTradeNo,
                Amount         = request.Amount,
                BankCode       = bankCard.BankCode,
                BankNo         = bankCard.BankNo,
                Desc           = "提现",
                TrueName       = bankCard.Name
            };

            var payBankResult = await _paymentService.PayBank(payBankRequest);

            var withdrawalHistory = new WithdrawalHistory
            {
                CustomerId     = bankCard.CustomerId,
                Name           = bankCard.Name,
                BankCode       = bankCard.BankCode,
                BankNo         = bankCard.BankNo,
                Amount         = amount,
                ReservedAmount = reservedAmount - reservedAmount,
                Status         = payBankResult.IsSuccess ? WithdrawalStatus.Success : WithdrawalStatus.Failed,
                Message        = payBankResult.Message,
                PartnerTradeNo = partnerTradeNo,
                Total          = request.Amount,
                HandlingFee    = handlingFee,
                Createat       = DateTime.Now
            };

            _withdrawalHistoryRepository.Insert(withdrawalHistory, false);

            using (var transaction = _withdrawalHistoryRepository.BeginTransaction())
            {
                await _withdrawalHistoryRepository.SaveAsync();

                if (payBankResult.IsSuccess)
                {
                    await _customerManager.UpdateAssets(assets, -request.Amount, reservedAmount - reservedAmount, "提现");
                }
                transaction.Commit();
            }

            return(Result.Ok(payBankResult));
        }
        public async Task <Result> Apply([FromBody] ShipmentApplyRequest request)
        {
            var userId = HttpContext.GetUserId();

            ShippingAddress shippingAddress = null;

            if (request.ShippingAddressId > 0)
            {
                var address = await _customerAddressRepository.Query()
                              .Include(e => e.Province)
                              .Include(e => e.City)
                              .Include(e => e.Area)
                              .FirstOrDefaultAsync(e => e.Id == request.ShippingAddressId);

                if (address == null)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, "送货地址不存在"));
                }

                shippingAddress = new ShippingAddress
                {
                    PostalCode   = address.PostalCode.ToString(),
                    ProvinceName = address.Province.Name,
                    CityName     = address.City.Name,
                    AreaName     = address.Area.Name,
                    DetailInfo   = address.DetailInfo,
                    TelNumber    = address.TelNumber,
                    UserName     = address.UserName,
                    Createat     = DateTime.Now
                };
            }
            else if (request.ShippingAddress != null)
            {
                shippingAddress = new ShippingAddress
                {
                    PostalCode   = request.ShippingAddress.PostalCode,
                    ProvinceName = request.ShippingAddress.ProvinceName,
                    CityName     = request.ShippingAddress.CityName,
                    AreaName     = request.ShippingAddress.CountyName,
                    DetailInfo   = request.ShippingAddress.DetailInfo,
                    TelNumber    = request.ShippingAddress.TelNumber,
                    UserName     = request.ShippingAddress.UserName,
                    Createat     = DateTime.Now
                };
            }

            var orderItemIds = request.Items.Select(e => e.Id).Distinct().ToList();
            var orderItems   = await _orderItemRepository.Query().Where(e => orderItemIds.Contains(e.Id)).ToListAsync();

            // var goodsIds = request.Items.Select(e => e.GoodsId);
            // var goodses = await _goodsRepository.Query().Where(e => goodsIds.Contains(e.Id)).ToListAsync();
            var shipmentOrderItems = new List <ShipmentOrderItem>();

            foreach (var item in request.Items.Distinct())
            {
                var first = orderItems.FirstOrDefault(e => e.Id == item.Id);
                if (first == null)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"订单不存在 {item.Id}"));
                }

                // var goods = goodses.FirstOrDefault(e => e.Id == item.GoodsId);
                // if (goods == null) return Result.Fail(ResultCodes.RequestParamError, "商品不存在");
                // if (goods.ParentId == null) return Result.Fail(ResultCodes.RequestParamError, "选择的商品不是有效的商品");
                // if (goods.StockQuantity <= 0) return Result.Fail(ResultCodes.RequestParamError, $"商品{goods.Name} {goods.NormalizedName} 库存不足");
                // //减库存
                // goods.StockQuantity -= first.Quantity;

                first.GoodsItemId    = item.GoodsId;
                first.NormalizedName = item.NormalizedName;
                // first.ShippingStatus = ShippingStatus.PendingShipment;
                // first.ShippingTime = DateTime.Now;

                shipmentOrderItems.Add(new ShipmentOrderItem(first.Id));
            }

            var shipment = new Shipment
            {
                CustomerId         = userId,
                Quantity           = orderItems.Count,
                ShippingStatus     = ShippingStatus.PendingShipment,
                ShippingTime       = DateTime.Now,
                Createat           = DateTime.Now,
                Remarks            = request.Remarks,
                ShippingAddress    = shippingAddress,
                ShipmentOrderItems = shipmentOrderItems
            };

            _shipmentRepository.Insert(shipment, false);

            using (var transaction = _shipmentRepository.BeginTransaction())
            {
                await _shipmentRepository.SaveAsync();

                // await _goodsRepository.UpdateRangeAsync(goodses);

                transaction.Commit();
            }

            await _orderItemRepository.UpdateRangeAsync(orderItems);

            return(Result.Ok(_mapper.Map <ShipmentResponse>(shipment)));
        }
        public async Task <Result> Create([FromBody] OrderCreateRequest request)
        {
            if (request == null)
            {
                return(Result.Fail(ResultCodes.RequestParamError));
            }
            if (request.Items == null || request.Items.Count <= 0)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "请选择商品"));
            }
            if (request.Items.Any(c => c.Quantity <= 0))
            {
                return(Result.Fail(ResultCodes.RequestParamError, "购买商品数量必须大于0"));
            }

            DateTime?timeNull = null;
            Assets   assets   = null;
            var      user     = await _customerManager.GetUserAndParentAsync();

            var commissionRatio = 0f; //佣金百分比
            var totalCommission = 0;  //总佣金
            var extendParams    = string.Empty;

            if (user.Role != PartnerRole.Default)
            {
                var parentUser = user.Parent;
                if (parentUser != null)
                {
                    var ratio = await _partnerApplyRepository.Query()
                                .Where(e => e.PartnerRole == parentUser.Role)
                                .Select(e => e.RepurchaseCommissionRatio)
                                .FirstOrDefaultAsync();

                    if (ratio > 0)
                    {
                        commissionRatio = ratio / 100f;
                    }
                }
            }

            var goodsIds = request.Items.Select(c => c.Id).Distinct();
            var goods    = await _goodsRepository.Query()
                           .Include(e => e.ThumbnailImage)
                           .Where(e => goodsIds.Contains(e.Id)).ToListAsync();

            if (goods.Count <= 0)
            {
                return(Result.Fail(ResultCodes.RequestParamError, "商品不存在"));
            }

            var orderItems = new List <OrderItem>();

            foreach (var item in goods)
            {
                var first = request.Items.FirstOrDefault(e => e.Id == item.Id);
                if (first == null)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"产品{item.Name}不存在"));
                }
                if (!item.IsPublished)
                {
                    return(Result.Fail(ResultCodes.RequestParamError, $"产品{item.Name}未发布"));
                }

                var discountRate = 100f;
                if (user.Role == PartnerRole.CityPartner && item.CityDiscount > 0)
                {
                    discountRate = item.CityDiscount;
                }
                else if (user.Role == PartnerRole.BranchPartner && item.BranchDiscount > 0)
                {
                    discountRate = item.BranchDiscount;
                }

                var amount     = (int)(item.Price * (discountRate / 100f));
                var commission = (int)(amount * commissionRatio);

                for (int i = 0; i < first.Quantity; i++)
                {
                    totalCommission += commission;

                    //创建订单时不选择商品选项,发货时在选择商品选项
                    var orderItem = new OrderItem
                    {
                        GoodsId        = item.Id,
                        GoodsName      = item.Name,
                        GoodsPrice     = item.Price,
                        DiscountAmount = amount, //折扣
                        GoodsMediaUrl  = item.ThumbnailImage?.Url,
                        Quantity       = 1,
                        Remarks        = first.Remarks,
                        Status         = OrderItemStatus.Default,
                        Createat       = DateTime.Now,
                    };

                    orderItem.SetCommissionHistory(user.ParentId, commission, (int)(commissionRatio * 100), CommissionStatus.Invalidation);

                    orderItems.Add(orderItem);
                }
            }

            var totalFee       = orderItems.Sum(e => e.Quantity * e.GoodsPrice);
            var actuallyAmount = orderItems.Sum(e => e.Quantity * e.DiscountAmount);
            var walletAmount   = 0;    //钱包扣除金额
            var needPay        = true; //需要支付

            if (request.IsUseWallet)
            {
                assets = await _assetsRepository.Query().FirstOrDefaultAsync(e => e.CustomerId == user.Id);

                if (assets.RepurchaseAmount > 0)
                {
                    walletAmount = assets.RepurchaseAmount >= actuallyAmount ? actuallyAmount : assets.RepurchaseAmount;
                    needPay      = (actuallyAmount - walletAmount) > 0;
                    foreach (var item in orderItems)
                    {
                        if (!needPay && item.CommissionHistory != null)
                        {
                            item.CommissionHistory.Status = CommissionStatus.PendingSettlement;
                        }
                    }
                }
            }

            var order = new Orders(GenerateHelper.GenOrderNo())
            {
                CustomerId     = user.Id,
                OrderStatus    = needPay ? OrderStatus.PendingPayment : OrderStatus.PaymentReceived,
                PaymentType    = request.PaymentType,
                PaymentMethod  = !needPay ? PaymentMethods.Wallet : PaymentMethods.Wechat,
                Remarks        = request.Remarks,
                Createat       = DateTime.Now,
                TotalFee       = totalFee,
                ActuallyAmount = actuallyAmount,
                WalletAmount   = walletAmount,
                ExtendParams   = extendParams,
                PaymentTime    = !needPay ? DateTime.Now : timeNull,
                OrderItems     = orderItems,
            };

            _orderRepository.Insert(order, false);

            using (var transaction = _orderRepository.BeginTransaction())
            {
                await _orderRepository.SaveAsync();

                if (user.ParentId.HasValue && !needPay && totalCommission > 0)
                {
                    await _customerManager.UpdateCommission(user.ParentId.Value, totalCommission);
                }

                if (!needPay && walletAmount > 0)
                {
                    await _customerManager.UpdateAssets(assets, 0, -walletAmount, "商品抵扣");
                }

                transaction.Commit();
            }
            if (needPay)
            {
                return(Result.Ok(_mapper.Map <OrderCreateResponse>(order)));
            }
            else
            {
                return(Result.Fail(ResultCodes.BalancePayment));
            }
        }