Commit 7a4a6a3046191d4420415c248fb273ddd21852f8
1 parent
92dde0b4
product:优化管理后台相关的接口
area:增加地区列表界面
Showing
31 changed files
with
401 additions
and
339 deletions
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
| 1 | package cn.iocoder.yudao.framework.ip.core.utils; | 1 | package cn.iocoder.yudao.framework.ip.core.utils; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.io.resource.ResourceUtil; | 3 | import cn.hutool.core.io.resource.ResourceUtil; |
| 4 | +import cn.hutool.core.lang.Assert; | ||
| 4 | import cn.hutool.core.text.csv.CsvRow; | 5 | import cn.hutool.core.text.csv.CsvRow; |
| 5 | import cn.hutool.core.text.csv.CsvUtil; | 6 | import cn.hutool.core.text.csv.CsvUtil; |
| 6 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| @@ -50,6 +51,7 @@ public class AreaUtils { | @@ -50,6 +51,7 @@ public class AreaUtils { | ||
| 50 | for (CsvRow row : rows) { | 51 | for (CsvRow row : rows) { |
| 51 | Area area = areas.get(Integer.valueOf(row.get(0))); // 自己 | 52 | Area area = areas.get(Integer.valueOf(row.get(0))); // 自己 |
| 52 | Area parent = areas.get(Integer.valueOf(row.get(3))); // 父 | 53 | Area parent = areas.get(Integer.valueOf(row.get(3))); // 父 |
| 54 | + Assert.isTrue(area != parent, "{}:父子节点相同", area.getName()); | ||
| 53 | area.setParent(parent); | 55 | area.setParent(parent); |
| 54 | parent.getChildren().add(area); | 56 | parent.getChildren().add(area); |
| 55 | } | 57 | } |
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/resources/area.csv
| @@ -2567,8 +2567,6 @@ id,name,type,parentId | @@ -2567,8 +2567,6 @@ id,name,type,parentId | ||
| 2567 | 441826,连南瑶族自治县,4,441800 | 2567 | 441826,连南瑶族自治县,4,441800 |
| 2568 | 441881,英德市,4,441800 | 2568 | 441881,英德市,4,441800 |
| 2569 | 441882,连州市,4,441800 | 2569 | 441882,连州市,4,441800 |
| 2570 | -441900,东莞市,4,441900 | ||
| 2571 | -442000,中山市,4,442000 | ||
| 2572 | 445102,湘桥区,4,445100 | 2570 | 445102,湘桥区,4,445100 |
| 2573 | 445103,潮安区,4,445100 | 2571 | 445103,潮安区,4,445100 |
| 2574 | 445122,饶平县,4,445100 | 2572 | 445122,饶平县,4,445100 |
| @@ -2704,7 +2702,6 @@ id,name,type,parentId | @@ -2704,7 +2702,6 @@ id,name,type,parentId | ||
| 2704 | 460321,西沙群岛,4,460300 | 2702 | 460321,西沙群岛,4,460300 |
| 2705 | 460322,南沙群岛,4,460300 | 2703 | 460322,南沙群岛,4,460300 |
| 2706 | 460323,中沙群岛的岛礁及其海域,4,460300 | 2704 | 460323,中沙群岛的岛礁及其海域,4,460300 |
| 2707 | -460400,儋州市,4,460400 | ||
| 2708 | 469001,五指山市,4,469000 | 2705 | 469001,五指山市,4,469000 |
| 2709 | 469002,琼海市,4,469000 | 2706 | 469002,琼海市,4,469000 |
| 2710 | 469005,文昌市,4,469000 | 2707 | 469005,文昌市,4,469000 |
yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/AssertUtils.java
| @@ -33,6 +33,10 @@ public class AssertUtils { | @@ -33,6 +33,10 @@ public class AssertUtils { | ||
| 33 | public static void assertPojoEquals(Object expected, Object actual, String... ignoreFields) { | 33 | public static void assertPojoEquals(Object expected, Object actual, String... ignoreFields) { |
| 34 | Field[] expectedFields = ReflectUtil.getFields(expected.getClass()); | 34 | Field[] expectedFields = ReflectUtil.getFields(expected.getClass()); |
| 35 | Arrays.stream(expectedFields).forEach(expectedField -> { | 35 | Arrays.stream(expectedFields).forEach(expectedField -> { |
| 36 | + // 忽略 jacoco 自动生成的 $jacocoData 属性的情况 | ||
| 37 | + if (expectedField.isSynthetic()) { | ||
| 38 | + return; | ||
| 39 | + } | ||
| 36 | // 如果是忽略的属性,则不进行比对 | 40 | // 如果是忽略的属性,则不进行比对 |
| 37 | if (ArrayUtil.contains(ignoreFields, expectedField.getName())) { | 41 | if (ArrayUtil.contains(ignoreFields, expectedField.getName())) { |
| 38 | return; | 42 | return; |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.product.controller.admin.property.vo; | ||
| 2 | - | ||
| 3 | -import io.swagger.annotations.ApiModel; | ||
| 4 | -import io.swagger.annotations.ApiModelProperty; | ||
| 5 | -import lombok.Data; | ||
| 6 | -import lombok.ToString; | ||
| 7 | - | ||
| 8 | -import java.util.List; | ||
| 9 | - | ||
| 10 | -// TODO 芋艿:看看怎么删除 | ||
| 11 | -@ApiModel("管理后台 - 商品属性详情展示 Request VO") | ||
| 12 | -@Data | ||
| 13 | -@ToString(callSuper = true) | ||
| 14 | -public class ProductPropertyViewRespVO { | ||
| 15 | - | ||
| 16 | - @ApiModelProperty(value = "属性项 id", example = "1") | ||
| 17 | - public Long propertyId; | ||
| 18 | - | ||
| 19 | - @ApiModelProperty(value = "属性项的名字", example = "内存") | ||
| 20 | - public String name; | ||
| 21 | - | ||
| 22 | - @ApiModelProperty(value = "属性值数组") | ||
| 23 | - public List<Tuple2> propertyValues; | ||
| 24 | - | ||
| 25 | - @Data | ||
| 26 | - @ApiModel(value = "属性值元组") | ||
| 27 | - public static class Tuple2 { | ||
| 28 | - private final long id; | ||
| 29 | - private final String name; | ||
| 30 | - | ||
| 31 | - public Tuple2(Long id, String name) { | ||
| 32 | - this.id = id; | ||
| 33 | - this.name = name; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModel; | ||
| 4 | +import io.swagger.annotations.ApiModelProperty; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +@ApiModel("管理后台 - 商品属性值的明细 Response VO") | ||
| 8 | +@Data | ||
| 9 | +public class ProductPropertyValueDetailRespVO { | ||
| 10 | + | ||
| 11 | + @ApiModelProperty(value = "属性的编号", required = true, example = "1") | ||
| 12 | + private Long propertyId; | ||
| 13 | + | ||
| 14 | + @ApiModelProperty(value = "属性的名称", required = true, example = "颜色") | ||
| 15 | + private String propertyName; | ||
| 16 | + | ||
| 17 | + @ApiModelProperty(value = "属性值的编号", required = true, example = "1024") | ||
| 18 | + private Long valueId; | ||
| 19 | + | ||
| 20 | + @ApiModelProperty(value = "属性值的名称", required = true, example = "红色") | ||
| 21 | + private String valueName; | ||
| 22 | + | ||
| 23 | +} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http
0 → 100644
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
| @@ -3,8 +3,13 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; | @@ -3,8 +3,13 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; | 5 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; |
| 6 | +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; | ||
| 6 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; | 7 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; |
| 8 | +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | ||
| 7 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; | 9 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 10 | +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; | ||
| 11 | +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; | ||
| 12 | +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; | ||
| 8 | import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; | 13 | import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; |
| 9 | import io.swagger.annotations.Api; | 14 | import io.swagger.annotations.Api; |
| 10 | import io.swagger.annotations.ApiImplicitParam; | 15 | import io.swagger.annotations.ApiImplicitParam; |
| @@ -15,10 +20,11 @@ import org.springframework.web.bind.annotation.*; | @@ -15,10 +20,11 @@ import org.springframework.web.bind.annotation.*; | ||
| 15 | 20 | ||
| 16 | import javax.annotation.Resource; | 21 | import javax.annotation.Resource; |
| 17 | import javax.validation.Valid; | 22 | import javax.validation.Valid; |
| 18 | -import java.util.Collection; | ||
| 19 | import java.util.List; | 23 | import java.util.List; |
| 20 | 24 | ||
| 25 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 26 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; | ||
| 22 | 28 | ||
| 23 | @Api(tags = "管理后台 - 商品 SPU") | 29 | @Api(tags = "管理后台 - 商品 SPU") |
| 24 | @RestController | 30 | @RestController |
| @@ -28,6 +34,10 @@ public class ProductSpuController { | @@ -28,6 +34,10 @@ public class ProductSpuController { | ||
| 28 | 34 | ||
| 29 | @Resource | 35 | @Resource |
| 30 | private ProductSpuService productSpuService; | 36 | private ProductSpuService productSpuService; |
| 37 | + @Resource | ||
| 38 | + private ProductSkuService productSkuService; | ||
| 39 | + @Resource | ||
| 40 | + private ProductPropertyValueService productPropertyValueService; | ||
| 31 | 41 | ||
| 32 | @PostMapping("/create") | 42 | @PostMapping("/create") |
| 33 | @ApiOperation("创建商品 SPU") | 43 | @ApiOperation("创建商品 SPU") |
| @@ -53,31 +63,24 @@ public class ProductSpuController { | @@ -53,31 +63,24 @@ public class ProductSpuController { | ||
| 53 | return success(true); | 63 | return success(true); |
| 54 | } | 64 | } |
| 55 | 65 | ||
| 56 | - // TODO 芋艿:修改接口 | ||
| 57 | - @GetMapping("/get/detail") | ||
| 58 | - @ApiOperation("获得商品 SPU") | 66 | + @GetMapping("/get-detail") |
| 67 | + @ApiOperation("获得商品 SPU 明细") | ||
| 59 | @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | 68 | @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) |
| 60 | @PreAuthorize("@ss.hasPermission('product:spu:query')") | 69 | @PreAuthorize("@ss.hasPermission('product:spu:query')") |
| 61 | public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) { | 70 | public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) { |
| 62 | - return success(productSpuService.getSpuDetail(id)); | ||
| 63 | - } | 71 | + // 获得商品 SPU |
| 72 | + ProductSpuDO spu = productSpuService.getSpu(id); | ||
| 73 | + if (spu == null) { | ||
| 74 | + throw exception(SPU_NOT_EXISTS); | ||
| 75 | + } | ||
| 64 | 76 | ||
| 65 | - @GetMapping("/get") | ||
| 66 | - @ApiOperation("获得商品 SPU") | ||
| 67 | - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | ||
| 68 | - @PreAuthorize("@ss.hasPermission('product:spu:query')") | ||
| 69 | - public CommonResult<ProductSpuDO> getSpu(@RequestParam("id") Long id) { | ||
| 70 | - return success(productSpuService.getSpu(id)); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - @GetMapping("/list") | ||
| 75 | - @ApiOperation("获得商品 SPU 列表") | ||
| 76 | - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) | ||
| 77 | - @PreAuthorize("@ss.hasPermission('product:spu:query')") | ||
| 78 | - public CommonResult<List<ProductSpuDO>> getSpuList(@RequestParam("ids") Collection<Long> ids) { | ||
| 79 | - List<ProductSpuDO> list = productSpuService.getSpuList(ids); | ||
| 80 | - return success(ProductSpuConvert.INSTANCE.convertList(list)); | 77 | + // 查询商品 SKU |
| 78 | + List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null); | ||
| 79 | + // 查询商品属性 | ||
| 80 | + List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService | ||
| 81 | + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); | ||
| 82 | + // 拼接 | ||
| 83 | + return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues)); | ||
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | @GetMapping("/get-simple-list") | 86 | @GetMapping("/get-simple-list") |
| @@ -92,7 +95,7 @@ public class ProductSpuController { | @@ -92,7 +95,7 @@ public class ProductSpuController { | ||
| 92 | @ApiOperation("获得商品 SPU 分页") | 95 | @ApiOperation("获得商品 SPU 分页") |
| 93 | @PreAuthorize("@ss.hasPermission('product:spu:query')") | 96 | @PreAuthorize("@ss.hasPermission('product:spu:query')") |
| 94 | public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { | 97 | public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { |
| 95 | - return success(productSpuService.getSpuPage(pageVO)); | 98 | + return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | } | 101 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
| 1 | package cn.iocoder.yudao.module.product.controller.admin.spu.vo; | 1 | package cn.iocoder.yudao.module.product.controller.admin.spu.vo; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; | 3 | +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; |
| 4 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; | 4 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; |
| 5 | import io.swagger.annotations.ApiModel; | 5 | import io.swagger.annotations.ApiModel; |
| 6 | -import io.swagger.annotations.ApiModelProperty; | ||
| 7 | import lombok.Data; | 6 | import lombok.Data; |
| 8 | import lombok.EqualsAndHashCode; | 7 | import lombok.EqualsAndHashCode; |
| 9 | import lombok.ToString; | 8 | import lombok.ToString; |
| 10 | 9 | ||
| 11 | -import java.time.LocalDateTime; | ||
| 12 | import java.util.List; | 10 | import java.util.List; |
| 13 | 11 | ||
| 14 | @ApiModel(value = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息") | 12 | @ApiModel(value = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息") |
| 15 | @Data | 13 | @Data |
| 16 | @EqualsAndHashCode(callSuper = true) | 14 | @EqualsAndHashCode(callSuper = true) |
| 17 | @ToString(callSuper = true) | 15 | @ToString(callSuper = true) |
| 18 | -public class ProductSpuDetailRespVO extends ProductSpuBaseVO { | ||
| 19 | - | ||
| 20 | - @ApiModelProperty(value = "主键", required = true, example = "1") | ||
| 21 | - private Long id; | ||
| 22 | - | ||
| 23 | - @ApiModelProperty(value = "创建时间") | ||
| 24 | - private LocalDateTime createTime; | 16 | +public class ProductSpuDetailRespVO extends ProductSpuRespVO { |
| 25 | 17 | ||
| 26 | // ========== SKU 相关字段 ========= | 18 | // ========== SKU 相关字段 ========= |
| 27 | 19 | ||
| 28 | - @ApiModelProperty(value = "库存", required = true, example = "true") | ||
| 29 | - private Integer totalStock; | ||
| 30 | - | ||
| 31 | - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") | ||
| 32 | - private Integer minPrice; | ||
| 33 | - | ||
| 34 | - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") | ||
| 35 | - private Integer maxPrice; | ||
| 36 | - | ||
| 37 | - @ApiModelProperty(value = "商品销量", example = "1024") | ||
| 38 | - private Integer salesCount; | ||
| 39 | - | ||
| 40 | /** | 20 | /** |
| 41 | * SKU 数组 | 21 | * SKU 数组 |
| 42 | */ | 22 | */ |
| 43 | private List<Sku> skus; | 23 | private List<Sku> skus; |
| 44 | 24 | ||
| 45 | - // ========== 统计相关字段 ========= | ||
| 46 | - | ||
| 47 | - @ApiModelProperty(value = "点击量", example = "1024") | ||
| 48 | - private Integer clickCount; | ||
| 49 | - | ||
| 50 | @ApiModel(value = "管理后台 - 商品 SKU 详细 Response VO") | 25 | @ApiModel(value = "管理后台 - 商品 SKU 详细 Response VO") |
| 51 | @Data | 26 | @Data |
| 52 | @EqualsAndHashCode(callSuper = true) | 27 | @EqualsAndHashCode(callSuper = true) |
| @@ -56,29 +31,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { | @@ -56,29 +31,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { | ||
| 56 | /** | 31 | /** |
| 57 | * 属性数组 | 32 | * 属性数组 |
| 58 | */ | 33 | */ |
| 59 | - private List<ProductSpuDetailRespVO.Property> properties; | ||
| 60 | - | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - @ApiModel(value = "管理后台 - 商品属性的详细 Response VO") | ||
| 64 | - @Data | ||
| 65 | - @EqualsAndHashCode(callSuper = true) | ||
| 66 | - @ToString(callSuper = true) | ||
| 67 | - public static class Property extends ProductSkuBaseVO.Property { | ||
| 68 | - | ||
| 69 | - @ApiModelProperty(value = "属性项的名字", required = true, example = "颜色") | ||
| 70 | - private String propertyName; | ||
| 71 | - | ||
| 72 | - @ApiModelProperty(value = "属性值的名称", required = true, example = "蓝色") | ||
| 73 | - private String valueName; | 34 | + private List<ProductPropertyValueDetailRespVO> properties; |
| 74 | 35 | ||
| 75 | } | 36 | } |
| 76 | 37 | ||
| 77 | - @ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "4") | ||
| 78 | - private Long categoryId; | ||
| 79 | - | ||
| 80 | - // TODO @芋艿:在瞅瞅~ | ||
| 81 | - @ApiModelProperty(value = "属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") | ||
| 82 | - private List<ProductPropertyViewRespVO> productPropertyViews; | ||
| 83 | - | ||
| 84 | } | 38 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
| @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; | 6 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; |
| 7 | -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO; | ||
| 8 | -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageItemRespVO; | 7 | +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; |
| 8 | +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; | ||
| 9 | import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; | 9 | import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; |
| 10 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; | 10 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; |
| 11 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | 11 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| @@ -48,7 +48,7 @@ public class AppProductSpuController { | @@ -48,7 +48,7 @@ public class AppProductSpuController { | ||
| 48 | 48 | ||
| 49 | @GetMapping("/page") | 49 | @GetMapping("/page") |
| 50 | @ApiOperation("获得商品 SPU 分页") | 50 | @ApiOperation("获得商品 SPU 分页") |
| 51 | - public CommonResult<PageResult<AppSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { | 51 | + public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { |
| 52 | PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus()); | 52 | PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus()); |
| 53 | return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult)); | 53 | return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult)); |
| 54 | } | 54 | } |
| @@ -56,7 +56,7 @@ public class AppProductSpuController { | @@ -56,7 +56,7 @@ public class AppProductSpuController { | ||
| 56 | @GetMapping("/get-detail") | 56 | @GetMapping("/get-detail") |
| 57 | @ApiOperation("获得商品 SPU 明细") | 57 | @ApiOperation("获得商品 SPU 明细") |
| 58 | @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | 58 | @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) |
| 59 | - public CommonResult<AppSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) { | 59 | + public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) { |
| 60 | // 获得商品 SPU | 60 | // 获得商品 SPU |
| 61 | ProductSpuDO spu = productSpuService.getSpu(id); | 61 | ProductSpuDO spu = productSpuService.getSpu(id); |
| 62 | if (spu == null) { | 62 | if (spu == null) { |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuDetailRespVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java
| @@ -9,7 +9,7 @@ import java.util.List; | @@ -9,7 +9,7 @@ import java.util.List; | ||
| 9 | 9 | ||
| 10 | @ApiModel("用户 App - 商品 SPU 明细 Response VO") | 10 | @ApiModel("用户 App - 商品 SPU 明细 Response VO") |
| 11 | @Data | 11 | @Data |
| 12 | -public class AppSpuDetailRespVO { | 12 | +public class AppProductSpuDetailRespVO { |
| 13 | 13 | ||
| 14 | @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") | 14 | @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") |
| 15 | private Long id; | 15 | private Long id; |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageItemRespVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java
| @@ -10,7 +10,7 @@ import java.util.List; | @@ -10,7 +10,7 @@ import java.util.List; | ||
| 10 | 10 | ||
| 11 | @ApiModel("用户 App - 商品 SPU 分页项 Response VO") | 11 | @ApiModel("用户 App - 商品 SPU 分页项 Response VO") |
| 12 | @Data | 12 | @Data |
| 13 | -public class AppSpuPageItemRespVO { | 13 | +public class AppProductSpuPageItemRespVO { |
| 14 | 14 | ||
| 15 | @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") | 15 | @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") |
| 16 | private Long id; | 16 | private Long id; |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
| @@ -3,11 +3,12 @@ package cn.iocoder.yudao.module.product.convert.spu; | @@ -3,11 +3,12 @@ package cn.iocoder.yudao.module.product.convert.spu; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 5 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 6 | +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; | ||
| 6 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; | 7 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; |
| 7 | import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; | 8 | import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; |
| 9 | +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; | ||
| 8 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; | 10 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; |
| 9 | -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO; | ||
| 10 | -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageItemRespVO; | 11 | +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; |
| 11 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | 12 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| 12 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; | 13 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 13 | import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; | 14 | import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; |
| @@ -45,9 +46,9 @@ public interface ProductSpuConvert { | @@ -45,9 +46,9 @@ public interface ProductSpuConvert { | ||
| 45 | 46 | ||
| 46 | List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list); | 47 | List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list); |
| 47 | 48 | ||
| 48 | - default AppSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus, | ||
| 49 | - List<ProductPropertyValueDetailRespBO> propertyValues) { | ||
| 50 | - AppSpuDetailRespVO spuVO = convert02(spu) | 49 | + default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus, |
| 50 | + List<ProductPropertyValueDetailRespBO> propertyValues) { | ||
| 51 | + AppProductSpuDetailRespVO spuVO = convert02(spu) | ||
| 51 | .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); | 52 | .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); |
| 52 | spuVO.setSkus(convertList03(skus)); | 53 | spuVO.setSkus(convertList03(skus)); |
| 53 | // 处理商品属性 | 54 | // 处理商品属性 |
| @@ -57,7 +58,7 @@ public interface ProductSpuConvert { | @@ -57,7 +58,7 @@ public interface ProductSpuConvert { | ||
| 57 | if (CollUtil.isEmpty(properties)) { | 58 | if (CollUtil.isEmpty(properties)) { |
| 58 | continue; | 59 | continue; |
| 59 | } | 60 | } |
| 60 | - AppSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); | 61 | + AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); |
| 61 | sku.setProperties(new ArrayList<>(properties.size())); | 62 | sku.setProperties(new ArrayList<>(properties.size())); |
| 62 | // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 | 63 | // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 |
| 63 | properties.forEach(property -> { | 64 | properties.forEach(property -> { |
| @@ -70,10 +71,38 @@ public interface ProductSpuConvert { | @@ -70,10 +71,38 @@ public interface ProductSpuConvert { | ||
| 70 | } | 71 | } |
| 71 | return spuVO; | 72 | return spuVO; |
| 72 | } | 73 | } |
| 73 | - AppSpuDetailRespVO convert02(ProductSpuDO spu); | ||
| 74 | - List<AppSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus); | 74 | + AppProductSpuDetailRespVO convert02(ProductSpuDO spu); |
| 75 | + List<AppProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus); | ||
| 75 | AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); | 76 | AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); |
| 76 | 77 | ||
| 77 | - PageResult<AppSpuPageItemRespVO> convertPage02(PageResult<ProductSpuDO> page); | 78 | + PageResult<AppProductSpuPageItemRespVO> convertPage02(PageResult<ProductSpuDO> page); |
| 79 | + | ||
| 80 | + default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus, | ||
| 81 | + List<ProductPropertyValueDetailRespBO> propertyValues) { | ||
| 82 | + ProductSpuDetailRespVO spuVO = convert03(spu); | ||
| 83 | + spuVO.setSkus(convertList04(skus)); | ||
| 84 | + // 处理商品属性 | ||
| 85 | + Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); | ||
| 86 | + for (int i = 0; i < skus.size(); i++) { | ||
| 87 | + List<ProductSkuDO.Property> properties = skus.get(i).getProperties(); | ||
| 88 | + if (CollUtil.isEmpty(properties)) { | ||
| 89 | + continue; | ||
| 90 | + } | ||
| 91 | + ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); | ||
| 92 | + sku.setProperties(new ArrayList<>(properties.size())); | ||
| 93 | + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 | ||
| 94 | + properties.forEach(property -> { | ||
| 95 | + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); | ||
| 96 | + if (propertyValue == null) { | ||
| 97 | + return; | ||
| 98 | + } | ||
| 99 | + sku.getProperties().add(convert04(propertyValue)); | ||
| 100 | + }); | ||
| 101 | + } | ||
| 102 | + return spuVO; | ||
| 103 | + } | ||
| 104 | + ProductSpuDetailRespVO convert03(ProductSpuDO spu); | ||
| 105 | + List<ProductSpuDetailRespVO.Sku> convertList04(List<ProductSkuDO> skus); | ||
| 106 | + ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); | ||
| 78 | 107 | ||
| 79 | } | 108 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java
| @@ -21,8 +21,7 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> { | @@ -21,8 +21,7 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> { | ||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | default ProductPropertyDO selectByName(String name) { | 23 | default ProductPropertyDO selectByName(String name) { |
| 24 | - return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>() | ||
| 25 | - .eqIfPresent(ProductPropertyDO::getName, name)); | 24 | + return selectOne(ProductPropertyDO::getName, name); |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | default List<ProductPropertyDO> selectList(ProductPropertyListReqVO listReqVO) { | 27 | default List<ProductPropertyDO> selectList(ProductPropertyListReqVO listReqVO) { |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java
| @@ -40,9 +40,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { | @@ -40,9 +40,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { | ||
| 40 | @Override | 40 | @Override |
| 41 | @Transactional(rollbackFor = Exception.class) | 41 | @Transactional(rollbackFor = Exception.class) |
| 42 | public Long createProperty(ProductPropertyCreateReqVO createReqVO) { | 42 | public Long createProperty(ProductPropertyCreateReqVO createReqVO) { |
| 43 | - // 校验名字重复 | ||
| 44 | - if (productPropertyMapper.selectByName(createReqVO.getName()) != null) { | ||
| 45 | - throw exception(PROPERTY_EXISTS); | 43 | + // 如果已经添加过该属性项,直接返回 |
| 44 | + ProductPropertyDO dbProperty = productPropertyMapper.selectByName(createReqVO.getName()); | ||
| 45 | + if (dbProperty != null) { | ||
| 46 | + return dbProperty.getId(); | ||
| 46 | } | 47 | } |
| 47 | 48 | ||
| 48 | // 插入 | 49 | // 插入 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java
| @@ -19,6 +19,7 @@ public interface ProductPropertyValueService { | @@ -19,6 +19,7 @@ public interface ProductPropertyValueService { | ||
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | * 创建属性值 | 21 | * 创建属性值 |
| 22 | + * 注意,如果已经存在该属性值,直接返回它的编号即可 | ||
| 22 | * | 23 | * |
| 23 | * @param createReqVO 创建信息 | 24 | * @param createReqVO 创建信息 |
| 24 | * @return 编号 | 25 | * @return 编号 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java
| @@ -42,9 +42,11 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ | @@ -42,9 +42,11 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ | ||
| 42 | 42 | ||
| 43 | @Override | 43 | @Override |
| 44 | public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { | 44 | public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { |
| 45 | - // 校验名字唯一 | ||
| 46 | - if (productPropertyValueMapper.selectByName(createReqVO.getPropertyId(), createReqVO.getName()) != null) { | ||
| 47 | - throw exception(PROPERTY_VALUE_EXISTS); | 45 | + // 如果已经添加过该属性值,直接返回 |
| 46 | + ProductPropertyValueDO dbValue = productPropertyValueMapper.selectByName( | ||
| 47 | + createReqVO.getPropertyId(), createReqVO.getName()); | ||
| 48 | + if (dbValue != null) { | ||
| 49 | + return dbValue.getId(); | ||
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | // 新增 | 52 | // 新增 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
| @@ -42,14 +42,6 @@ public interface ProductSpuService { | @@ -42,14 +42,6 @@ public interface ProductSpuService { | ||
| 42 | void deleteSpu(Long id); | 42 | void deleteSpu(Long id); |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | - * 获得商品 SPU 详情 | ||
| 46 | - * | ||
| 47 | - * @param id 编号 | ||
| 48 | - * @return 商品 SPU | ||
| 49 | - */ | ||
| 50 | - ProductSpuDetailRespVO getSpuDetail(Long id); | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | * 获得商品 SPU | 45 | * 获得商品 SPU |
| 54 | * | 46 | * |
| 55 | * @param id 编号 | 47 | * @param id 编号 |
| @@ -88,7 +80,7 @@ public interface ProductSpuService { | @@ -88,7 +80,7 @@ public interface ProductSpuService { | ||
| 88 | * @param pageReqVO 分页查询 | 80 | * @param pageReqVO 分页查询 |
| 89 | * @return 商品spu分页 | 81 | * @return 商品spu分页 |
| 90 | */ | 82 | */ |
| 91 | - PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO); | 83 | + PageResult<ProductSpuDO> getSpuPage(ProductSpuPageReqVO pageReqVO); |
| 92 | 84 | ||
| 93 | /** | 85 | /** |
| 94 | * 获得商品 SPU 分页 | 86 | * 获得商品 SPU 分页 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| 1 | package cn.iocoder.yudao.module.product.service.spu; | 1 | package cn.iocoder.yudao.module.product.service.spu; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.bean.BeanUtil; | ||
| 4 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; | ||
| 8 | -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; | ||
| 9 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; | 6 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; |
| 10 | -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; | ||
| 11 | -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; | 7 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; |
| 8 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; | ||
| 12 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; | 10 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; |
| 13 | -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; | ||
| 14 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; | 11 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; |
| 15 | -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; | ||
| 16 | -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | ||
| 17 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | 12 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| 18 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; | 13 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 19 | import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; | 14 | import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; |
| 20 | -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; | ||
| 21 | import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; | 15 | import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; |
| 22 | import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; | 16 | import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; |
| 23 | -import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; | ||
| 24 | -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; | ||
| 25 | import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; | 17 | import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; |
| 26 | import org.springframework.context.annotation.Lazy; | 18 | import org.springframework.context.annotation.Lazy; |
| 27 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
| @@ -29,8 +21,10 @@ import org.springframework.transaction.annotation.Transactional; | @@ -29,8 +21,10 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 29 | import org.springframework.validation.annotation.Validated; | 21 | import org.springframework.validation.annotation.Validated; |
| 30 | 22 | ||
| 31 | import javax.annotation.Resource; | 23 | import javax.annotation.Resource; |
| 32 | -import java.util.*; | ||
| 33 | -import java.util.stream.Collectors; | 24 | +import java.util.Collection; |
| 25 | +import java.util.List; | ||
| 26 | +import java.util.Map; | ||
| 27 | +import java.util.Set; | ||
| 34 | 28 | ||
| 35 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 29 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 36 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 30 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| @@ -50,17 +44,12 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -50,17 +44,12 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 50 | private ProductSpuMapper productSpuMapper; | 44 | private ProductSpuMapper productSpuMapper; |
| 51 | 45 | ||
| 52 | @Resource | 46 | @Resource |
| 53 | - private ProductCategoryService categoryService; | ||
| 54 | - | ||
| 55 | - @Resource | ||
| 56 | @Lazy // 循环依赖,避免报错 | 47 | @Lazy // 循环依赖,避免报错 |
| 57 | private ProductSkuService productSkuService; | 48 | private ProductSkuService productSkuService; |
| 58 | @Resource | 49 | @Resource |
| 59 | - private ProductPropertyService productPropertyService; | ||
| 60 | - @Resource | ||
| 61 | - private ProductPropertyValueService productPropertyValueService; | ||
| 62 | - @Resource | ||
| 63 | private ProductBrandService brandService; | 50 | private ProductBrandService brandService; |
| 51 | + @Resource | ||
| 52 | + private ProductCategoryService categoryService; | ||
| 64 | 53 | ||
| 65 | @Override | 54 | @Override |
| 66 | @Transactional(rollbackFor = Exception.class) | 55 | @Transactional(rollbackFor = Exception.class) |
| @@ -149,46 +138,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -149,46 +138,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 149 | } | 138 | } |
| 150 | 139 | ||
| 151 | @Override | 140 | @Override |
| 152 | - // TODO @芋艿:需要再 review 下 | ||
| 153 | - public ProductSpuDetailRespVO getSpuDetail(Long id) { | ||
| 154 | - ProductSpuDO spu = productSpuMapper.selectById(id); | ||
| 155 | - ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class); | ||
| 156 | - if (null != spu) { | ||
| 157 | - List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkuListBySpuId(id)); | ||
| 158 | - respVO.setSkus(skuReqs); | ||
| 159 | - // 组合 sku 属性 | ||
| 160 | - if (spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) { | ||
| 161 | - List<ProductSkuRespVO.Property> properties = new ArrayList<>(); | ||
| 162 | - for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) { | ||
| 163 | - properties.addAll(productSkuRespVO.getProperties()); | ||
| 164 | - } | ||
| 165 | - Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId)); | ||
| 166 | - | ||
| 167 | - List<ProductPropertyValueDO> propertyValueList = productPropertyValueService.getPropertyValueListByPropertyId(propertyMaps.keySet()); | ||
| 168 | - List<ProductPropertyDO> propertyList = productPropertyService.getPropertyList(propertyMaps.keySet()); | ||
| 169 | - // 装载组装过后的属性 | ||
| 170 | - List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>(); | ||
| 171 | - propertyList.forEach(p -> { | ||
| 172 | - ProductPropertyViewRespVO productPropertyViewRespVO = new ProductPropertyViewRespVO(); | ||
| 173 | - productPropertyViewRespVO.setPropertyId(p.getId()); | ||
| 174 | - productPropertyViewRespVO.setName(p.getName()); | ||
| 175 | - List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>(); | ||
| 176 | - // 转换成map是为了能快速获取 | ||
| 177 | - Map<Long, ProductPropertyValueDO> propertyValueMaps = convertMap(propertyValueList, ProductPropertyValueDO::getId); | ||
| 178 | - propertyMaps.get(p.getId()).forEach(pv -> { | ||
| 179 | - ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName()); | ||
| 180 | - propertyValues.add(tuple2); | ||
| 181 | - }); | ||
| 182 | - productPropertyViewRespVO.setPropertyValues(propertyValues.stream().distinct().collect(Collectors.toList())); | ||
| 183 | - productPropertyViews.add(productPropertyViewRespVO); | ||
| 184 | - }); | ||
| 185 | - respVO.setProductPropertyViews(productPropertyViews); | ||
| 186 | - } | ||
| 187 | - } | ||
| 188 | - return respVO; | ||
| 189 | - } | ||
| 190 | - | ||
| 191 | - @Override | ||
| 192 | public ProductSpuDO getSpu(Long id) { | 141 | public ProductSpuDO getSpu(Long id) { |
| 193 | return productSpuMapper.selectById(id); | 142 | return productSpuMapper.selectById(id); |
| 194 | } | 143 | } |
| @@ -203,9 +152,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -203,9 +152,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 203 | return productSpuMapper.selectList(); | 152 | return productSpuMapper.selectList(); |
| 204 | } | 153 | } |
| 205 | 154 | ||
| 206 | - // TODO 芋艿:改成 DO 返回 | ||
| 207 | @Override | 155 | @Override |
| 208 | - public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { | 156 | + public PageResult<ProductSpuDO> getSpuPage(ProductSpuPageReqVO pageReqVO) { |
| 209 | // 库存告警的 SPU 编号的集合 | 157 | // 库存告警的 SPU 编号的集合 |
| 210 | Set<Long> alarmStockSpuIds = null; | 158 | Set<Long> alarmStockSpuIds = null; |
| 211 | if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { | 159 | if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { |
| @@ -215,7 +163,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -215,7 +163,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 215 | } | 163 | } |
| 216 | } | 164 | } |
| 217 | // 分页查询 | 165 | // 分页查询 |
| 218 | - return ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds)); | 166 | + return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds); |
| 219 | } | 167 | } |
| 220 | 168 | ||
| 221 | @Override | 169 | @Override |
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java
| @@ -19,11 +19,12 @@ import java.util.Arrays; | @@ -19,11 +19,12 @@ import java.util.Arrays; | ||
| 19 | import java.util.List; | 19 | import java.util.List; |
| 20 | 20 | ||
| 21 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | 21 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 22 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||
| 22 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | 23 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 24 | +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | ||
| 23 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; | 25 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; |
| 24 | import static java.util.Collections.singletonList; | 26 | import static java.util.Collections.singletonList; |
| 25 | -import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 26 | -import static org.junit.jupiter.api.Assertions.assertNotEquals; | 27 | +import static org.junit.jupiter.api.Assertions.*; |
| 27 | import static org.mockito.ArgumentMatchers.argThat; | 28 | import static org.mockito.ArgumentMatchers.argThat; |
| 28 | import static org.mockito.Mockito.verify; | 29 | import static org.mockito.Mockito.verify; |
| 29 | 30 | ||
| @@ -145,4 +146,26 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { | @@ -145,4 +146,26 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { | ||
| 145 | SKU_STOCK_NOT_ENOUGH); | 146 | SKU_STOCK_NOT_ENOUGH); |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 149 | + @Test | ||
| 150 | + public void testDeleteSku_success() { | ||
| 151 | + // mock 数据 | ||
| 152 | + ProductSkuDO dbSku = randomPojo(ProductSkuDO.class); | ||
| 153 | + productSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据 | ||
| 154 | + // 准备参数 | ||
| 155 | + Long id = dbSku.getId(); | ||
| 156 | + | ||
| 157 | + // 调用 | ||
| 158 | + productSkuService.deleteSku(id); | ||
| 159 | + // 校验数据不存在了 | ||
| 160 | + assertNull(productSkuMapper.selectById(id)); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + @Test | ||
| 164 | + public void testDeleteSku_notExists() { | ||
| 165 | + // 准备参数 | ||
| 166 | + Long id = 1L; | ||
| 167 | + | ||
| 168 | + // 调用, 并断言异常 | ||
| 169 | + assertServiceException(() -> productSkuService.deleteSku(id), SKU_NOT_EXISTS); | ||
| 170 | + } | ||
| 148 | } | 171 | } |
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java deleted
| 1 | -package cn.iocoder.yudao.module.product.service.sku; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||
| 4 | -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | ||
| 5 | -import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; | ||
| 6 | -import org.junit.jupiter.api.Disabled; | ||
| 7 | -import org.junit.jupiter.api.Test; | ||
| 8 | -import org.springframework.context.annotation.Import; | ||
| 9 | - | ||
| 10 | -import javax.annotation.Resource; | ||
| 11 | - | ||
| 12 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||
| 13 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||
| 14 | -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | ||
| 15 | -import static org.junit.jupiter.api.Assertions.assertNull; | ||
| 16 | - | ||
| 17 | -// TODO 芋艿:整合到 {@link ProductSkuServiceTest} 中 | ||
| 18 | -/** | ||
| 19 | -* {@link ProductSkuServiceImpl} 的单元测试类 | ||
| 20 | -* | ||
| 21 | -* @author 芋道源码 | ||
| 22 | -*/ | ||
| 23 | -@Import(ProductSkuServiceImpl.class) | ||
| 24 | -@Disabled // TODO 芋艿:临时去掉 | ||
| 25 | -public class SkuServiceImplTest extends BaseDbUnitTest { | ||
| 26 | - | ||
| 27 | - @Resource | ||
| 28 | - private ProductSkuServiceImpl ProductSkuService; | ||
| 29 | - | ||
| 30 | - @Resource | ||
| 31 | - private ProductSkuMapper ProductSkuMapper; | ||
| 32 | - | ||
| 33 | - @Test | ||
| 34 | - public void testDeleteSku_success() { | ||
| 35 | - // mock 数据 | ||
| 36 | - ProductSkuDO dbSku = randomPojo(ProductSkuDO.class); | ||
| 37 | - ProductSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据 | ||
| 38 | - // 准备参数 | ||
| 39 | - Long id = dbSku.getId(); | ||
| 40 | - | ||
| 41 | - // 调用 | ||
| 42 | - ProductSkuService.deleteSku(id); | ||
| 43 | - // 校验数据不存在了 | ||
| 44 | - assertNull(ProductSkuMapper.selectById(id)); | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - @Test | ||
| 48 | - public void testDeleteSku_notExists() { | ||
| 49 | - // 准备参数 | ||
| 50 | - Long id = 1L; | ||
| 51 | - | ||
| 52 | - // 调用, 并断言异常 | ||
| 53 | - assertServiceException(() -> ProductSkuService.deleteSku(id), SKU_NOT_EXISTS); | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | -} |
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
| @@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 8 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 9 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | 9 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; |
| 10 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 10 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 11 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; | ||
| 12 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | ||
| 13 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; | 11 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; |
| 14 | -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; | 12 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; |
| 13 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; | ||
| 14 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; | ||
| 15 | +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; | ||
| 15 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; | 16 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; |
| 16 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; | 17 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; |
| 17 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | 18 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| @@ -149,53 +150,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -149,53 +150,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | @Test | 152 | @Test |
| 152 | - void getSpuDetail() { | ||
| 153 | - // 准备spu参数 | ||
| 154 | - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> { | ||
| 155 | - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); | ||
| 156 | - }); | ||
| 157 | - productSpuMapper.insert(createReqVO); | ||
| 158 | - | ||
| 159 | - // 创建两个属性 | ||
| 160 | - ArrayList<ProductPropertyRespVO> productPropertyRespVOS = Lists.newArrayList( | ||
| 161 | - randomPojo(ProductPropertyRespVO.class), | ||
| 162 | - randomPojo(ProductPropertyRespVO.class)); | ||
| 163 | - | ||
| 164 | - // 所有属性值 | ||
| 165 | - ArrayList<ProductPropertyValueRespVO> productPropertyValueRespVO = new ArrayList<>(); | ||
| 166 | - | ||
| 167 | - // 每个属性创建属性值 | ||
| 168 | - productPropertyRespVOS.forEach(v -> { | ||
| 169 | - ProductPropertyValueRespVO productPropertyValueRespVO1 = randomPojo(ProductPropertyValueRespVO.class, o -> o.setPropertyId(v.getId())); | ||
| 170 | - productPropertyValueRespVO.add(productPropertyValueRespVO1); | ||
| 171 | - }); | ||
| 172 | - | ||
| 173 | - // 属性值建立笛卡尔积 | ||
| 174 | - Map<Long, List<ProductPropertyValueRespVO>> collect = productPropertyValueRespVO.stream().collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId)); | ||
| 175 | - List<List<ProductPropertyValueRespVO>> lists = cartesianProduct(Lists.newArrayList(collect.values())); | ||
| 176 | - | ||
| 177 | - // 准备sku参数 | ||
| 178 | - ArrayList<ProductSkuDO> productSkuDOS = Lists.newArrayList(); | ||
| 179 | - lists.forEach(pp -> { | ||
| 180 | - List<ProductSkuDO.Property> property = pp.stream().map(ppv -> new ProductSkuDO.Property(ppv.getPropertyId(), ppv.getId())).collect(Collectors.toList()); | ||
| 181 | - ProductSkuDO productSkuDO = randomPojo(ProductSkuDO.class, o -> { | ||
| 182 | - o.setProperties(property); | ||
| 183 | - }); | ||
| 184 | - productSkuDOS.add(productSkuDO); | ||
| 185 | - | ||
| 186 | - }); | ||
| 187 | - | ||
| 188 | - Mockito.when(productSkuService.getSkuListBySpuId(createReqVO.getId())).thenReturn(productSkuDOS); | ||
| 189 | -// Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO); | ||
| 190 | -// Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS); | ||
| 191 | -// | ||
| 192 | - // 调用 | ||
| 193 | - ProductSpuDetailRespVO spuDetail = productSpuService.getSpuDetail(createReqVO.getId()); | ||
| 194 | - | ||
| 195 | - assertPojoEquals(createReqVO, spuDetail); | ||
| 196 | - } | ||
| 197 | - | ||
| 198 | - @Test | ||
| 199 | void getSpu() { | 153 | void getSpu() { |
| 200 | // 准备参数 | 154 | // 准备参数 |
| 201 | ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); | 155 | ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); |
| @@ -222,7 +176,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -222,7 +176,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 222 | ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); | 176 | ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); |
| 223 | productSpuPageReqVO.setAlarmStock(true); | 177 | productSpuPageReqVO.setAlarmStock(true); |
| 224 | 178 | ||
| 225 | - PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); | 179 | + PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); |
| 226 | 180 | ||
| 227 | PageResult<Object> result = PageResult.empty(); | 181 | PageResult<Object> result = PageResult.empty(); |
| 228 | Assertions.assertIterableEquals(result.getList(), spuPage.getList()); | 182 | Assertions.assertIterableEquals(result.getList(), spuPage.getList()); |
| @@ -271,7 +225,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -271,7 +225,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 271 | // 调用 | 225 | // 调用 |
| 272 | ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); | 226 | ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); |
| 273 | productSpuPageReqVO.setAlarmStock(true); | 227 | productSpuPageReqVO.setAlarmStock(true); |
| 274 | - PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); | 228 | + PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); |
| 275 | 229 | ||
| 276 | PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); | 230 | PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); |
| 277 | Assertions.assertIterableEquals(result.getList(), spuPage.getList()); | 231 | Assertions.assertIterableEquals(result.getList(), spuPage.getList()); |
| @@ -323,7 +277,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -323,7 +277,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 323 | productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); | 277 | productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); |
| 324 | productSpuPageReqVO.setCategoryId(categoryId); | 278 | productSpuPageReqVO.setCategoryId(categoryId); |
| 325 | 279 | ||
| 326 | - PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); | 280 | + PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO); |
| 327 | 281 | ||
| 328 | PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set<Long>) null)); | 282 | PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set<Long>) null)); |
| 329 | assertEquals(result, spuPage); | 283 | assertEquals(result, spuPage); |
yudao-module-system/yudao-module-system-biz/pom.xml
| @@ -54,6 +54,10 @@ | @@ -54,6 +54,10 @@ | ||
| 54 | <groupId>cn.iocoder.boot</groupId> | 54 | <groupId>cn.iocoder.boot</groupId> |
| 55 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | 55 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| 56 | </dependency> | 56 | </dependency> |
| 57 | + <dependency> | ||
| 58 | + <groupId>cn.iocoder.boot</groupId> | ||
| 59 | + <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> | ||
| 60 | + </dependency> | ||
| 57 | 61 | ||
| 58 | <!-- Web 相关 --> | 62 | <!-- Web 相关 --> |
| 59 | <dependency> | 63 | <dependency> |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.http
0 → 100644
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.controller.admin.ip; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.lang.Assert; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | +import cn.iocoder.yudao.framework.ip.core.Area; | ||
| 6 | +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||
| 7 | +import cn.iocoder.yudao.framework.ip.core.utils.IPUtils; | ||
| 8 | +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; | ||
| 9 | +import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; | ||
| 10 | +import io.swagger.annotations.Api; | ||
| 11 | +import io.swagger.annotations.ApiImplicitParam; | ||
| 12 | +import io.swagger.annotations.ApiOperation; | ||
| 13 | +import org.springframework.validation.annotation.Validated; | ||
| 14 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 15 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 16 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 17 | +import org.springframework.web.bind.annotation.RestController; | ||
| 18 | + | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 22 | + | ||
| 23 | +@Api(tags = "管理后台 - 地区") | ||
| 24 | +@RestController | ||
| 25 | +@RequestMapping("/system/area") | ||
| 26 | +@Validated | ||
| 27 | +public class AreaController { | ||
| 28 | + | ||
| 29 | + @GetMapping("/tree") | ||
| 30 | + @ApiOperation("获得地区树") | ||
| 31 | + public CommonResult<List<AreaNodeRespVO>> getAreaTree() { | ||
| 32 | + Area area = AreaUtils.getArea(Area.ID_CHINA); | ||
| 33 | + Assert.notNull(area, "获取不到中国"); | ||
| 34 | + return success(AreaConvert.INSTANCE.convertList(area.getChildren())); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @GetMapping("/get-by-ip") | ||
| 38 | + @ApiOperation("获得 IP 对应的地区名") | ||
| 39 | + @ApiImplicitParam(name = "ip", value = "IP", required = true, dataTypeClass = String.class) | ||
| 40 | + public CommonResult<String> getAreaByIp(@RequestParam("ip") String ip) { | ||
| 41 | + // 获得城市 | ||
| 42 | + Area area = IPUtils.getArea(ip); | ||
| 43 | + if (area == null) { | ||
| 44 | + return success("未知"); | ||
| 45 | + } | ||
| 46 | + // 格式化返回 | ||
| 47 | + return success(AreaUtils.format(area.getId())); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | +} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.controller.admin.ip.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModel; | ||
| 4 | +import io.swagger.annotations.ApiModelProperty; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +@ApiModel("管理后台 - 地区节点 Response VO") | ||
| 10 | +@Data | ||
| 11 | +public class AreaNodeRespVO { | ||
| 12 | + | ||
| 13 | + @ApiModelProperty(value = "编号", required = true, example = "110000") | ||
| 14 | + private Integer id; | ||
| 15 | + | ||
| 16 | + @ApiModelProperty(value = "名字", required = true, example = "北京") | ||
| 17 | + private String name; | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 子节点 | ||
| 21 | + */ | ||
| 22 | + private List<AreaNodeRespVO> children; | ||
| 23 | + | ||
| 24 | +} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.convert.ip; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.ip.core.Area; | ||
| 4 | +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; | ||
| 5 | +import org.mapstruct.Mapper; | ||
| 6 | +import org.mapstruct.factory.Mappers; | ||
| 7 | + | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 10 | +@Mapper | ||
| 11 | +public interface AreaConvert { | ||
| 12 | + | ||
| 13 | + AreaConvert INSTANCE = Mappers.getMapper(AreaConvert.class); | ||
| 14 | + | ||
| 15 | + List<AreaNodeRespVO> convertList(List<Area> list); | ||
| 16 | + | ||
| 17 | +} |
yudao-ui-admin/src/api/mall/product/spu.js
| @@ -26,18 +26,10 @@ export function deleteSpu(id) { | @@ -26,18 +26,10 @@ export function deleteSpu(id) { | ||
| 26 | }) | 26 | }) |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | -// 获得商品spu | ||
| 30 | -export function getSpu(id) { | ||
| 31 | - return request({ | ||
| 32 | - url: '/product/spu/get?id=' + id, | ||
| 33 | - method: 'get' | ||
| 34 | - }) | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | // 获得商品 SPU 详情 | 29 | // 获得商品 SPU 详情 |
| 38 | export function getSpuDetail(id) { | 30 | export function getSpuDetail(id) { |
| 39 | return request({ | 31 | return request({ |
| 40 | - url: '/product/spu/get/detail?id=' + id, | 32 | + url: '/product/spu/get-detail?id=' + id, |
| 41 | method: 'get' | 33 | method: 'get' |
| 42 | }) | 34 | }) |
| 43 | } | 35 | } |
yudao-ui-admin/src/api/system/area.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获得地区树 | ||
| 4 | +export function getAreaTree() { | ||
| 5 | + return request({ | ||
| 6 | + url: '/system/area/tree', | ||
| 7 | + method: 'get' | ||
| 8 | + }) | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +// 获得 IP 对应的地区名 | ||
| 12 | +export function getAreaByIp(ip) { | ||
| 13 | + return request({ | ||
| 14 | + url: '/system/area/get-by-ip?ip=' + ip, | ||
| 15 | + method: 'get' | ||
| 16 | + }) | ||
| 17 | +} |
yudao-ui-admin/src/views/mall/product/spu/save.vue
| @@ -4,9 +4,8 @@ | @@ -4,9 +4,8 @@ | ||
| 4 | <el-tabs v-model="activeName" class="tabs"> | 4 | <el-tabs v-model="activeName" class="tabs"> |
| 5 | <!-- 基础设置 --> | 5 | <!-- 基础设置 --> |
| 6 | <!-- TODO @luowenfeng:基础设置,分成基础信息、配送信息 --> | 6 | <!-- TODO @luowenfeng:基础设置,分成基础信息、配送信息 --> |
| 7 | - <!-- TODO @luowenfeng:base=》basic 会更好哈 --> | ||
| 8 | - <el-tab-pane label="基础设置" name="base"> | ||
| 9 | - <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> | 7 | + <el-tab-pane label="基础设置" name="basic"> |
| 8 | + <el-form ref="basic" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> | ||
| 10 | <el-form-item label="商品名称" prop="name"> | 9 | <el-form-item label="商品名称" prop="name"> |
| 11 | <el-input v-model="baseForm.name" placeholder="请输入商品名称" /> | 10 | <el-input v-model="baseForm.name" placeholder="请输入商品名称" /> |
| 12 | </el-form-item> | 11 | </el-form-item> |
| @@ -155,9 +154,8 @@ | @@ -155,9 +154,8 @@ | ||
| 155 | </el-tab-pane> | 154 | </el-tab-pane> |
| 156 | 155 | ||
| 157 | <!-- 商品详情 --> | 156 | <!-- 商品详情 --> |
| 158 | - <!-- TODO @luowenfeng:third=》detail 会更好哈 --> | ||
| 159 | - <el-tab-pane label="商品详情" name="third"> | ||
| 160 | - <el-form ref="third" :model="baseForm" :rules="rules"> | 157 | + <el-tab-pane label="商品详情" name="detail"> |
| 158 | + <el-form ref="detail" :model="baseForm" :rules="rules"> | ||
| 161 | <el-form-item prop="description"> | 159 | <el-form-item prop="description"> |
| 162 | <editor v-model="baseForm.description" :min-height="380"/> | 160 | <editor v-model="baseForm.description" :min-height="380"/> |
| 163 | </el-form-item> | 161 | </el-form-item> |
| @@ -165,9 +163,8 @@ | @@ -165,9 +163,8 @@ | ||
| 165 | </el-tab-pane> | 163 | </el-tab-pane> |
| 166 | 164 | ||
| 167 | <!-- 销售设置 --> | 165 | <!-- 销售设置 --> |
| 168 | - <!-- TODO @luowenfeng:fourth=》senior 会更好哈 --> | ||
| 169 | - <el-tab-pane label="高级设置" name="fourth"> | ||
| 170 | - <el-form ref="fourth" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> | 166 | + <el-tab-pane label="高级设置" name="senior"> |
| 167 | + <el-form ref="senior" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> | ||
| 171 | <el-form-item label="排序字段"> | 168 | <el-form-item label="排序字段"> |
| 172 | <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> | 169 | <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> |
| 173 | </el-form-item> | 170 | </el-form-item> |
| @@ -208,7 +205,7 @@ export default { | @@ -208,7 +205,7 @@ export default { | ||
| 208 | data() { | 205 | data() { |
| 209 | return { | 206 | return { |
| 210 | specSwitch: false, | 207 | specSwitch: false, |
| 211 | - activeName: "base", | 208 | + activeName: "basic", |
| 212 | propName: { | 209 | propName: { |
| 213 | checkStrictly: true, | 210 | checkStrictly: true, |
| 214 | label: "name", | 211 | label: "name", |
yudao-ui-admin/src/views/system/area/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="app-container"> | ||
| 3 | + | ||
| 4 | + <!-- 操作工具栏 --> | ||
| 5 | + <el-row :gutter="10" class="mb8"> | ||
| 6 | + <el-col :span="1.5"> | ||
| 7 | + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">IP 查询 | ||
| 8 | + </el-button> | ||
| 9 | + </el-col> | ||
| 10 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | ||
| 11 | + </el-row> | ||
| 12 | + | ||
| 13 | + <!-- 列表 --> | ||
| 14 | + <el-table v-if="refreshTable" v-loading="loading" :data="list" row-key="id" | ||
| 15 | + :tree-props="{children: 'children', hasChildren: 'hasChildren'}"> | ||
| 16 | + <el-table-column label="编号" prop="id"/> | ||
| 17 | + <el-table-column label="名字" prop="name"/> | ||
| 18 | + </el-table> | ||
| 19 | + | ||
| 20 | + <!-- 对话框(添加 / 修改) --> | ||
| 21 | + <el-dialog title="IP 查询" :visible.sync="open" width="500px" append-to-body> | ||
| 22 | + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | ||
| 23 | + <el-form-item label="IP" prop="ip"> | ||
| 24 | + <el-input v-model="form.ip" placeholder="请输入 IP 地址"/> | ||
| 25 | + </el-form-item> | ||
| 26 | + <el-form-item label="地址" prop="result"> | ||
| 27 | + <el-input v-model="form.result" readonly placeholder="展示查询 IP 结果" /> | ||
| 28 | + </el-form-item> | ||
| 29 | + </el-form> | ||
| 30 | + <div slot="footer" class="dialog-footer"> | ||
| 31 | + <el-button type="primary" @click="submitForm">查 询</el-button> | ||
| 32 | + <el-button @click="cancel">取 消</el-button> | ||
| 33 | + </div> | ||
| 34 | + </el-dialog> | ||
| 35 | + </div> | ||
| 36 | +</template> | ||
| 37 | + | ||
| 38 | +<script> | ||
| 39 | +import {getAreaByIp, getAreaTree} from "@/api/system/area"; | ||
| 40 | + | ||
| 41 | +export default { | ||
| 42 | + name: "Area", | ||
| 43 | + components: { | ||
| 44 | + }, | ||
| 45 | + data() { | ||
| 46 | + return { | ||
| 47 | + // 遮罩层 | ||
| 48 | + loading: true, | ||
| 49 | + // 显示搜索条件 | ||
| 50 | + showSearch: true, | ||
| 51 | + // 地区列表 | ||
| 52 | + list: [], | ||
| 53 | + // 弹出层标题 | ||
| 54 | + title: "", | ||
| 55 | + // 是否显示弹出层 | ||
| 56 | + open: false, | ||
| 57 | + // 重新渲染表格状态 | ||
| 58 | + refreshTable: true, | ||
| 59 | + // 表单参数 | ||
| 60 | + form: { | ||
| 61 | + ip: undefined, | ||
| 62 | + result: undefined, | ||
| 63 | + }, | ||
| 64 | + // 表单校验 | ||
| 65 | + rules: { | ||
| 66 | + ip: [{required: true, message: "IP 地址不能为控", trigger: "blur"}], | ||
| 67 | + } | ||
| 68 | + }; | ||
| 69 | + }, | ||
| 70 | + created() { | ||
| 71 | + this.getList(); | ||
| 72 | + }, | ||
| 73 | + methods: { | ||
| 74 | + /** 查询列表 */ | ||
| 75 | + getList() { | ||
| 76 | + this.loading = true; | ||
| 77 | + getAreaTree().then(response => { | ||
| 78 | + this.list = response.data; | ||
| 79 | + this.loading = false; | ||
| 80 | + }) | ||
| 81 | + }, | ||
| 82 | + /** 取消按钮 */ | ||
| 83 | + cancel() { | ||
| 84 | + this.open = false; | ||
| 85 | + this.reset(); | ||
| 86 | + }, | ||
| 87 | + /** 表单重置 */ | ||
| 88 | + reset() { | ||
| 89 | + this.form = { | ||
| 90 | + ip: undefined, | ||
| 91 | + result: undefined, | ||
| 92 | + }; | ||
| 93 | + this.resetForm("form"); | ||
| 94 | + }, | ||
| 95 | + /** 新增按钮操作 */ | ||
| 96 | + handleAdd() { | ||
| 97 | + this.reset(); | ||
| 98 | + this.open = true; | ||
| 99 | + }, | ||
| 100 | + /** 提交按钮 */ | ||
| 101 | + submitForm() { | ||
| 102 | + this.$refs["form"].validate(valid => { | ||
| 103 | + if (!valid) { | ||
| 104 | + return; | ||
| 105 | + } | ||
| 106 | + getAreaByIp(this.form.ip).then(response => { | ||
| 107 | + this.$modal.msgSuccess("查询成功"); | ||
| 108 | + this.form.result = response.data | ||
| 109 | + }); | ||
| 110 | + }); | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | +}; | ||
| 114 | +</script> |