diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..13ee2b0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "nuxt.isNuxtApp": false +} \ No newline at end of file diff --git a/ARW.Model/Dto/Api/GoodsManager/Goodss/GoodsFreightDto.cs b/ARW.Model/Dto/Api/GoodsManager/Goodss/GoodsFreightDto.cs new file mode 100644 index 0000000..ff57f30 --- /dev/null +++ b/ARW.Model/Dto/Api/GoodsManager/Goodss/GoodsFreightDto.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using ARW.Model.Models.Business.GoodsManager.Goodss; + +namespace ARW.Model.Dto.Api.GoodsManager.Goodss +{ + + /// + /// 商品查询对象Api + /// + /// @author lwh + /// @date 2023-07-09 + /// + public class GoodsFreightDto + { + /// + /// 待结算商品 + /// + public List GoodsRequestList { get; set; } + + /// + /// 地址guid + /// + public long CustomerAddressGuid { get; set; } + + } + + public class GoodsRequest + { + /// + /// 商品Id + /// + public long SpuId { get; set; } + + + /// + /// 商品SkuId + /// + public int SkuId { get; set; } + + + /// + /// 购买数量 + /// + public int Quantity { get; set; } + + } + +} diff --git a/ARW.Model/Dto/Api/Pay/AddPayOrderDtoApi.cs b/ARW.Model/Dto/Api/Pay/AddPayOrderDtoApi.cs index 5897a9c..ad3d73b 100644 --- a/ARW.Model/Dto/Api/Pay/AddPayOrderDtoApi.cs +++ b/ARW.Model/Dto/Api/Pay/AddPayOrderDtoApi.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using ARW.Model.Models.Business.Carts; -namespace ARW.Model.Dto.Api.Carts +namespace ARW.Model.Dto.Api.Pay { /// diff --git a/ARW.Model/Dto/Api/Pay/CommitPayDtoApi.cs b/ARW.Model/Dto/Api/Pay/CommitPayDtoApi.cs index d1318d4..f94b8e7 100644 --- a/ARW.Model/Dto/Api/Pay/CommitPayDtoApi.cs +++ b/ARW.Model/Dto/Api/Pay/CommitPayDtoApi.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using ARW.Model.Models.Business.Carts; -namespace ARW.Model.Dto.Api.Carts +namespace ARW.Model.Dto.Api.Pay { /// @@ -29,18 +29,6 @@ namespace ARW.Model.Dto.Api.Carts /// public string OpenId { get; set; } - - /// - /// 核销前价格 - /// - public decimal BeforeMoney { get; set; } - - - /// - /// 核销后价格/操作金额 - /// - public decimal Money { get; set; } - /// /// 留言 /// @@ -51,5 +39,10 @@ namespace ARW.Model.Dto.Api.Carts /// public int CouponId { get; set;} + /// + /// 待结算购物车商品 + /// + public List GoodsRequestList { get; set; } + } } diff --git a/ARW.Model/Dto/Api/Pay/GoodsRequest.cs b/ARW.Model/Dto/Api/Pay/GoodsRequest.cs index 3f4a5b4..cfe0231 100644 --- a/ARW.Model/Dto/Api/Pay/GoodsRequest.cs +++ b/ARW.Model/Dto/Api/Pay/GoodsRequest.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using ARW.Model.Models.Business.Carts; -namespace ARW.Model.Dto.Api.Carts +namespace ARW.Model.Dto.Api.Pay { /// @@ -19,28 +19,5 @@ namespace ARW.Model.Dto.Api.Carts /// public int CartId { get; set; } - /// - /// 购物车加入时间 - /// - public DateTime JoinCartTime { get; set; } - - /// - /// 小程序用户OpenId - /// - public string openId { get; set; } - - - /// - /// 待结算的商品集合 - /// - public string goodsRequestList { get; set; } - - - /// - /// 发票信息 - /// - public string invoiceRequest { get; set; } - - } } diff --git a/ARW.Service/Api/BusinessService/GoodsManager/Goodss/GoodsServiceApi.cs b/ARW.Service/Api/BusinessService/GoodsManager/Goodss/GoodsServiceApi.cs index 8d493cc..476ada8 100644 --- a/ARW.Service/Api/BusinessService/GoodsManager/Goodss/GoodsServiceApi.cs +++ b/ARW.Service/Api/BusinessService/GoodsManager/Goodss/GoodsServiceApi.cs @@ -22,6 +22,13 @@ using ARW.Model.Models.Business.GoodsManager.GoodsCategorys; using ARW.Repository.Business.GoodsManager.GoodsCategorys; using System; using ARW.Common; +using Microsoft.AspNetCore.Components.Forms; +using ARW.Repository.Business.LogisticsManage.Deliverys; +using ARW.Repository.Business.Custom.CustomerAddresses; +using ARW.Repository.Business.LogisticsManage.DeliveryRules; +using Infrastructure; +using ARW.Model.Models.Business.LogisticsManage.DeliveryRules; +using ARW.Model.Vo.Business.GoodsManager.Goodss; namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss { @@ -40,9 +47,12 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss private readonly SpecValueRepository _SpecValueRepository; private readonly GoodsSkuRepository _GoodsSkuRepository; private readonly GoodsCategoryRepository _GoodsCategoryRepository; + private readonly DeliveryRepository _DeliveryRepository; + private readonly DeliveryRuleRepository _DeliveryRuleRepository; + private readonly CustomerAddressRepository _CustomerAddressRepository; - public GoodsServiceImplApi(GoodsRepository GoodsRepository, GoodsSpecRelRepository goodsSpecRelRepository, SpecRepository specRepository, SpecValueRepository specValueRepository, GoodsSkuRepository goodsSkuRepository, GoodsCategoryRepository goodsCategoryRepository) + public GoodsServiceImplApi(GoodsRepository GoodsRepository, GoodsSpecRelRepository goodsSpecRelRepository, SpecRepository specRepository, SpecValueRepository specValueRepository, GoodsSkuRepository goodsSkuRepository, GoodsCategoryRepository goodsCategoryRepository, DeliveryRepository deliveryRepository, CustomerAddressRepository customerAddressRepository, DeliveryRuleRepository deliveryRuleRepository) { this._GoodsRepository = GoodsRepository; _GoodsSpecRelRepository = goodsSpecRelRepository; @@ -50,6 +60,9 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss _SpecValueRepository = specValueRepository; _GoodsSkuRepository = goodsSkuRepository; _GoodsCategoryRepository = goodsCategoryRepository; + _DeliveryRepository = deliveryRepository; + _CustomerAddressRepository = customerAddressRepository; + _DeliveryRuleRepository = deliveryRuleRepository; } #region Api接口代码 @@ -87,18 +100,18 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss predicate = predicate.AndIF(parm.MaxPrice != 0, s => s.GoodsPriceLowest <= parm.MaxPrice); var sortType = OrderByType.Asc; - if(parm.GoodsSortType == 1) sortType = OrderByType.Desc; + if (parm.GoodsSortType == 1) sortType = OrderByType.Desc; var query = _GoodsRepository .Queryable() .LeftJoin((s, c) => s.ShopGuid == c.ShopGuid) .Where(predicate.ToExpression()) - .WhereIF(parm.GoodsCategoryGuid != null, (s,c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid) + .WhereIF(parm.GoodsCategoryGuid != null, (s, c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid) //.WhereIF(parm.GoodsCategoryGuid != null, (s, c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid || goodsCategoryArr.Contains(c.ShopBusinessCategoryGuid.ToString())) .Where(s => s.GoodsShelfStatus == 1) - .OrderByIF(parm.GoodsSort == 0 , s => s.GoodsSort, OrderByType.Asc) - .OrderByIF(parm.GoodsSort == 1 , s => s.GoodsPriceLowest, sortType) - .OrderByIF(parm.GoodsSort == 2 , s => s.GoodsSalesInitial + s.GoodsSalesActual, sortType) + .OrderByIF(parm.GoodsSort == 0, s => s.GoodsSort, OrderByType.Asc) + .OrderByIF(parm.GoodsSort == 1, s => s.GoodsPriceLowest, sortType) + .OrderByIF(parm.GoodsSort == 2, s => s.GoodsSalesInitial + s.GoodsSalesActual, sortType) //.OrderBy(s => s.GoodsSort, OrderByType.Desc) .Select((s, c) => new GoodsVoApi { @@ -160,7 +173,7 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss }); - var list = await query.ToListAsync(); + var list = await query.ToListAsync(); foreach (var item in list) { @@ -170,6 +183,65 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss return list; } + + /// + /// 获取商品运费(Api) + /// + /// + /// + public async Task GetGoodsFreight(GoodsFreightDto parm) + { + decimal freight = 0; + foreach (var item in parm.GoodsRequestList) + { + var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == item.SpuId); + var delivery = await _DeliveryRepository.GetFirstAsync(s => s.DeliveryGuid == goods.DeliveryGuid); + var deliveRule = await _DeliveryRuleRepository.GetFirstAsync(s => s.DeliveryGuid == delivery.DeliveryGuid); + var adress = await _CustomerAddressRepository.GetFirstAsync(s => s.CustomerAddressGuid == parm.CustomerAddressGuid); + + // 判断是否在配送范围 + + var regionIdList = Tools.SpitIntArrary(deliveRule.DeliveryRuleRegion).ToList(); + if (regionIdList.Contains(adress.CustomerAddressCityId)) + { + // 判断是否免运费 + if (deliveRule.DeliveryRuleFirstFee == 0) + return freight; + + // 按件计费 + if (delivery.DeliveryBillingMethod == 1) + { + freight += CalculateFreight(item.Quantity, deliveRule); + } + // 按重量计费 + if (delivery.DeliveryBillingMethod == 2) + { + // 是否有sku + if (item.SkuId != 0) + { + var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == item.SkuId); + if (sku == null) return freight; + var skuWeight = sku.GoodsSkuWeight * item.Quantity; + freight += CalculateFreight(skuWeight, deliveRule); + } + else + { + var allWeight = goods.GoodsWeight * item.Quantity; + freight += CalculateFreight(allWeight, deliveRule); + } + } + + } + else + { + throw new CustomException($"{goods.GoodsName} 不在配送范围内"); + } + } + + return Math.Round(freight, 2); ; + } + + /// /// 查询商品详情(Api) /// @@ -182,10 +254,10 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss .Queryable() .LeftJoin((s, c) => s.ShopGuid == c.ShopGuid) .Where(s => s.GoodsGuid == parm.SpuId) - .Select((s,c) => new GoodsApiDetailsVo + .Select((s, c) => new GoodsApiDetailsVo { SpuId = s.GoodsGuid, - ShopGuid = s.ShopGuid, + ShopGuid = s.ShopGuid, ShopLogo = c.ShopLogo, ShopName = c.ShopName, ShopSalesOrderCount = c.ShopSalesOrderCount, @@ -364,6 +436,30 @@ namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss return resList; } + + /// + /// 计算运费 + /// + /// + /// + /// + public decimal CalculateFreight(decimal parm, DeliveryRule deliveRule) + { + decimal freight = 0; + // 是否超过首件/首重 + if (parm >= deliveRule.DeliveryRuleFirst) + { + freight += deliveRule.DeliveryRuleFirstFee; + if (parm > deliveRule.DeliveryRuleFirst) + { + var additionalCount = parm - deliveRule.DeliveryRuleFirst; + var additionalFee = additionalCount / deliveRule.DeliveryRuleAdditional * deliveRule.DeliveryRuleAdditionalFee; + freight += additionalFee; + } + } + return freight; + } + #endregion } diff --git a/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs b/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs index 0623c66..c4995bb 100644 --- a/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs +++ b/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs @@ -16,6 +16,7 @@ using ARW.Model.Dto.Api.Carts; using ARW.Repository.Business.Marketing.CouponManage.Coupons; using Org.BouncyCastle.Crypto.Prng; using Aliyun.Acs.Core.Logging; +using ARW.Model.Dto.Api.Pay; namespace ARW.Service.Api.BusinessService.PaymentManage { @@ -35,9 +36,10 @@ namespace ARW.Service.Api.BusinessService.PaymentManage private readonly PaymentRepository _PaymentRepository; private readonly CouponRepository _CouponRepository; private readonly SenparcHttpClient _httpClient; + private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); - public PayServiceApi(ShopRepository ShopRepository, GoodsCategoryRepository goodsCategoryRepository, CustomerRepository customerRepository, OrderRepository orderRepository, PaymentRepository paymentRepository, CouponRepository couponRepository) + public PayServiceApi(ShopRepository ShopRepository, GoodsCategoryRepository goodsCategoryRepository, CustomerRepository customerRepository, OrderRepository orderRepository, PaymentRepository paymentRepository, CouponRepository couponRepository, SenparcHttpClient httpClient) { this._ShopRepository = ShopRepository; _GoodsCategoryRepository = goodsCategoryRepository; @@ -45,6 +47,7 @@ namespace ARW.Service.Api.BusinessService.PaymentManage _OrderRepository = orderRepository; _PaymentRepository = paymentRepository; _CouponRepository = couponRepository; + _httpClient = httpClient; } #region Api接口代码 @@ -140,11 +143,13 @@ namespace ARW.Service.Api.BusinessService.PaymentManage GoodsTotalAmoun = parm.BeforeMoney, OrderAmount = parm.Money, PayPrice = parm.Money, - OrderRemark = parm.Remark, + OrderRemark = parm?.Remark, PayType = parm.PayType, PayStatus = 1, }; + // 计算总额 + // 优惠券减免价格 if (parm.CouponId != 0) { diff --git a/ARW.Service/Api/IBusinessService/GoodsManager/Goodss/IGoodsServiceApi.cs b/ARW.Service/Api/IBusinessService/GoodsManager/Goodss/IGoodsServiceApi.cs index 30c1f21..5b4ede9 100644 --- a/ARW.Service/Api/IBusinessService/GoodsManager/Goodss/IGoodsServiceApi.cs +++ b/ARW.Service/Api/IBusinessService/GoodsManager/Goodss/IGoodsServiceApi.cs @@ -33,6 +33,15 @@ namespace ARW.Service.Api.IBusinessService.GoodsManager.Goodss /// Task> GetGoodsApi(GoodsQueryDtoApi parm); + + /// + /// 获取商品运费(Api) + /// + /// + /// + Task GetGoodsFreight(GoodsFreightDto parm); + + /// /// 获取商品详情(Api) /// diff --git a/ARW.Service/Api/IBusinessService/PayManage/IPayServiceApi.cs b/ARW.Service/Api/IBusinessService/PayManage/IPayServiceApi.cs index fbf911e..98cc3ca 100644 --- a/ARW.Service/Api/IBusinessService/PayManage/IPayServiceApi.cs +++ b/ARW.Service/Api/IBusinessService/PayManage/IPayServiceApi.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using ARW.Model.Dto.Api.Carts; +using ARW.Model.Dto.Api.Pay; using ARW.Model.Models.Business.Payments; using static Infrastructure.WeChat.TenPay.Pay; diff --git a/ARW.WebApi/Controllers/Api/GoodsManager/Goodss/GoodsApiController.cs b/ARW.WebApi/Controllers/Api/GoodsManager/Goodss/GoodsApiController.cs index 087beb8..4613522 100644 --- a/ARW.WebApi/Controllers/Api/GoodsManager/Goodss/GoodsApiController.cs +++ b/ARW.WebApi/Controllers/Api/GoodsManager/Goodss/GoodsApiController.cs @@ -44,7 +44,7 @@ namespace ARW.WebApi.Controllers.Api.GoodsManager.Goodss /// 获取商品列表(Api) /// /// 查询参数 - /// + /// z [HttpGet("getGoodsList")] public async Task GetGoodsListApi([FromQuery] GoodsQueryDtoApi parm) { @@ -52,6 +52,19 @@ namespace ARW.WebApi.Controllers.Api.GoodsManager.Goodss return SUCCESS(res); } + + /// + /// 获取商品运费(Api) + /// + /// 查询参数 + /// + [HttpPost("getGoodsFreight")] + public async Task GetGoodsFreight([FromBody] GoodsFreightDto parm) + { + var res = await _GoodsServiceApi.GetGoodsFreight(parm); + return SUCCESS(res); + } + /// /// 获取Goods详情(Api) /// diff --git a/ARW.WebApi/Controllers/Api/Wechat/WxPay/WxPayController.cs b/ARW.WebApi/Controllers/Api/Wechat/WxPay/WxPayController.cs index ff2f804..c58e7d5 100644 --- a/ARW.WebApi/Controllers/Api/Wechat/WxPay/WxPayController.cs +++ b/ARW.WebApi/Controllers/Api/Wechat/WxPay/WxPayController.cs @@ -14,6 +14,7 @@ using ARW.Service.Business.IBusinessService.Custom.Customers; using ARW.Service.Api.IBusinessService.PayManage; using ARW.Service.Api.BusinessService.PaymentManage; using ARW.Model.Dto.Api.Carts; +using ARW.Model.Dto.Api.Pay; namespace ARW.WebApi.Controllers.Api.Wechat.WxPay { diff --git a/ARW.WebApi/Dockerfile b/ARW.WebApi/Dockerfile index bc86a60..9943510 100644 --- a/ARW.WebApi/Dockerfile +++ b/ARW.WebApi/Dockerfile @@ -2,7 +2,7 @@ FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app -EXPOSE 80 +EXPOSE 8888 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src @@ -14,6 +14,8 @@ COPY ["ARW.Model/ARW.Model.csproj", "ARW.Model/"] COPY ["ARW.Common/ARW.Common.csproj", "ARW.Common/"] COPY ["ARW.Service/ARW.Service.csproj", "ARW.Service/"] COPY ["ARW.Tasks/ARW.Tasks.csproj", "ARW.Tasks/"] +RUN mkdir /app/bin/Debug/net6.0 +RUN cp ARW.WebApi/bin/Debug/net6.0/ARW.Model.dll /app/bin/Debug/net6.0 RUN dotnet restore "ARW.WebApi/ARW.WebApi.csproj" COPY . . WORKDIR "/src/ARW.WebApi" diff --git a/ARW.WebApi/Dockerfile.original b/ARW.WebApi/Dockerfile.original index cca73b7..e5963fc 100644 --- a/ARW.WebApi/Dockerfile.original +++ b/ARW.WebApi/Dockerfile.original @@ -1,12 +1,9 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 8888 + FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build -WORKDIR /app - WORKDIR /src -COPY . . -RUN dotnet restore -RUN dotnet publish -c Release -o publish - -FROM mcr.microsoft.com/dotnet/aspnet:6.0 -WORKDIR /app -COPY --from=build /src/publish ./ -ENTRYPOINT ["dotnet", "ARW.WebApi.dll"] \ No newline at end of file +COPY ../ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a36534e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 8888 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["ARW.WebApi/ARW.WebApi.csproj", "ARW.WebApi/"] +COPY ["ARW.CodeGenerator/ARW.CodeGenerator.csproj", "ARW.CodeGenerator/"] +COPY ["ARW.Repository/ARW.Repository.csproj", "ARW.Repository/"] +COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"] +COPY ["ARW.Model/ARW.Model.csproj", "ARW.Model/"] +COPY ["ARW.Common/ARW.Common.csproj", "ARW.Common/"] +COPY ["ARW.Service/ARW.Service.csproj", "ARW.Service/"] +COPY ["ARW.Tasks/ARW.Tasks.csproj", "ARW.Tasks/"] +RUN dotnet restore "ARW.WebApi/ARW.WebApi.csproj" +COPY . . +WORKDIR "/src/ARW.WebApi" +RUN dotnet build "ARW.WebApi.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "ARW.WebApi.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +RUN mkdir bin +RUN mkdir ./bin/Debug +RUN mkdir ./bin/Debug/net6.0 +RUN cp ARW.Model.dll ./bin/Debug/net6.0 +ENTRYPOINT ["dotnet", "ARW.WebApi.dll"] \ No newline at end of file