From 1ee5c3102204cc3f5da42722df61d10d0f60e6c0 Mon Sep 17 00:00:00 2001 From: huk Date: Fri, 19 Sep 2025 14:53:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(goods):=20=E4=BC=98=E5=8C=96=E5=95=86?= =?UTF-8?q?=E5=93=81=20SKU=20=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SkuBo 主键字段,用于更新操作 - 优化商品保存逻辑,支持新增和更新 SKU - 新增 SKU 获取接口,按商品 ID 查询 -调整商品查询结果,使用别名区分 SKU 字段 --- .../app/AppProductCategoryController.java | 7 +- .../goods/business/ProductBusinessImpl.java | 67 ++++++++++++++++--- .../com/wzj/soopin/goods/domain/bo/SkuBo.java | 3 + .../wzj/soopin/goods/service/SkuService.java | 4 ++ .../goods/service/impl/SkuServiceImpl.java | 11 ++- .../resources/mapper/goods/ProductMapper.xml | 13 ++-- 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/app/AppProductCategoryController.java b/ruoyi-admin/src/main/java/org/dromara/app/AppProductCategoryController.java index c5b2f0701..c1787025b 100644 --- a/ruoyi-admin/src/main/java/org/dromara/app/AppProductCategoryController.java +++ b/ruoyi-admin/src/main/java/org/dromara/app/AppProductCategoryController.java @@ -6,6 +6,7 @@ import com.wzj.soopin.goods.domain.bo.ProductCategoryBo; import com.wzj.soopin.goods.domain.entity.ProductCategory; import com.wzj.soopin.goods.domain.vo.ProductCategoryVO; import com.wzj.soopin.goods.service.impl.ProductCategoryServiceImpl; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; @@ -16,7 +17,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; -@Tag(name ="商品分类接口列表") +@Tag(name ="商品分类") @RestController @RequestMapping("/app/product/category") @RequiredArgsConstructor @@ -26,13 +27,13 @@ public class AppProductCategoryController { private final ProductCategoryServiceImpl service; private final ProductCategoryConvert convert; - @Tag(name ="查询商品分类列表") + @Operation(summary = "查询商品分类列表") @PostMapping("page") public R> page(@RequestBody ProductCategoryBo query, Page page) { Page productCategoryPage = service.page(page,query.toWrapper()); return R.ok(convert.toVO(productCategoryPage)); } - @Tag(name = "查询列表") + @Operation(summary = "查询列表") @PostMapping("/tree") public R> tree(@RequestBody ProductCategoryBo bo ) { List articleList = service.tree( bo.toWrapper()); diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/business/ProductBusinessImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/business/ProductBusinessImpl.java index 5951871e4..1651e1508 100644 --- a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/business/ProductBusinessImpl.java +++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/business/ProductBusinessImpl.java @@ -1,12 +1,12 @@ package com.wzj.soopin.goods.business; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.wzj.soopin.goods.convert.ProductConvert; import com.wzj.soopin.goods.convert.SkuConvert; import com.wzj.soopin.goods.domain.bo.ProductBo; +import com.wzj.soopin.goods.domain.bo.SkuBo; import com.wzj.soopin.goods.domain.entity.Product; import com.wzj.soopin.goods.domain.entity.Sku; import com.wzj.soopin.goods.domain.vo.ProductVO; @@ -20,6 +20,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; @Service @@ -59,11 +60,34 @@ public class ProductBusinessImpl extends BusinessImpl().eq(Sku::getProductId, product.getId())); - // 2. 保存SKU列表 - if (CollectionUtils.isNotEmpty(bo.getSkuList())) { - List skus = bo.getSkuList().stream() + // 新增则直接保存sku信息 + if (bo.getId() == null) { + List skus = bo.getSkuList().stream().map(skuBO -> { + Sku sku = skuConvert.toPo(skuBO); + sku.setProductId(product.getId()); + sku.setTenantId(TenantHelper.getTenantId()); + return sku; + }).collect(Collectors.toList()); + result = skuService.saveBatch(skus); + } else { + // 更新需按照新sku信息和旧sku信息对比,id一致的数据更新,新sku信息中id缺失的要删除,没有id的要新增 + List skuList = bo.getSkuList(); + List oldSkus = skuService.getByProductId(bo.getId()); + + // 分离需要更新、新增和删除的SKU + List skusToUpdate = skuList.stream() + .filter(skuBo -> skuBo.getId() != null) + .map(skuBO -> { + Sku sku = skuConvert.toPo(skuBO); + sku.setId(skuBO.getId()); + sku.setProductId(product.getId()); + sku.setTenantId(TenantHelper.getTenantId()); + return sku; + }) + .collect(Collectors.toList()); + + List skusToSave = skuList.stream() + .filter(skuBo -> skuBo.getId() == null) .map(skuBO -> { Sku sku = skuConvert.toPo(skuBO); sku.setProductId(product.getId()); @@ -71,9 +95,36 @@ public class ProductBusinessImpl extends BusinessImpl oldSkuIds = oldSkus.stream() + .map(Sku::getId) + .collect(Collectors.toList()); + List currentSkuIds = skuList.stream() + .map(SkuBo::getId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 找出需要删除的SKU ID(在旧列表中但不在当前列表中的) + List skusToDelete = oldSkuIds.stream() + .filter(id -> !currentSkuIds.contains(id)) + .collect(Collectors.toList()); + + // 执行更新操作 + if (CollectionUtils.isNotEmpty(skusToUpdate)) { + result = skuService.updateBatchById(skusToUpdate) && result; + } + + // 执行新增操作 + if (CollectionUtils.isNotEmpty(skusToSave)) { + result = skuService.saveBatch(skusToSave) && result; + } + + // 执行删除操作 + if (CollectionUtils.isNotEmpty(skusToDelete)) { + result = skuService.removeByIds(skusToDelete) && result; + } + } return result; } diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/domain/bo/SkuBo.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/domain/bo/SkuBo.java index beef4de88..1d6a8b610 100644 --- a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/domain/bo/SkuBo.java +++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/domain/bo/SkuBo.java @@ -12,6 +12,9 @@ import java.math.BigDecimal; @Schema(description = "SKU信息 查询 对象") public class SkuBo { + @Schema(description = "主键") + private Long id; + @Schema(description = "PRODUCT_ID 精确匹配") private Long productId; diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/SkuService.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/SkuService.java index ec138dd5a..a4c93d856 100644 --- a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/SkuService.java +++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/SkuService.java @@ -3,7 +3,11 @@ package com.wzj.soopin.goods.service; import com.baomidou.mybatisplus.extension.service.IService; import com.wzj.soopin.goods.domain.entity.Sku; +import java.util.List; + public interface SkuService extends IService { void add(Sku sku); + + List getByProductId(Long productId); } diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/impl/SkuServiceImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/impl/SkuServiceImpl.java index fed888f2a..e077b362e 100644 --- a/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/impl/SkuServiceImpl.java +++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/wzj/soopin/goods/service/impl/SkuServiceImpl.java @@ -2,21 +2,23 @@ package com.wzj.soopin.goods.service.impl; import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wzj.soopin.goods.domain.bo.SkuBo; import com.wzj.soopin.goods.domain.entity.Product; import com.wzj.soopin.goods.domain.entity.Sku; - import com.wzj.soopin.goods.domain.vo.SkuVO; +import com.wzj.soopin.goods.domain.vo.SkuVO; import com.wzj.soopin.goods.mapper.ProductMapper; import com.wzj.soopin.goods.mapper.SkuMapper; import com.wzj.soopin.goods.service.SkuService; import lombok.RequiredArgsConstructor; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.springframework.stereotype.Service; +import java.util.List; + /** * sku信息Service业务层处理 @@ -49,4 +51,9 @@ public class SkuServiceImpl extends ServiceImpl implements SkuSe sku.setTenantId(product.getTenantId()); skuMapper.insert(sku); } + + @Override + public List getByProductId(Long productId) { + return skuMapper.selectList(Wrappers.lambdaQuery(Sku.class).eq(Sku::getProductId, productId)); + } } diff --git a/ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/ProductMapper.xml b/ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/ProductMapper.xml index a50dba3d0..1eb130f0a 100644 --- a/ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/ProductMapper.xml +++ b/ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/ProductMapper.xml @@ -63,8 +63,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" p.*, s.id AS sku_id, s.out_sku_id, - s.price, - s.pic, + s.price as skuPrice, + s.pic as skuPic, s.stock, s.sp_data FROM @@ -89,9 +89,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND p.name LIKE CONCAT('%', #{query.nameLike}, '%') - - - AND p.category_id IN @@ -104,13 +101,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - - - + +