From 96757d95358aa3b9500d77807976ba9f6fcf8d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Thu, 21 May 2026 17:33:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(shopping):=20=E4=BC=98=E5=8C=96=E6=8A=A5?= =?UTF-8?q?=E4=BB=B7=E5=8D=95=E5=A4=8D=E5=88=B6=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=8D=E5=88=B6=E8=8E=B7=E5=8F=96=E6=9C=BA?= =?UTF-8?q?=E5=9E=8B=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在AdminShoppingController中简化返回成功数据逻辑,移除未使用的汇率处理代码 - 新增CartsForCopyVO数据结构,封装购物车ID与机型信息,用于机型列表展示 - 修改QuotationCopyRequest,调整字段命名为更符合业务语义的cartId,新增区域字段支持多区域报价 - ShoppingController中新增接口getCartsForCopy,支持根据报价单ID获取报价单中机型列表 - 重构copyQuotation方法,基于购物车ID复制报价单,完善多区域、多权限、价格有效性等校验 - 复制逻辑中优化购物车价格及配件组装,确保部件配置正确返回,提升用户体验 - 修复导出PDF时传参格式,保证导出功能稳定调用 --- .../admin/AdminShoppingController.java | 5 +- .../controller/app/ShoppingController.java | 150 ++++++++++++++++-- .../pojo/request/QuotationCopyRequest.java | 10 +- .../quotation/pojo/vo/CartsForCopyVO.java | 19 +++ 4 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/CartsForCopyVO.java diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java index f1e6eb22..59ba48fb 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java @@ -76,10 +76,7 @@ public class AdminShoppingController extends ControllerBase { if (CollectionUtil.isEmpty(datas.getRecords())) { return ApiResult.success(PageData.empty()); } - return ApiResult.success(datas, data -> { - //TODO 设置汇率价格 - return data; - }); + return ApiResult.success(datas); } /** diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java index d16a7836..b77a16d7 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java @@ -22,10 +22,7 @@ import com.nflg.mobilebroken.common.pojo.vo.SimpleUserVO; import com.nflg.mobilebroken.common.util.*; import com.nflg.mobilebroken.quotation.controller.ControllerBase; import com.nflg.mobilebroken.quotation.pojo.request.*; -import com.nflg.mobilebroken.quotation.pojo.vo.QuotationOrderInfoVO; -import com.nflg.mobilebroken.quotation.pojo.vo.ShoppingCartPartGroupVO; -import com.nflg.mobilebroken.quotation.pojo.vo.ShoppingCartPartVO; -import com.nflg.mobilebroken.quotation.pojo.vo.ShoppingCartVO; +import com.nflg.mobilebroken.quotation.pojo.vo.*; import com.nflg.mobilebroken.quotation.service.PdfExportService; import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; @@ -805,24 +802,147 @@ public class ShoppingController extends ControllerBase { // return ApiResult.success(); // } + /** + * 报价单-获取报价单中的机型列表 + */ + @GetMapping("/quotation/getCartsForCopy") + public ApiResult> getCartsForCopy(@RequestParam Long orderId) { + QuotationShoppingOrder order = shoppingOrderService.getById(orderId); + VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单"); + return ApiResult.success(shoppingOrderService.getCarts(orderId) + .stream() + .map(cart -> new CartsForCopyVO(cart.getId(), cart.getModelNo())) + .collect(Collectors.toList()) + ); + } + /** * 报价单-复制报价单 */ @PostMapping("/quotation/copy") - public ApiResult copyQuotation(@Valid @RequestBody QuotationCopyRequest request) { - QuotationShoppingOrder order = shoppingOrderService.getById(request.getId()); - VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单"); - List orderItems = shoppingOrderItemService.lambdaQuery() - .eq(QuotationShoppingOrderItem::getOrderId, request.getId()) - .list(); - VUtils.trueThrowBusinessError(orderItems.size() > 1).throwMessage("多机型报价单不能复制"); - QuotationShoppingCart cart = shoppingCartService.getById(orderItems.get(0).getCartId()); + public ApiResult copyQuotation(@Valid @RequestBody QuotationCopyRequest request) { + String qc = getQuotationCode(); + VUtils.trueThrowBusinessError(StrUtil.isBlank(qc)).throwMessage("请联系管理员为您开放权限"); + QuotationShoppingCart cart = shoppingCartService.getById(request.getCartId()); + VUtils.trueThrowBusinessError(Objects.isNull(cart)).throwMessage("未找到数据"); VUtils.trueThrowBusinessError(priceService.getById(cart.getPriceId()).getPriceStatus() != 1) .throwMessage("报价配置已失效"); + VUtils.trueThrowBusinessError(Objects.isNull(request.getAreaId()) && isMultiRegionQuotationsUser()) + .throwMessage("请选择区域"); + Long categoryId = Objects.isNull(request.getAreaId()) ? getCategoryId() : request.getAreaId(); +// ProductModel model = productModelService.lambdaQuery().eq(ProductModel::getState, 1).eq(ProductModel::getNo, request.getModelNo()).one(); +// VUtils.trueThrowBusinessError(Objects.isNull(model)).throwMessage("未找到该机型"); VUtils.trueThrowBusinessError(AppUserUtil.isAgent() && forbidService.isForbid(cart.getModelId(), 1, request.getTargetId())) .throwMessage("该机型已禁售"); - - return ApiResult.success(); +// ModelPrice1VO modelPrice = priceService.getModelPrice(request.getModelId(), categoryId); +// VUtils.trueThrowBusinessError(Objects.isNull(modelPrice)).throwMessage("该机型尚未设置价格"); + ShoppingCartVO vo = new ShoppingCartVO() + .setModelId(cart.getModelId()) + .setTargetId(request.getTargetId()) + .setCustomerName(request.getCustomerName()) + .setPriceId(cart.getPriceId()) + .setDefaultRatio(cart.getDefaultRatio()) + .setPlanItemId(cart.getPlanItemId()) + .setConfigId(cart.getConfigId()) + .setDiscount(cart.getDiscount()) + .setTotalFee(cart.getStandardFee().add(cart.getOptionalFee())) + .setActualFee(cart.getStandardFee().add(cart.getOptionalFee())); +// //系数 +// Pair pair = getRatio(request.getModelId()); +// BigDecimal standardRatio = pair.getLeft(), optionalRatio = pair.getRight(), discountRatio = BigDecimal.ONE; +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// if (AppUserUtil.isAgent()) { +// //代理商 +// QuotationDiscountDTO discountDTO = discountService.getEffectiveForCustomer(request.getModelId(), request.getTargetId(), categoryId); +// if (Objects.nonNull(discountDTO)) { +// vo.setDiscountId(discountDTO.getDiscountId()); +//// vo.setActualFee(vo.getTotalFee().multiply(discountDTO.getRatio())); +//// vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee())); +//// log.debug("机型【{}】打折后价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount()); +// discountRatio = discountDTO.getRatio(); +// log.debug("机型【{}】折扣为{}", request.getModelNo(), discountRatio); +// } +// } +// if (!request.getShowLowestPrice()) { +// //方案 +// QuotationUserPlanModelItem planModelItem = userPlanModelItemService.getEffectiveForUser(request.getModelId(), AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); +// if (Objects.nonNull(planModelItem)) { +// log.debug("机型【{}】方案为{},系数:{}", request.getModelNo(), planModelItem.getName(), planModelItem.getRatio()); +// standardRatio = NumberUtil.multiply(standardRatio, planModelItem.getRatio()); +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// vo.setPlanItemId(planModelItem.getId()); +// } else { +// QuotationUserPlanDefault userPlanDefault = userPlanDefaultService.getEffectiveForUser(AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); +// if (Objects.nonNull(userPlanDefault)) { +// vo.setDefaultRatio(userPlanDefault.getRatio()); +// log.debug("用户方案默认系数为{}", userPlanDefault.getRatio()); +// standardRatio = NumberUtil.multiply(standardRatio, userPlanDefault.getRatio()); +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// } +// } +// } +// vo.setTotalFee(NumberUtil.multiply(vo.getTotalFee(), standardRatio)); +// vo.setActualFee(NumberUtil.multiply(vo.getTotalFee(), discountRatio)); +// vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee())); +// log.debug("机型【{}】价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount()); + //获取部件配置 +// List parts = modelConfigService.getEffectives(modelPrice.getConfigId(), modelPrice.getPriceId(), categoryId, MultilingualUtil.getLanguage()); + List parts = shoppingCartItemService.getParts(cart.getId(), MultilingualUtil.getLanguage()); + VUtils.trueThrowBusinessError(CollectionUtil.isEmpty(parts)).throwMessage("未获取到部件信息"); + vo.setStandardParts(parts.stream() + .filter(part -> part.getParentId() == 0L && part.getType() == 1) + .map(part -> { + ShoppingCartPartVO vi = convert(part, BigDecimal.ONE); + vi.setChildren( + parts.stream() + .filter(pi -> pi.getParentId().equals(part.getId())) + .map(pi -> convert(pi, BigDecimal.ONE)) + .collect(Collectors.groupingBy(ShoppingCartPartVO::getGroupName)) + .entrySet() + .stream() + .map(kv -> new ShoppingCartPartGroupVO() + .setGroupName(kv.getKey()) + .setItems(kv.getValue() + .stream() + .sorted(Comparator.comparing(ShoppingCartPartVO::getType).reversed()) + .collect(Collectors.toList()) + ) + ) + .sorted(Comparator.comparing(ShoppingCartPartGroupVO::getGroupName)) + .collect(Collectors.toList()) + ); + vi.setHasSelect(true); + return vi; + } + ).collect(Collectors.toList()) + ); + vo.setOptionalParts(parts.stream() + .filter(part -> part.getParentId() == 0L && part.getType() == 0) + .map(part -> { + ShoppingCartPartVO vi = convert(part, BigDecimal.ONE); + vi.setChildren( + parts.stream() + .filter(pi -> pi.getParentId().equals(part.getId())) + .map(pi -> convert(pi, BigDecimal.ONE)) + .collect(Collectors.groupingBy(ShoppingCartPartVO::getGroupName)) + .entrySet() + .stream() + .map(kv -> new ShoppingCartPartGroupVO() + .setGroupName(kv.getKey()) + .setItems(kv.getValue() + .stream() + .sorted(Comparator.comparing(ShoppingCartPartVO::getType).reversed()) + .collect(Collectors.toList()) + ) + ) + .sorted(Comparator.comparing(ShoppingCartPartGroupVO::getGroupName)) + .collect(Collectors.toList()) + ); + return vi; + } + ).collect(Collectors.toList()) + ); + return ApiResult.success(vo); } /** @@ -891,7 +1011,7 @@ public class ShoppingController extends ControllerBase { */ @GetMapping("/export") public void exportPdf(HttpServletResponse response, @RequestParam Long id) throws IOException { - pdfExportService.export(id,response); + pdfExportService.export(id, response); } /** diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java index 95d629aa..63257297 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java @@ -1,5 +1,6 @@ package com.nflg.mobilebroken.quotation.pojo.request; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -9,10 +10,10 @@ import javax.validation.constraints.NotNull; public class QuotationCopyRequest { /** - * 报价ID + * 购物车id */ @NotNull - private Long id; + private Long cartId; /** * 客户名称 @@ -25,4 +26,9 @@ public class QuotationCopyRequest { */ @NotNull private Integer targetId; + + /** + * 区域(国内/国外),字典id + */ + private Long areaId; } diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/CartsForCopyVO.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/CartsForCopyVO.java new file mode 100644 index 00000000..fdcd61e1 --- /dev/null +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/CartsForCopyVO.java @@ -0,0 +1,19 @@ +package com.nflg.mobilebroken.quotation.pojo.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class CartsForCopyVO { + + /** + * 购物车ID + */ + private Long cartId; + + /** + * 机型 + */ + private String modelNo; +}