From 4a01348e0bf2a7b80cb111afbf246841241d0beb Mon Sep 17 00:00:00 2001 From: wangzhs Date: Wed, 15 Mar 2023 11:36:45 +0800 Subject: [PATCH 001/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E5=88=86=E7=B1=BB]=20=E5=88=97=E8=A1=A8=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E5=A2=9E=E5=8A=A0=20status=E3=80=81parentId?= =?UTF-8?q?=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/category/vo/ProductCategoryListReqVO.java | 6 ++++++ .../dal/mysql/category/ProductCategoryMapper.java | 2 ++ .../category/ProductCategoryServiceImplTest.java | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java index 9c9439d3e..16f5df857 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -10,4 +10,10 @@ public class ProductCategoryListReqVO { @Schema(description = "分类名称", example = "办公文具") private String name; + @Schema(description = "开启状态", example = "0") + private Integer status; + + @Schema(description = "父分类编号", example = "1") + private Long parentId; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java index 8130d5a46..fbb88f592 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java @@ -19,6 +19,8 @@ public interface ProductCategoryMapper extends BaseMapperX { default List selectList(ProductCategoryListReqVO listReqVO) { return selectList(new LambdaQueryWrapperX() .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName()) + .eqIfPresent(ProductCategoryDO::getParentId, listReqVO.getParentId()) + .eqIfPresent(ProductCategoryDO::getStatus, listReqVO.getStatus()) .orderByDesc(ProductCategoryDO::getId)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index a2963d498..0b8cd30bd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.service.category; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; @@ -127,18 +128,28 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { // mock 数据 ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到 o.setName("奥特曼"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setParentId(ProductCategoryDO.PARENT_ID_NULL); }); productCategoryMapper.insert(dbCategory); // 测试 name 不匹配 productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("奥特块"))); + // 测试 status 不匹配 + productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 parentId 不匹配 + productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setParentId(3333L))); // 准备参数 ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO(); reqVO.setName("特曼"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setParentId(ProductCategoryDO.PARENT_ID_NULL); // 调用 List list = productCategoryService.getEnableCategoryList(reqVO); + List all = productCategoryService.getEnableCategoryList(new ProductCategoryListReqVO()); // 断言 assertEquals(1, list.size()); + assertEquals(4, all.size()); assertPojoEquals(dbCategory, list.get(0)); } From b89d7ff3841789f33400e33c448da0951263d244 Mon Sep 17 00:00:00 2001 From: wangzhs Date: Wed, 15 Mar 2023 13:44:13 +0800 Subject: [PATCH 002/232] =?UTF-8?q?[=E4=BF=AE=E6=94=B9][=E5=95=86=E5=93=81?= =?UTF-8?q?=E5=88=86=E7=B1=BB]=201.=20=E5=88=A0=E9=99=A4=20description=20?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E6=8F=8F=E8=BF=B0=E5=AD=97=E6=AE=B5=202.=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9Ebig=5Fpic=5Furl=20PC=E7=AB=AF=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E5=9B=BE=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/category/vo/ProductCategoryBaseVO.java | 6 +++--- .../dal/dataobject/category/ProductCategoryDO.java | 10 +++++----- .../src/test/resources/sql/create_tables.sql | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 5182bdadd..2d38c933d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -28,11 +28,11 @@ public class ProductCategoryBaseVO { @Schema(description = "分类排序", required = true, example = "1") private Integer sort; - @Schema(description = "分类描述", required = true, example = "描述") - private String description; - @Schema(description = "开启状态", required = true, example = "0") @NotNull(message = "开启状态不能为空") private Integer status; + @Schema(description = "PC端分类图") + private String bigPicUrl; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index 93ec925a9..f79e4f1a8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -53,15 +53,15 @@ public class ProductCategoryDO extends BaseDO { * 分类排序 */ private Integer sort; - /** - * 分类描述 - */ - private String description; /** * 开启状态 - * + *

* 枚举 {@link CommonStatusEnum} */ private Integer status; + /** + * PC端分类图 + */ + private String bigPicUrl; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 8f53ba72f..e79e987c6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -56,8 +56,8 @@ CREATE TABLE IF NOT EXISTS `product_category` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', `parent_id` bigint DEFAULT NULL COMMENT '父分类编号', `name` varchar(128) NOT NULL COMMENT '分类名称', - `description` varchar(128) NOT NULL COMMENT '分类描述', `pic_url` varchar DEFAULT NULL COMMENT '分类图片', + `big_pic_url` varchar DEFAULT NULL COMMENT 'PC端分类图', `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', `status` bit(1) DEFAULT NULL COMMENT '状态', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', From 5674bfafc89b3b5247ac3007d49c70b3c35d79fd Mon Sep 17 00:00:00 2001 From: wangzhs Date: Wed, 15 Mar 2023 14:03:00 +0800 Subject: [PATCH 003/232] =?UTF-8?q?[=E4=BF=AE=E6=94=B9][=E5=95=86=E5=93=81?= =?UTF-8?q?=E5=88=86=E7=B1=BB]=E5=88=86=E7=B1=BB=E5=8F=AA=E8=83=BD?= =?UTF-8?q?=E5=AD=98=E5=9C=A82=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/service/category/ProductCategoryServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index f0d10b8b8..21dfb9dee 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -77,7 +77,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { throw exception(CATEGORY_PARENT_NOT_EXISTS); } // 父分类不能是二级分类 - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + if (!Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL); } } From b0c73b786a698fa9db8d2593e3f5bf97c7cc625e Mon Sep 17 00:00:00 2001 From: wangzhs Date: Wed, 15 Mar 2023 14:23:42 +0800 Subject: [PATCH 004/232] =?UTF-8?q?[=E6=B5=8B=E8=AF=95][=E5=95=86=E5=93=81?= =?UTF-8?q?=E5=88=86=E7=B1=BB]=E6=B5=8B=E8=AF=95=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=95=86=E5=93=81=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductCategoryServiceImplTest.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 0b8cd30bd..09c4f7927 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -18,6 +18,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; @@ -38,9 +39,16 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @Test public void testCreateCategory_success() { // 准备参数 - ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); + ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class,o -> { + // 设置PC端图片可为空 + o.setBigPicUrl(null); + }); + // mock 父类 - ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); + ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> { + reqVO.setParentId(o.getId()); + o.setParentId(PARENT_ID_NULL); + }); productCategoryMapper.insert(parentProductCategory); // 调用 @@ -108,7 +116,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { public void testGetCategoryLevel() { // mock 数据 ProductCategoryDO category1 = randomPojo(ProductCategoryDO.class, - o -> o.setParentId(ProductCategoryDO.PARENT_ID_NULL)); + o -> o.setParentId(PARENT_ID_NULL)); productCategoryMapper.insert(category1); ProductCategoryDO category2 = randomPojo(ProductCategoryDO.class, o -> o.setParentId(category1.getId())); @@ -129,7 +137,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到 o.setName("奥特曼"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setParentId(ProductCategoryDO.PARENT_ID_NULL); + o.setParentId(PARENT_ID_NULL); }); productCategoryMapper.insert(dbCategory); // 测试 name 不匹配 @@ -142,7 +150,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO(); reqVO.setName("特曼"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setParentId(ProductCategoryDO.PARENT_ID_NULL); + reqVO.setParentId(PARENT_ID_NULL); // 调用 List list = productCategoryService.getEnableCategoryList(reqVO); From f69d8503a2e17995010c78eceb9bb94e9afe6371 Mon Sep 17 00:00:00 2001 From: wangzhs Date: Sun, 19 Mar 2023 15:47:49 +0800 Subject: [PATCH 005/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=201.=20=E5=AE=9E=E4=BD=93=E7=B1=BB=202.=20h?= =?UTF-8?q?2.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataobject/comment/ProductCommentDO.java | 158 +++++++++++------- .../mysql/comment/ProductCommentMapper.java | 16 ++ .../comment/ProductCommentService.java | 14 ++ .../comment/ProductCommentServiceImpl.java | 9 + .../ProductCommentServiceImplTest.java | 39 +++++ .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 32 ++++ 7 files changed, 211 insertions(+), 58 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index c14808f22..76259aa02 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.product.dal.dataobject.comment; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.comment.ProductCommentAuditStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -18,7 +18,7 @@ import java.util.List; * * @author 芋道源码 */ -@TableName("product_comment") +@TableName(value = "product_comment", autoResultMap = true) @KeySequence("product_comment_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) @@ -33,97 +33,139 @@ public class ProductCommentDO extends BaseDO { */ @TableId private Long id; - /** - * 商品 SPU 编号 - * - * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - /** - * 交易订单编号 - * - * 关联 TradeOrderDO 的 id 编号 - */ - private Long orderId; - /** - * 交易订单项编号 - * - * 关联 TradeOrderItemDO 的 id 编号 - */ - private Long orderItemId; - /** - * 审核状态 - * - * 枚举 {@link ProductCommentAuditStatusEnum} - */ - private Integer auditStatus; /** - * 用户编号 - * + * 评价人 用户编号 + *

* 关联 MemberUserDO 的 id 编号 */ private Long userId; + /** - * 用户 IP + * 评价人名称 */ - private String userIp; + private Long userNickname; + + /** + * 评价人头像 + */ + private Long userAvatar; + /** * 是否匿名 */ private Boolean anonymous; + + /** + * 交易订单编号 + *

+ * 关联 TradeOrderDO 的 id 编号 + */ + private Long orderId; + + /** + * 交易订单项编号 + *

+ * 关联 TradeOrderItemDO 的 id 编号 + */ + private Long orderItemId; + + /** + * 商品 SPU 编号 + *

+ * 关联 {@link ProductSpuDO#getId()} + */ + private Long spuId; + + /** + * 商品 SKU 编号 + *

+ * 关联 {@link ProductSkuDO#getId()} + */ + private Long skuId; + + /** + * 是否可见 + *

+ * 1:显示 0:隐藏 + */ + private Boolean visible; + + /** + * 评分星级 + *

+ * 1-5分 + */ + private Integer scores; + + /** + * 描述星级 + *

+ * 1-5 星 + */ + private Integer descriptionScores; + + /** + * 服务星级 + *

+ * 1-5 星 + */ + private Integer benefitScores; + + /** + * 配送星级 + *

+ * 1-5 星 + */ + private Integer deliveryScores; + /** * 评论内容 */ private String content; + /** * 评论图片地址数组 */ @TableField(typeHandler = JacksonTypeHandler.class) private List picUrls; - /** - * 描述相符星级 - * - * 1-5 星 - */ - private Integer descriptionScore; - /** - * 商品评论星级 - * - * 1-5 星 - */ - private Integer productScore; - /** - * 服务评论星级 - * - * 1-5 星 - */ - private Integer serviceScore; - /** - * 物流评论星级 - * - * 1-5 星 - */ - private Integer expressComment; /** * 商家是否回复 */ private Boolean replied; + + /** + * 回复管理员编号 + *

+ * 关联 AdminUserDO 的 id 编号 + */ + private Long replyUserId; + /** * 商家回复内容 */ private String replyContent; + /** * 商家回复时间 */ private LocalDateTime replyTime; /** - * 有用的计数 - * - * 其他用户看到评论时,可点击「有用」按钮 + * 追加评价内容 */ - private Integer usefulCount; + private String additionalContent; + + /** + * 追评评价图片地址数组 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List additionalPicUrls; + + /** + * 追加评价时间 + */ + private LocalDateTime additionalCreateTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java new file mode 100644 index 000000000..4b44e0ce2 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.product.dal.mysql.comment; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import org.apache.ibatis.annotations.Mapper; + + +/** + * 商品评论 Mapper + * + * @author wangzhs + */ +@Mapper +public interface ProductCommentMapper extends BaseMapperX { +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java new file mode 100644 index 000000000..e89a2de0e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.service.comment; + +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +/** + * 商品评论 Service 接口 + * + * @author wangzhs + */ +@Service +@Validated +public interface ProductCommentService { +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java new file mode 100644 index 000000000..a085a75ce --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.product.service.comment; + +/** + * 商品评论 Service 实现类 + * + * @author wangzhs + */ +public class ProductCommentServiceImpl implements ProductCommentService { +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java new file mode 100644 index 000000000..47a66995e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.product.service.comment; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; + +/** + * {@link ProductCommentServiceImpl} 的单元测试类 + * + * @author wangzhs + */ +@Import(ProductCommentServiceImpl.class) +public class ProductCommentServiceImplTest extends BaseDbUnitTest { + + @Resource + private ProductCommentMapper productCommentMapper; + + @Test + public void testCreateCommentAndGet_success() { + // mock 测试 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class); + productCommentMapper.insert(productComment); + + // 断言 + // 校验记录的属性是否正确 + ProductCommentDO comment = productCommentMapper.selectById(productComment.getId()); + assertPojoEquals(productComment, comment); + } + + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql index 48079766a..4ecb5f34d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql @@ -2,3 +2,4 @@ DELETE FROM "product_sku"; DELETE FROM "product_spu"; DELETE FROM "product_brand"; DELETE FROM "product_category"; +DELETE FROM "product_comment"; diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index e79e987c6..dc9f903f0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -82,3 +82,35 @@ CREATE TABLE IF NOT EXISTS `product_brand` ( `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`) ) COMMENT '商品品牌'; + +CREATE TABLE IF NOT EXISTS `product_comment` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评价编号', + `user_id` bigint NOT NULL COMMENT ' 评价ID 用户编号', + `user_nickname` varchar(128) NOT NULL COMMENT '评价人名称', + `user_avatar` varchar(255) NOT NULL COMMENT '评价人头像', + `anonymous` bit(1) NOT NULL DEFAULT 0 COMMENT '是否匿名 0:不匿名 1:匿名', + `order_id` bigint NOT NULL COMMENT '交易订单编号', + `order_item_id` bigint NOT NULL COMMENT '交易订单项编号', + `spu_id` bigint NOT NULL COMMENT '商品SPU编号', + `sku_id` bigint NOT NULL COMMENT '商品SKU编号', + `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏', + `scores` int NOT NULL COMMENT '评分星级 1-5分', + `description_scores` int NOT NULL COMMENT '描述星级 1-5分', + `benefit_scores` int NOT NULL COMMENT '服务星级 1-5分', + `delivery_scores` int NOT NULL COMMENT '配送星级 1-5分', + `content` varchar(2000) NOT NULL COMMENT '评论内容', + `pic_urls` varchar(1024) DEFAULT '' COMMENT '评论图片地址数组,以逗号分隔最多上传9张', + `replied` bit(1) NOT NULL DEFAULT 0 COMMENT '商家是否回复 1:回复 0:未回复', + `reply_user_id` bigint COMMENT '回复管理员编号', + `reply_content` varchar(2000) COMMENT '商家回复内容', + `reply_time` datetime COMMENT '商家回复时间', + `additional_content` varchar(2000) COMMENT '追加评价内容', + `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张', + `additional_create_time` datetime COMMENT '追加评价时间', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar DEFAULT NULL COMMENT '创建人', + `updater` varchar DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) +) COMMENT '商品评价'; \ No newline at end of file From da53a041daaa9d2a2e2b3b2f70d2733bacdcbf0f Mon Sep 17 00:00:00 2001 From: wangzhs Date: Sun, 19 Mar 2023 18:59:51 +0800 Subject: [PATCH 006/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/ProductCommentScoresEnum.java | 41 +++++++++++++ .../comment/ProductCommentController.http | 0 .../comment/ProductCommentController.java | 40 ++++++++++++ .../comment/vo/ProductCommentBaseVO.java | 60 ++++++++++++++++++ .../comment/vo/ProductCommentCreateReqVO.java | 12 ++++ .../comment/vo/ProductCommentPageReqVO.java | 42 +++++++++++++ .../comment/vo/ProductCommentRespVO.java | 53 ++++++++++++++++ .../comment/ProductCommentConvert.java | 27 ++++++++ .../dataobject/comment/ProductCommentDO.java | 7 ++- .../mysql/comment/ProductCommentMapper.java | 15 +++++ .../comment/ProductCommentService.java | 12 ++++ .../comment/ProductCommentServiceImpl.java | 20 ++++++ .../ProductCommentServiceImplTest.java | 61 ++++++++++++++++++- .../src/test/resources/sql/create_tables.sql | 1 + 14 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentScoresEnum.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.http create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentScoresEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentScoresEnum.java new file mode 100644 index 000000000..a114e1ab8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentScoresEnum.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.product.enums.comment; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 商品评论的星级枚举 + * + * @author wangzhs + */ +@Getter +@AllArgsConstructor +public enum ProductCommentScoresEnum implements IntArrayValuable { + + ONE(1, "1星"), + TWO(2, "2星"), + THREE(3, "3星"), + FOUR(4, "4星"), + FIVE(5, "5星"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentScoresEnum::getScores).toArray(); + + /** + * 星级 + */ + private final Integer scores; + + /** + * 星级名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.http new file mode 100644 index 000000000..e69de29bb diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java new file mode 100644 index 000000000..7cbf3484e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 商品评价") +@RestController +@RequestMapping("/product/comment") +@Validated +public class ProductCommentController { + + @Resource + private ProductCommentService productCommentService; + + @GetMapping("/page") + @Operation(summary = "获得商品评价分页") + @PreAuthorize("@ss.hasPermission('product:comment:query')") + public CommonResult> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { + PageResult pageResult = productCommentService.getCommentPage(pageVO); + return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java new file mode 100644 index 000000000..45abd3adc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class ProductCommentBaseVO { + + @Schema(description = "评价人 用户编号", required = true, example = "15721") + @NotNull(message = "评价人 用户编号不能为空") + private Long userId; + + @Schema(description = "评价人名称", required = true, example = "张三") + @NotNull(message = "评价人名称不能为空") + private String userNickname; + + @Schema(description = "评价人头像", required = true) + @NotNull(message = "评价人头像不能为空") + private String userAvatar; + + @Schema(description = "商品SPU编号", required = true, example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "赵六") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "3082") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "评分星级 1-5分", required = true) + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true) + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true) + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "配送星级 1-5分", required = true) + @NotNull(message = "配送星级 1-5分不能为空") + private Integer deliveryScores; + + @Schema(description = "评论内容", required = true) + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) + @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空") + private List picUrls; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java new file mode 100644 index 000000000..8fd0e7099 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import lombok.*; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "管理后台 - 商品评价创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCommentCreateReqVO extends ProductCommentBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java new file mode 100644 index 000000000..ea364fa0d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 商品评价分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCommentPageReqVO extends PageParam { + + @Schema(description = "评价人名称", example = "王二狗") + private String userNickname; + + @Schema(description = "交易订单编号", example = "24428") + private Long orderId; + + @Schema(description = "商品SPU编号", example = "29502") + private Long spuId; + + @Schema(description = "商品SPU名称", example = "感冒药") + private String spuName; + + @Schema(description = "评分星级 1-5分") + @InEnum(ProductCommentScoresEnum.class) + private Integer scores; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java new file mode 100644 index 000000000..c194f0b03 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 商品评价 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCommentRespVO extends ProductCommentBaseVO { + + @Schema(description = "订单项编号", required = true, example = "24965") + private Long id; + + @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true) + private Boolean anonymous; + + @Schema(description = "交易订单编号", required = true, example = "24428") + private Long orderId; + + @Schema(description = "交易订单项编号", required = true, example = "8233") + private Long orderItemId; + + @Schema(description = "是否可见:[1:显示 0:隐藏]", required = true) + private Boolean visible; + + @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) + private Boolean replied; + + @Schema(description = "回复管理员编号", example = "22212") + private Long replyUserId; + + @Schema(description = "商家回复内容") + private String replyContent; + + @Schema(description = "商家回复时间") + private LocalDateTime replyTime; + + @Schema(description = "追加评价内容") + private String additionalContent; + + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") + private List additionalPicUrls; + + @Schema(description = "追加评价时间") + private LocalDateTime additionalCreateTime; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java new file mode 100644 index 000000000..c9fe64a21 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.convert.comment; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 商品评价 Convert + * + * @author wangzhs + */ +@Mapper +public interface ProductCommentConvert { + + ProductCommentConvert INSTANCE = Mappers.getMapper(ProductCommentConvert.class); + + ProductCommentRespVO convert(ProductCommentDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 76259aa02..0c9d2f844 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -44,7 +44,7 @@ public class ProductCommentDO extends BaseDO { /** * 评价人名称 */ - private Long userNickname; + private String userNickname; /** * 评价人头像 @@ -77,6 +77,11 @@ public class ProductCommentDO extends BaseDO { */ private Long spuId; + /** + * 商品 SPU 名称 + */ + private String spuName; + /** * 商品 SKU 编号 *

diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index 4b44e0ce2..d8c833961 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.product.dal.mysql.comment; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.apache.ibatis.annotations.Mapper; @@ -13,4 +16,16 @@ import org.apache.ibatis.annotations.Mapper; */ @Mapper public interface ProductCommentMapper extends BaseMapperX { + + default PageResult selectPage(ProductCommentPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ProductCommentDO::getUserNickname, reqVO.getUserNickname()) + .eqIfPresent(ProductCommentDO::getOrderId, reqVO.getOrderId()) + .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId()) + .eqIfPresent(ProductCommentDO::getScores, reqVO.getScores()) + .betweenIfPresent(ProductCommentDO::getCreateTime, reqVO.getCreateTime()) + .likeIfPresent(ProductCommentDO::getSpuName, reqVO.getSpuName()) + .orderByDesc(ProductCommentDO::getId)); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index e89a2de0e..4910c3113 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.product.service.comment; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -11,4 +14,13 @@ import org.springframework.validation.annotation.Validated; @Service @Validated public interface ProductCommentService { + + /** + * 获得商品评价分页 + * + * @param pageReqVO 分页查询 + * @return 商品评价分页 + */ + PageResult getCommentPage(ProductCommentPageReqVO pageReqVO); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index a085a75ce..2bd644995 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,9 +1,29 @@ package cn.iocoder.yudao.module.product.service.comment; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + /** * 商品评论 Service 实现类 * * @author wangzhs */ +@Service +@Validated public class ProductCommentServiceImpl implements ProductCommentService { + + @Resource + private ProductCommentMapper productCommentMapper; + + @Override + public PageResult getCommentPage(ProductCommentPageReqVO pageReqVO) { + return productCommentMapper.selectPage(pageReqVO); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 47a66995e..1c8ed2969 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -1,16 +1,25 @@ package cn.iocoder.yudao.module.product.service.comment; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.Date; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * {@link ProductCommentServiceImpl} 的单元测试类 @@ -23,6 +32,17 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { @Resource private ProductCommentMapper productCommentMapper; + @Resource + private ProductCommentServiceImpl productCommentService; + + public String generateNo() { + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); + } + + public Long generateId() { + return RandomUtil.randomLong(100000, 999999); + } + @Test public void testCreateCommentAndGet_success() { // mock 测试 @@ -35,5 +55,44 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertPojoEquals(productComment, comment); } + @Test + public void testGetCommentPage_success() { + // 准备参数 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { + o.setUserNickname("王二狗"); + o.setSpuName("感冒药"); + o.setScores(ProductCommentScoresEnum.FOUR.getScores()); + }); + productCommentMapper.insert(productComment); + + Long orderId = productComment.getOrderId(); + Long spuId = productComment.getSpuId(); + + // 测试 userNickname 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三"))); + // 测试 orderId 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setOrderId(generateId()))); + // 测试 spuId 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuId(generateId()))); + // 测试 spuName 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuName("感康"))); + // 测试 scores 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); + + // 调用 + ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO(); + productCommentPageReqVO.setUserNickname("王二"); + productCommentPageReqVO.setOrderId(orderId); + productCommentPageReqVO.setSpuId(spuId); + productCommentPageReqVO.setSpuName("感冒药"); + productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores()); + + PageResult commentPage = productCommentService.getCommentPage(productCommentPageReqVO); + PageResult result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO)); + assertEquals(result.getTotal(), commentPage.getTotal()); + + PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); + assertEquals(6, all.getTotal()); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index dc9f903f0..2c2145f54 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -92,6 +92,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` ( `order_id` bigint NOT NULL COMMENT '交易订单编号', `order_item_id` bigint NOT NULL COMMENT '交易订单项编号', `spu_id` bigint NOT NULL COMMENT '商品SPU编号', + `spu_name` varchar NOT NULL COMMENT '商品SPU名称', `sku_id` bigint NOT NULL COMMENT '商品SKU编号', `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏', `scores` int NOT NULL COMMENT '评分星级 1-5分', From cbf5ef5953221b9cb2ed04bfd807931a65916a5e Mon Sep 17 00:00:00 2001 From: wangzhs Date: Sun, 19 Mar 2023 22:07:07 +0800 Subject: [PATCH 007/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0=201.=20?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=20/=20=E9=9A=90=E8=97=8F=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=202.=20=E5=95=86=E5=AE=B6=E5=9B=9E=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 3 ++ .../comment/ProductCommentController.java | 23 ++++++++-- .../comment/vo/ProductCommentPageReqVO.java | 3 ++ .../comment/vo/ProductCommentReplyVO.java | 22 +++++++++ .../vo/ProductCommentUpdateVisibleReqVO.java | 22 +++++++++ .../mysql/comment/ProductCommentMapper.java | 20 ++++++++ .../comment/ProductCommentService.java | 17 +++++++ .../comment/ProductCommentServiceImpl.java | 28 +++++++++++ .../ProductCommentServiceImplTest.java | 46 ++++++++++++++++++- 9 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 4adad0afc..df3413986 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -42,4 +42,7 @@ public interface ErrorCodeConstants { ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复"); ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足"); + // ========== 商品 评价 1008007000 ========== + ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在"); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index 7cbf3484e..8970f7860 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.product.controller.admin.comment; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; @@ -11,14 +13,13 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 商品评价") @RestController @@ -37,4 +38,20 @@ public class ProductCommentController { return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); } + @PutMapping("/update/visible") + @Operation(summary = "显示 / 隐藏评论") + @PreAuthorize("@ss.hasPermission('product:comment:update')") + public CommonResult updateCommentVisible(@Valid @RequestBody ProductCommentUpdateVisibleReqVO updateReqVO) { + productCommentService.updateCommentVisible(updateReqVO); + return success(true); + } + + @PutMapping("/reply") + @Operation(summary = "商家回复") + @PreAuthorize("@ss.hasPermission('product:comment:update')") + public CommonResult commentReply(@Valid @RequestBody ProductCommentReplyVO replyVO) { + productCommentService.commentReply(replyVO, getLoginUserId()); + return success(true); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java index ea364fa0d..5a90d1c20 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java @@ -35,6 +35,9 @@ public class ProductCommentPageReqVO extends PageParam { @InEnum(ProductCommentScoresEnum.class) private Integer scores; + @Schema(description = "商家是否回复") + private Boolean replied; + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java new file mode 100644 index 000000000..44101b602 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 商品评价可见修改 Request VO") +@Data +@ToString(callSuper = true) +public class ProductCommentReplyVO { + + @Schema(description = "评价编号", required = true, example = "15721") + @NotNull(message = "评价编号不能为空") + private Long id; + + @Schema(description = "商家回复内容", required = true, example = "谢谢亲") + @NotNull(message = "商家回复内容不能为空") + private String replyContent; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java new file mode 100644 index 000000000..a297d37e1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 商品评价可见修改 Request VO") +@Data +@ToString(callSuper = true) +public class ProductCommentUpdateVisibleReqVO { + + @Schema(description = "评价编号", required = true, example = "15721") + @NotNull(message = "评价编号不能为空") + private Long id; + + @Schema(description = "是否可见 true:显示 false:隐藏", required = true, example = "false") + @NotNull(message = "是否可见不能为空") + private Boolean visible; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index d8c833961..cb384ce5f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -5,9 +5,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; +import java.time.LocalDateTime; + /** * 商品评论 Mapper @@ -28,4 +32,20 @@ public interface ProductCommentMapper extends BaseMapperX { .orderByDesc(ProductCommentDO::getId)); } + default void updateCommentVisible(Long id, Boolean visible) { + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .set(ProductCommentDO::getVisible, visible) + .eq(ProductCommentDO::getId, id); + update(null, lambdaUpdateWrapper); + } + + default void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .set(ProductCommentDO::getReplied, Boolean.TRUE) + .set(ProductCommentDO::getReplyTime, LocalDateTime.now()) + .set(ProductCommentDO::getReplyUserId, loginUserId) + .set(ProductCommentDO::getReplyContent, replyVO.getReplyContent()) + .eq(ProductCommentDO::getId, replyVO.getId()); + update(null, lambdaUpdateWrapper); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 4910c3113..0985e8f76 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -23,4 +25,19 @@ public interface ProductCommentService { */ PageResult getCommentPage(ProductCommentPageReqVO pageReqVO); + /** + * 修改评论是否可见 + * + * @param updateReqVO 修改评论可见 + */ + void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO); + + /** + * 商家回复 + * + * @param replyVO 商家回复 + * @param loginUserId 管理后台商家登陆人ID + */ + void commentReply(ProductCommentReplyVO replyVO, Long loginUserId); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 2bd644995..b03809e3a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import org.springframework.stereotype.Service; @@ -9,6 +11,9 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COMMENT_NOT_EXISTS; + /** * 商品评论 Service 实现类 * @@ -26,4 +31,27 @@ public class ProductCommentServiceImpl implements ProductCommentService { return productCommentMapper.selectPage(pageReqVO); } + @Override + public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { + // 校验评论是否存在 + validateCommentExists(updateReqVO.getId()); + + productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible()); + } + + @Override + public void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { + // 校验评论是否存在 + validateCommentExists(replyVO.getId()); + + productCommentMapper.commentReply(replyVO, loginUserId); + } + + private void validateCommentExists(Long id) { + if (productCommentMapper.selectById(id) == null) { + throw exception(COMMENT_NOT_EXISTS); + } + } + + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 1c8ed2969..c3be206ed 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -5,7 +5,9 @@ import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; @@ -19,7 +21,7 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; /** * {@link ProductCommentServiceImpl} 的单元测试类 @@ -62,6 +64,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setUserNickname("王二狗"); o.setSpuName("感冒药"); o.setScores(ProductCommentScoresEnum.FOUR.getScores()); + o.setReplied(Boolean.TRUE); }); productCommentMapper.insert(productComment); @@ -78,6 +81,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuName("感康"))); // 测试 scores 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); + // 测试 replied 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE))); // 调用 ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO(); @@ -86,13 +91,50 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { productCommentPageReqVO.setSpuId(spuId); productCommentPageReqVO.setSpuName("感冒药"); productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores()); + productCommentPageReqVO.setReplied(Boolean.TRUE); PageResult commentPage = productCommentService.getCommentPage(productCommentPageReqVO); PageResult result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO)); assertEquals(result.getTotal(), commentPage.getTotal()); PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); - assertEquals(6, all.getTotal()); + assertEquals(7, all.getTotal()); } + @Test + public void testUpdateCommentVisible_success() { + // mock 测试 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { + o.setVisible(Boolean.TRUE); + }); + productCommentMapper.insert(productComment); + + Long productCommentId = productComment.getId(); + + ProductCommentUpdateVisibleReqVO updateReqVO = new ProductCommentUpdateVisibleReqVO(); + updateReqVO.setId(productCommentId); + updateReqVO.setVisible(Boolean.FALSE); + productCommentService.updateCommentVisible(updateReqVO); + + ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); + assertFalse(productCommentDO.getVisible()); + } + + + @Test + public void testCommentReply_success() { + // mock 测试 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class); + productCommentMapper.insert(productComment); + + Long productCommentId = productComment.getId(); + + ProductCommentReplyVO replyVO = new ProductCommentReplyVO(); + replyVO.setId(productCommentId); + replyVO.setReplyContent("测试"); + productCommentService.commentReply(replyVO, 1L); + + ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); + assertEquals("测试", productCommentDO.getReplyContent()); + } } From 6fe5f4bc0d369d918bbeb9d453a93edd0c3f7f31 Mon Sep 17 00:00:00 2001 From: wangzhs Date: Tue, 21 Mar 2023 11:09:10 +0800 Subject: [PATCH 008/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0/APP?= =?UTF-8?q?=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 3 + .../yudao-module-product-biz/pom.xml | 6 ++ .../comment/ProductCommentController.java | 13 ++-- .../comment/vo/ProductCommentRespVO.java | 9 ++- .../app/comment/AppCommentController.http | 0 .../app/comment/AppCommentController.java | 63 +++++++++++++++++++ .../comment/vo/AppCommentAdditionalReqVO.java | 27 ++++++++ .../app/comment/vo/AppCommentBaseVO.java | 48 ++++++++++++++ .../app/comment/vo/AppCommentCreateReqVO.java | 28 +++++++++ .../app/comment/vo/AppCommentPageReqVO.java | 21 +++++++ .../app/comment/vo/AppCommentRespVO.java | 63 +++++++++++++++++++ .../comment/ProductCommentConvert.java | 47 ++++++++++++++ .../dataobject/comment/ProductCommentDO.java | 17 +---- .../mysql/comment/ProductCommentMapper.java | 26 ++++++++ .../comment/ProductCommentService.java | 28 +++++++++ .../comment/ProductCommentServiceImpl.java | 48 +++++++++++++- .../ProductCommentServiceImplTest.java | 38 ++++++++++- .../src/test/resources/sql/create_tables.sql | 4 +- 18 files changed, 461 insertions(+), 28 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index df3413986..fe9319dae 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -44,5 +44,8 @@ public interface ErrorCodeConstants { // ========== 商品 评价 1008007000 ========== ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在"); + ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在"); + ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作"); + ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); } diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index e89ed105e..8a06a4cde 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -24,6 +24,12 @@ ${revision} + + cn.iocoder.boot + yudao-module-member-api + ${revision} + + cn.iocoder.boot diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index 8970f7860..9a49cbba0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.comment; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; @@ -54,4 +51,12 @@ public class ProductCommentController { return success(true); } + @PutMapping("/create") + @Operation(summary = "添加自评") + @PreAuthorize("@ss.hasPermission('product:comment:update')") + public CommonResult createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) { + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE); + return success(true); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index c194f0b03..b934c1bf3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + import java.time.LocalDateTime; import java.util.List; @@ -23,7 +26,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "交易订单项编号", required = true, example = "8233") private Long orderItemId; - @Schema(description = "是否可见:[1:显示 0:隐藏]", required = true) + @Schema(description = "是否可见:[true:显示 false:隐藏]", required = true) private Boolean visible; @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) @@ -45,7 +48,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { private List additionalPicUrls; @Schema(description = "追加评价时间") - private LocalDateTime additionalCreateTime; + private LocalDateTime additionalTime; @Schema(description = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http new file mode 100644 index 000000000..e69de29bb diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java new file mode 100644 index 000000000..9e5e64550 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.controller.app.comment; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 APP - 商品评价") +@RestController +@RequestMapping("/product/comment") +@Validated +public class AppCommentController { + + @Resource + private ProductCommentService productCommentService; + + @Resource + private MemberUserApi memberUserApi; + + @GetMapping("/page") + @Operation(summary = "获得商品评价分页") + public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { + PageResult pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE); + return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult)); + } + + @PostMapping(value = "/create") + @Operation(summary = "创建商品评价") + public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { + // 查询会员 todo@艿艿 获取用户头像 + // TODO: 2023/3/20 要不要判断订单、商品是否存在 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); + return success(true); + } + + @PostMapping(value = "/additional") + @Operation(summary = "追加评论") + public CommonResult additionalComment(@RequestBody AppCommentAdditionalReqVO createReqVO) { + // 查询会员 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); + productCommentService.additionalComment(user, createReqVO); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java new file mode 100644 index 000000000..2b10b85a2 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "用户APP - 商品追加评价创建 Request VO") +@Data +@ToString(callSuper = true) +public class AppCommentAdditionalReqVO { + + @Schema(description = "评论编号", required = true) + @NotNull(message = "评论编号不能为空") + private Long id; + + @Schema(description = "追加评价内容", required = true) + @NotNull(message = "追加评价内容不能为空") + private String additionalContent; + + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", required = true) + @NotNull(message = "追评评价图片地址数组,以逗号分隔最多上传9张不能为空") + private List additionalPicUrls; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java new file mode 100644 index 000000000..49803c4b1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class AppCommentBaseVO { + + @Schema(description = "商品SPU编号", required = true, example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "赵六") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "3082") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "评分星级 1-5分", required = true) + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true) + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true) + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "配送星级 1-5分", required = true) + @NotNull(message = "配送星级 1-5分不能为空") + private Integer deliveryScores; + + @Schema(description = "评论内容", required = true) + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) + @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空") + private List picUrls; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java new file mode 100644 index 000000000..9bfdf52c0 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户APP - 商品评价创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentCreateReqVO extends AppCommentBaseVO { + + @Schema(description = "是否匿名 true:是 false:否", required = true, example = "true") + @NotNull(message = "是否匿名不能为空") + private Boolean anonymous; + + @Schema(description = "交易订单编号", required = true, example = "12312") + @NotNull(message = "交易订单编号不能为空") + private Long orderId; + + @Schema(description = "交易订单项编号", required = true, example = "2312312") + @NotNull(message = "交易订单项编号不能为空") + private Long orderItemId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java new file mode 100644 index 000000000..f557d7779 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户APP - 商品评价分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentPageReqVO extends PageParam { + + @Schema(description = "商品SPU编号", example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java new file mode 100644 index 000000000..43aeb2355 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "用户APP - 商品评价 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentRespVO extends AppCommentBaseVO { + + @Schema(description = "评价人 用户编号", required = true, example = "15721") + private Long userId; + + @Schema(description = "评价人名称", required = true, example = "张三") + private String userNickname; + + @Schema(description = "评价人头像", required = true) + private String userAvatar; + + @Schema(description = "订单项编号", required = true, example = "24965") + private Long id; + + @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true) + private Boolean anonymous; + + @Schema(description = "交易订单编号", required = true, example = "24428") + private Long orderId; + + @Schema(description = "交易订单项编号", required = true, example = "8233") + private Long orderItemId; + + @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) + private Boolean replied; + + @Schema(description = "回复管理员编号", example = "22212") + private Long replyUserId; + + @Schema(description = "商家回复内容") + private String replyContent; + + @Schema(description = "商家回复时间") + private LocalDateTime replyTime; + + @Schema(description = "追加评价内容") + private String additionalContent; + + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") + private List additionalPicUrls; + + @Schema(description = "追加评价时间") + private LocalDateTime additionalTime; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index c9fe64a21..dd88fadcd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.product.convert.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -24,4 +28,47 @@ public interface ProductCommentConvert { PageResult convertPage(PageResult page); + PageResult convertPage02(PageResult pageResult); + + default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) { + ProductCommentDO productComment = new ProductCommentDO(); + productComment.setUserId(user.getId()); + productComment.setUserNickname(user.getNickname()); +// productComment.setUserAvatar(); + productComment.setAnonymous(createReqVO.getAnonymous()); + productComment.setOrderId(createReqVO.getOrderId()); + productComment.setOrderItemId(createReqVO.getOrderItemId()); + productComment.setSpuId(createReqVO.getSpuId()); + productComment.setSpuName(createReqVO.getSpuName()); + productComment.setSkuId(createReqVO.getSkuId()); + productComment.setScores(createReqVO.getScores()); + productComment.setDescriptionScores(createReqVO.getDescriptionScores()); + productComment.setBenefitScores(createReqVO.getBenefitScores()); + productComment.setDeliveryScores(createReqVO.getDeliveryScores()); + productComment.setContent(createReqVO.getContent()); + productComment.setPicUrls(createReqVO.getPicUrls()); + return productComment; + } + + default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { + ProductCommentDO productComment = new ProductCommentDO(); + productComment.setUserId(createReq.getUserId()); + productComment.setUserNickname(createReq.getUserNickname()); + productComment.setUserAvatar(createReq.getUserAvatar()); + productComment.setAnonymous(Boolean.FALSE); + // TODO: 2023/3/21 自评订单ID来源 + productComment.setOrderId(0L); + productComment.setOrderItemId(0L); + productComment.setSpuId(createReq.getSpuId()); + productComment.setSpuName(createReq.getSpuName()); + productComment.setSkuId(createReq.getSkuId()); + productComment.setScores(createReq.getScores()); + productComment.setDescriptionScores(createReq.getDescriptionScores()); + productComment.setBenefitScores(createReq.getBenefitScores()); + productComment.setDeliveryScores(createReq.getDeliveryScores()); + productComment.setContent(createReq.getContent()); + productComment.setPicUrls(createReq.getPicUrls()); + return productComment; + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 0c9d2f844..6e0bd04fa 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -36,7 +36,6 @@ public class ProductCommentDO extends BaseDO { /** * 评价人 用户编号 - *

* 关联 MemberUserDO 的 id 编号 */ private Long userId; @@ -49,7 +48,7 @@ public class ProductCommentDO extends BaseDO { /** * 评价人头像 */ - private Long userAvatar; + private String userAvatar; /** * 是否匿名 @@ -58,21 +57,18 @@ public class ProductCommentDO extends BaseDO { /** * 交易订单编号 - *

* 关联 TradeOrderDO 的 id 编号 */ private Long orderId; /** * 交易订单项编号 - *

* 关联 TradeOrderItemDO 的 id 编号 */ private Long orderItemId; /** * 商品 SPU 编号 - *

* 关联 {@link ProductSpuDO#getId()} */ private Long spuId; @@ -84,42 +80,36 @@ public class ProductCommentDO extends BaseDO { /** * 商品 SKU 编号 - *

* 关联 {@link ProductSkuDO#getId()} */ private Long skuId; /** * 是否可见 - *

- * 1:显示 0:隐藏 + * true:显示 false:隐藏 */ private Boolean visible; /** * 评分星级 - *

* 1-5分 */ private Integer scores; /** * 描述星级 - *

* 1-5 星 */ private Integer descriptionScores; /** * 服务星级 - *

* 1-5 星 */ private Integer benefitScores; /** * 配送星级 - *

* 1-5 星 */ private Integer deliveryScores; @@ -142,7 +132,6 @@ public class ProductCommentDO extends BaseDO { /** * 回复管理员编号 - *

* 关联 AdminUserDO 的 id 编号 */ private Long replyUserId; @@ -171,6 +160,6 @@ public class ProductCommentDO extends BaseDO { /** * 追加评价时间 */ - private LocalDateTime additionalCreateTime; + private LocalDateTime additionalTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index cb384ce5f..e378f53ce 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -32,6 +34,13 @@ public interface ProductCommentMapper extends BaseMapperX { .orderByDesc(ProductCommentDO::getId)); } + default PageResult selectPage(AppCommentPageReqVO reqVO, Boolean visible) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId()) + .eqIfPresent(ProductCommentDO::getVisible, visible) + .orderByDesc(ProductCommentDO::getId)); + } + default void updateCommentVisible(Long id, Boolean visible) { LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() .set(ProductCommentDO::getVisible, visible) @@ -48,4 +57,21 @@ public interface ProductCommentMapper extends BaseMapperX { .eq(ProductCommentDO::getId, replyVO.getId()); update(null, lambdaUpdateWrapper); } + + default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { + return selectOne(new LambdaQueryWrapperX() + .eq(ProductCommentDO::getUserId, userId) + .eq(ProductCommentDO::getOrderId, orderId) + .eq(ProductCommentDO::getSpuId, spuId)); + } + + default void additionalComment(AppCommentAdditionalReqVO createReqVO) { + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .set(ProductCommentDO::getAdditionalTime, LocalDateTime.now()) + .set(ProductCommentDO::getAdditionalPicUrls, createReqVO.getAdditionalPicUrls(), "javaType=List,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler") + .set(ProductCommentDO::getAdditionalContent, createReqVO.getAdditionalContent()) + .eq(ProductCommentDO::getId, createReqVO.getId()); + update(null, lambdaUpdateWrapper); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 0985e8f76..6f5e1b59f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -40,4 +43,29 @@ public interface ProductCommentService { */ void commentReply(ProductCommentReplyVO replyVO, Long loginUserId); + /** + * 获得商品评价分页 + * + * @param pageVO 分页查询 + * @param visible 是否可见 + * @return 商品评价分页 + */ + PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); + + /** + * 创建商品评论 + * + * @param productComment 创建实体 + * @param system 是否系统评价 + */ + void createComment(ProductCommentDO productComment, Boolean system); + + /** + * 追加商品评论 + * + * @param user 用户相关信息 + * @param createReqVO 创建实体 + */ + void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index b03809e3a..2fe331d59 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,18 +1,23 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COMMENT_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; /** * 商品评论 Service 实现类 @@ -47,10 +52,47 @@ public class ProductCommentServiceImpl implements ProductCommentService { productCommentMapper.commentReply(replyVO, loginUserId); } - private void validateCommentExists(Long id) { - if (productCommentMapper.selectById(id) == null) { + @Override + public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { + return productCommentMapper.selectPage(pageVO, visible); + } + + @Override + public void createComment(ProductCommentDO productComment, Boolean system) { + if (!system) { + // 判断当前订单的当前商品用户是否评价过 + ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId()); + if (null != exist) { + throw exception(ORDER_SPU_COMMENT_EXISTS); + } + } + productCommentMapper.insert(productComment); + } + + @Override + public void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO) { + // 校验评论是否存在 + ProductCommentDO productComment = validateCommentExists(createReqVO.getId()); + + // 判断是否是同一用户追加评论 + if (!Objects.equals(productComment.getUserId(), user.getId())) { + throw exception(COMMENT_ERROR_OPT); + } + + // 判断是否已经追加评论过了 + if (StringUtils.hasText(productComment.getAdditionalContent())) { + throw exception(COMMENT_ADDITIONAL_EXISTS); + } + + productCommentMapper.additionalComment(createReqVO); + } + + private ProductCommentDO validateCommentExists(Long id) { + ProductCommentDO productComment = productCommentMapper.selectById(id); + if (productComment == null) { throw exception(COMMENT_NOT_EXISTS); } + return productComment; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index c3be206ed..af1d529d8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -4,10 +4,13 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; @@ -21,7 +24,8 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * {@link ProductCommentServiceImpl} 的单元测试类 @@ -65,6 +69,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setSpuName("感冒药"); o.setScores(ProductCommentScoresEnum.FOUR.getScores()); o.setReplied(Boolean.TRUE); + o.setVisible(Boolean.TRUE); }); productCommentMapper.insert(productComment); @@ -83,6 +88,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); // 测试 replied 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE))); + // 测试 visible 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE))); // 调用 ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO(); @@ -98,7 +105,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals(result.getTotal(), commentPage.getTotal()); PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); - assertEquals(7, all.getTotal()); + assertEquals(8, all.getTotal()); + + PageResult visible = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); + assertEquals(7, visible.getTotal()); } @Test @@ -137,4 +147,28 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); assertEquals("测试", productCommentDO.getReplyContent()); } + + @Test + public void testCreateComment_success() { + // mock 测试 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { + o.setAdditionalContent(""); + }); + + productCommentService.createComment(productComment, Boolean.TRUE); + + MemberUserRespDTO user = new MemberUserRespDTO(); + user.setId(productComment.getUserId()); + + AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO(); + createReqVO.setId(productComment.getId()); + createReqVO.setAdditionalContent("追加"); + createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls()); + + productCommentService.additionalComment(user, createReqVO); + ProductCommentDO exist = productCommentMapper.selectById(productComment.getId()); + + assertEquals("追加", exist.getAdditionalContent()); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 2c2145f54..512175a9d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` ( `spu_id` bigint NOT NULL COMMENT '商品SPU编号', `spu_name` varchar NOT NULL COMMENT '商品SPU名称', `sku_id` bigint NOT NULL COMMENT '商品SKU编号', - `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏', + `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 true:显示 false:隐藏', `scores` int NOT NULL COMMENT '评分星级 1-5分', `description_scores` int NOT NULL COMMENT '描述星级 1-5分', `benefit_scores` int NOT NULL COMMENT '服务星级 1-5分', @@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` ( `reply_time` datetime COMMENT '商家回复时间', `additional_content` varchar(2000) COMMENT '追加评价内容', `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张', - `additional_create_time` datetime COMMENT '追加评价时间', + `additional_time` datetime COMMENT '追加评价时间', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `creator` varchar DEFAULT NULL COMMENT '创建人', From 38d7d75f7f13edba2ad169fad6abaf56e870a5f9 Mon Sep 17 00:00:00 2001 From: wangzhs Date: Thu, 23 Mar 2023 14:06:14 +0800 Subject: [PATCH 009/232] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0/APP?= =?UTF-8?q?=E7=AB=AF=201.=20=E5=A2=9E=E5=8A=A0=E5=A4=B4=E5=83=8F=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=AD=97=E6=AE=B5=202.=20=E8=B0=83=E6=95=B4=E5=95=86?= =?UTF-8?q?=E6=88=B7=E8=87=AA=E8=AF=84userId=203.=20=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E5=9B=BE=E7=89=87=E6=95=B0=E9=87=8F=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/comment/vo/ProductCommentBaseVO.java | 7 ++----- .../controller/admin/comment/vo/ProductCommentRespVO.java | 5 ++++- .../controller/app/comment/AppCommentController.java | 1 - .../app/comment/vo/AppCommentAdditionalReqVO.java | 3 ++- .../controller/app/comment/vo/AppCommentBaseVO.java | 3 ++- .../product/convert/comment/ProductCommentConvert.java | 5 ++--- .../module/member/api/user/dto/MemberUserRespDTO.java | 5 ++++- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java index 45abd3adc..19dae8777 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java @@ -4,15 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.util.List; @Data public class ProductCommentBaseVO { - @Schema(description = "评价人 用户编号", required = true, example = "15721") - @NotNull(message = "评价人 用户编号不能为空") - private Long userId; - @Schema(description = "评价人名称", required = true, example = "张三") @NotNull(message = "评价人名称不能为空") private String userNickname; @@ -54,7 +51,7 @@ public class ProductCommentBaseVO { private String content; @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) - @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空") + @Size(max = 9, message = "评论图片地址数组长度不能超过9张") private List picUrls; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index b934c1bf3..8568b4f8c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -17,12 +17,15 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "订单项编号", required = true, example = "24965") private Long id; - @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true) + @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true) private Boolean anonymous; @Schema(description = "交易订单编号", required = true, example = "24428") private Long orderId; + @Schema(description = "评价人 用户编号", required = true, example = "15721") + private Long userId; + @Schema(description = "交易订单项编号", required = true, example = "8233") private Long orderItemId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java index 9e5e64550..a5621c57a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -44,7 +44,6 @@ public class AppCommentController { @PostMapping(value = "/create") @Operation(summary = "创建商品评价") public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { - // 查询会员 todo@艿艿 获取用户头像 // TODO: 2023/3/20 要不要判断订单、商品是否存在 MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java index 2b10b85a2..b989a867d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java @@ -5,6 +5,7 @@ import lombok.Data; import lombok.ToString; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.util.List; @Schema(description = "用户APP - 商品追加评价创建 Request VO") @@ -21,7 +22,7 @@ public class AppCommentAdditionalReqVO { private String additionalContent; @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", required = true) - @NotNull(message = "追评评价图片地址数组,以逗号分隔最多上传9张不能为空") + @Size(max = 9, message = "追评评价图片地址数组长度不能超过9张") private List additionalPicUrls; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java index 49803c4b1..59716b5a6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.util.List; @Data @@ -42,7 +43,7 @@ public class AppCommentBaseVO { private String content; @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) - @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空") + @Size(max = 9, message = "评论图片地址数组长度不能超过9张") private List picUrls; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index dd88fadcd..a0f5b154d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -34,7 +34,7 @@ public interface ProductCommentConvert { ProductCommentDO productComment = new ProductCommentDO(); productComment.setUserId(user.getId()); productComment.setUserNickname(user.getNickname()); -// productComment.setUserAvatar(); + productComment.setUserAvatar(user.getAvatar()); productComment.setAnonymous(createReqVO.getAnonymous()); productComment.setOrderId(createReqVO.getOrderId()); productComment.setOrderItemId(createReqVO.getOrderItemId()); @@ -52,11 +52,10 @@ public interface ProductCommentConvert { default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { ProductCommentDO productComment = new ProductCommentDO(); - productComment.setUserId(createReq.getUserId()); + productComment.setUserId(0L); productComment.setUserNickname(createReq.getUserNickname()); productComment.setUserAvatar(createReq.getUserAvatar()); productComment.setAnonymous(Boolean.FALSE); - // TODO: 2023/3/21 自评订单ID来源 productComment.setOrderId(0L); productComment.setOrderItemId(0L); productComment.setSpuId(createReq.getSpuId()); diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java index 7b2bac0c9..10d96365f 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java @@ -25,7 +25,10 @@ public class MemberUserRespDTO { * 枚举 {@link CommonStatusEnum} */ private Integer status; - + /** + * 用户头像 + */ + private String avatar; /** * 手机 */ From b30fc2802154694a03da29afe41336db9f20c919 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 19 Apr 2023 10:55:43 +0800 Subject: [PATCH 010/232] =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9Aproduct?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=20ProductSpuDO=20=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../enums/spu/ProductSpuSpecTypeEnum.java | 1 + .../dataobject/group/ProductGroupBindDO.java | 43 ----- .../dal/dataobject/group/ProductGroupDO.java | 63 ------ .../dataobject/search/ProductHotSearchDO.java | 38 ---- .../product/dal/dataobject/shop/ShopDO.java | 26 --- .../dal/dataobject/spu/ProductSpuDO.java | 179 +++++++++--------- .../spu/ProductSpuServiceImplTest.java | 4 +- yudao-server/pom.xml | 40 ++-- 9 files changed, 110 insertions(+), 286 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java diff --git a/pom.xml b/pom.xml index 2a4ec36e1..0cee86d68 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - + yudao-module-mall yudao-example diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java index fbc227b53..af455bece 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java @@ -13,6 +13,7 @@ import java.util.Arrays; */ @Getter @AllArgsConstructor +@Deprecated public enum ProductSpuSpecTypeEnum implements IntArrayValuable { RECYCLE(1, "统一规格"), diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java deleted file mode 100644 index 2e3b63e59..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.group; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品分组的绑定 DO - * - * @author 芋道源码 - */ -@TableName("product_group_bind") -@KeySequence("product_group_bind_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductGroupBindDO extends BaseDO { - - /** - * 编号,自增 - */ - @TableId - private Long id; - /** - * 商品分组编号 - * - * 关联 {@link ProductGroupDO#getId()} - */ - private Long groupId; - /** - * 商品 SPU 编号 - * - * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java deleted file mode 100644 index 605e8c38a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java +++ /dev/null @@ -1,63 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.group; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品分组 DO - * - * @author 芋道源码 - */ -@TableName("product_group") -@KeySequence("product_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductGroupDO extends BaseDO { - - /** - * 商品分组编号,自增 - */ - @TableId - private Long id; - /** - * 分组名称 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 商品数量 - */ - private Integer count; - /** - * 排序 - */ - private Integer sort; - /** - * 风格,用于 APP 首页展示商品的样式 - * - * 枚举 {@link ProductGroupStyleEnum} - */ - private Integer style; - /** - * 是否默认 - * - * true - 系统默认,不允许删除 - * false - 自定义,允许删除 - */ - private Boolean defaulted; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java deleted file mode 100644 index 3d5cf9101..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.search; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品热搜关键字 DO - * - * @author 芋道源码 - */ -@TableName("product_hot_search") -@KeySequence("product_hot_search_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductHotSearchDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - /** - * 关键字 - */ - private String name; - /** - * 内容 - */ - private String content; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java deleted file mode 100644 index 1c702da91..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.shop; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -// TODO 芋艿:待设计 -/** - * 店铺 DO - * - * @author 芋道源码 - */ -@TableName("shop") -@KeySequence("shop_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ShopDO extends BaseDO { - - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 93c47d4af..6084849c9 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.spu; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; @@ -43,17 +44,22 @@ public class ProductSpuDO extends BaseDO { */ private String name; /** - * 商品编码 + * 关键字 */ - private String code; + private String keyword; /** - * 促销语 + * 商品简介 */ - private String sellPoint; + private String introduction; /** * 商品详情 */ private String description; + /** + * 商品条码(一维码) + */ + private String barCode; + /** * 商品分类编号 * @@ -67,19 +73,23 @@ public class ProductSpuDO extends BaseDO { */ private Long brandId; /** - * 商品图片的数组 - * - * 1. 第一张图片将作为商品主图,支持同时上传多张图; - * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; - * 3. 至少 1 张,最多上传 10 张 + * 商品封面图 + */ + private String picUrl; + /** + * 商品轮播图 */ @TableField(typeHandler = JacksonTypeHandler.class) - private List picUrls; + private List sliderPicUrls; /** * 商品视频 */ private String videoUrl; + /** + * 单位名 + */ + private String unitName; /** * 排序字段 */ @@ -96,37 +106,86 @@ public class ProductSpuDO extends BaseDO { /** * 规格类型 * - * 枚举 {@link ProductSpuSpecTypeEnum} + * false - 单规格 + * true - 多规格 */ - private Integer specType; + private Boolean specType; /** - * 最小价格,单位使用:分 + * 商品价格,单位使用:分 * * 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值 */ - private Integer minPrice; - /** - * 最大价格,单位使用:分 - * - * 基于其对应的 {@link ProductSkuDO#getPrice()} 最大值 - */ - private Integer maxPrice; + private Integer price; /** * 市场价,单位使用:分 * - * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值 + * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值 TODO 芋艿:待确定最大还是最小 */ private Integer marketPrice; /** - * 总库存 + * 成本价,单位使用:分 + * + * 基于其对应的 {@link ProductSkuDO#getCostPrice()} 最大值 TODO 芋艿:待确定最大还是最小 + */ + private Integer costPrice; + /** + * 库存 * * 基于其对应的 {@link ProductSkuDO#getStock()} 求和 */ - private Integer totalStock; + private Integer stock; + + // ========== 物流相关字段 ========= + /** - * 是否展示库存 + * 物流配置模板编号 + * + * 关联 {@link DeliveryTemplateDO#getId()} */ - private Boolean showStock; + private Long deliveryTemplateId; + + // ========== 营销相关字段 ========= + /** + * 是否热卖推荐 + */ + private Boolean recommendHot; + /** + * 是否优惠推荐 + */ + private Boolean recommendBenefit; + /** + * 是否精品推荐 + */ + private Boolean recommendBest; + /** + * 是否新品推荐 + */ + private Boolean recommendNew; + /** + * 是否优品推荐 + */ + private Boolean recommendGood; + + /** + * 赠送积分 + */ + private Integer giveIntegral; + + /** + * 分销类型 + * + * false - 默认 + * true - 自行设置 + */ + private Boolean subCommissionType; + + /** + * 活动展示顺序 + * + * 对应 PromotionTypeEnum 枚举 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List activityOrders; // ========== 统计相关字段 ========= @@ -139,74 +198,8 @@ public class ProductSpuDO extends BaseDO { */ private Integer virtualSalesCount; /** - * 商品点击量 + * 浏览量 */ - private Integer clickCount; - - // ========== 物流相关字段 ========= - - // TODO 芋艿:稍后完善物流的字段 -// /** -// * 配送方式 -// * -// * 枚举 {@link DeliveryModeEnum} -// */ -// private Integer deliveryMode; -// /** -// * 配置模板编号 -// * -// * 关联 {@link DeliveryTemplateDO#getId()} -// */ -// private Long deliveryTemplateId; - - // TODO ========== 待定字段:yv ========= - // TODO vip_price 会员价格 - // TODO postage 邮费 - // TODO is_postage 是否包邮 - // TODO unit_name 单位 - // TODO is_new 商户是否代理 - // TODO give_integral 获得积分 - // TODO is_integral 是开启积分兑换 - // TODO integral 所需积分 - // TODO is_seckill 秒杀状态 - // TODO is_bargain 砍价状态 - // TODO code_path 产品二维码地址 - // TODO is_sub 是否分佣 - - // TODO ↓↓ 芋艿 ↓↓ 看起来走分组更合适? - // TODO is_hot 是否热卖 - // TODO is_benefit 是否优惠 - // TODO is_best 是否精品 - // TODO is_new 是否新品 - // TODO is_good 是否优品推荐 - - // TODO ========== 待定字段:cf ========= - // TODO source_link 淘宝京东1688类型 - // TODO activity 活动显示排序 0=默认 1=秒 2=砍价 3=拼团 - - // TODO ========== 待定字段:lf ========= - - // TODO free_shipping_type:运费类型:1-包邮;2-统一运费;3-运费模板 - // TODO free_shipping:统一运费金额 - // TODO free_shipping_template_id:运费模板 - // TODO is_commission:分销佣金:1-开启;0-不开启;first_ratio second_ratio three_ratio - // TODO is_share_bouns:区域股东分红:1-开启;0-不开启;region_ratio;shareholder_ratio - - // TODO is_new:新品推荐:1-是;0-否 - // TODO is_best:好物优选:1-是;0-否 - // TODO is_like:猜你喜欢:1-是;0-否 - - // TODO is_team:是否开启拼团[0=否, 1=是] - // TODO is_integral:积分抵扣:1-开启;0-不开启 - // TODO is_member:会员价:1-开启;0-不开启 - // TODO give_integral_type:赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分 - // TODO give_integral:赠送积分; - - // TODO poster:商品自定义海报 - - // TODO ========== 待定字段:laoji ========= - // TODO productType 1 - 普通商品 2 - 预售商品;可能和 type 合并不错 - // TODO productUnit 商品单位 - // TODO extJson 扩展信息;例如说,预售商品的信息 + private Integer browseCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 1e029570c..fbd50cad7 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -203,7 +203,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { o.setClickCount(100); o.setCode(code); o.setDescription("测试商品"); - o.setPicUrls(new ArrayList<>()); + o.setSliderPicUrls(new ArrayList<>()); o.setName("测试"); o.setSalesCount(100); o.setSellPoint("超级加倍"); @@ -251,7 +251,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { o.setClickCount(1); o.setCode(generateNo()); o.setDescription("测试商品"); - o.setPicUrls(new ArrayList<>()); + o.setSliderPicUrls(new ArrayList<>()); o.setName("测试"); o.setSalesCount(1); o.setSellPoint("卖点"); diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 52de36fc0..30df27750 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -54,11 +54,11 @@ - - - - - + + cn.iocoder.boot + yudao-module-pay-biz + ${revision} + @@ -68,21 +68,21 @@ - - - - - - - - - - - - - - - + + cn.iocoder.boot + yudao-module-promotion-biz + ${revision} + + + cn.iocoder.boot + yudao-module-product-biz + ${revision} + + + cn.iocoder.boot + yudao-module-trade-biz + ${revision} + From 63542b4ccbadd1a119169005eced042dcab0554a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 19 Apr 2023 16:30:57 +0800 Subject: [PATCH 011/232] =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9Aproduct?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=20ProductSkuDO=20=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/dataobject/sku/ProductSkuDO.java | 54 +++++++++++-------- .../dal/dataobject/spu/ProductSpuDO.java | 8 ++- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 3836f20e5..a9488563a 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.dal.dataobject.sku; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; @@ -37,23 +36,17 @@ public class ProductSkuDO extends BaseDO { private Long id; /** * SPU 编号 - *

+ * * 关联 {@link ProductSpuDO#getId()} */ private Long spuId; - /** - * SPU 名字 - * - * 冗余 {@link ProductSkuDO#getSpuName()} - */ - private String spuName; /** * 属性数组,JSON 格式 */ @TableField(typeHandler = PropertyTypeHandler.class) private List properties; /** - * 销售价格,单位:分 + * 商品价格,单位:分 */ private Integer price; /** @@ -65,27 +58,17 @@ public class ProductSkuDO extends BaseDO { */ private Integer costPrice; /** - * SKU 的条形码 + * 商品条码 */ private String barCode; /** * 图片地址 */ private String picUrl; - /** - * SKU 状态 - *

- * 枚举 {@link CommonStatusEnum} - */ - private Integer status; /** * 库存 */ private Integer stock; - /** - * 预警预存 - */ - private Integer warnStock; /** * 商品重量,单位:kg 千克 */ @@ -95,6 +78,23 @@ public class ProductSkuDO extends BaseDO { */ private Double volume; + /** + * 一级分销的佣金,单位:分 + */ + private Integer subCommissionFirstPrice; + /** + * 二级分销的佣金,单位:分 + */ + private Integer subCommissionSecondPrice; + + // ========== 营销相关字段 ========= + + // ========== 统计相关字段 ========= + /** + * 商品销量 + */ + private Integer salesCount; + /** * 商品属性 */ @@ -105,13 +105,13 @@ public class ProductSkuDO extends BaseDO { /** * 属性编号 - *

+ * * 关联 {@link ProductPropertyDO#getId()} */ private Long propertyId; /** * 属性值编号 - *

+ * * 关联 {@link ProductPropertyValueDO#getId()} */ private Long valueId; @@ -133,5 +133,15 @@ public class ProductSkuDO extends BaseDO { } + // TODO 芋艿:integral from y + // TODO 芋艿:pinkPrice from y + // TODO 芋艿:seckillPrice from y + // TODO 芋艿:pinkStock from y + // TODO 芋艿:seckillStock from y + + // TODO 芋艿:quota from c + // TODO 芋艿:quotaShow from c + // TODO 芋艿:attrValue from c + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 6084849c9..31ef0784f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -170,6 +170,13 @@ public class ProductSpuDO extends BaseDO { * 赠送积分 */ private Integer giveIntegral; + /** + * 赠送的优惠劵编号的数组 + * + * 对应 CouponTemplateDO 的 id 属性 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List giveCouponTemplateIds; /** * 分销类型 @@ -201,5 +208,4 @@ public class ProductSpuDO extends BaseDO { * 浏览量 */ private Integer browseCount; - } From 32da5aae84109284599a406ffa88baff148835c2 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 19 Apr 2023 18:07:22 +0800 Subject: [PATCH 012/232] =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9Aproduct?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=20ProductSpuDO=20=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/product/dal/dataobject/spu/ProductSpuDO.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 31ef0784f..df935d74d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -55,6 +55,7 @@ public class ProductSpuDO extends BaseDO { * 商品详情 */ private String description; + // TODO @芋艿:是不是要删除 /** * 商品条码(一维码) */ @@ -87,9 +88,11 @@ public class ProductSpuDO extends BaseDO { private String videoUrl; /** - * 单位名 + * 单位 + * + * 对应 product_unit 数据字典 */ - private String unitName; + private Integer unit; /** * 排序字段 */ From 6786aa352bc6b8801f5b5829340a206ab356629e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 24 Apr 2023 10:29:02 +0800 Subject: [PATCH 013/232] =?UTF-8?q?=E4=BF=AE=E6=AD=A3DO=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E8=A1=A8=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?VO=E5=AF=B9=E9=BD=90=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/category/vo/ProductCategoryBaseVO.java | 4 ++-- .../admin/category/vo/ProductCategoryCreateReqVO.java | 5 ++++- .../admin/category/vo/ProductCategoryUpdateReqVO.java | 3 +++ .../dal/dataobject/category/ProductCategoryDO.java | 9 +++++++-- .../service/category/ProductCategoryServiceImplTest.java | 4 ++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 2d38c933d..75a73cd41 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -32,7 +32,7 @@ public class ProductCategoryBaseVO { @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(description = "PC端分类图") - private String bigPicUrl; + //@Schema(description = "PC端分类图") TODO 数据库没有这个字段 + //private String bigPicUrl; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java index f9b559776..616286674 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -5,10 +5,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import javax.validation.constraints.NotBlank; + @Schema(description = "管理后台 - 商品分类创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { - + @Schema(description = "分类描述") + private String description; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java index 15f663761..68cad0d30 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -5,6 +5,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Schema(description = "管理后台 - 商品分类更新 Request VO") @@ -16,5 +17,7 @@ public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { @Schema(description = "分类编号", required = true, example = "2") @NotNull(message = "分类编号不能为空") private Long id; + @Schema(description = "分类描述") + private String description; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index f79e4f1a8..dfa98d80a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -60,8 +60,13 @@ public class ProductCategoryDO extends BaseDO { */ private Integer status; /** - * PC端分类图 + * 描述 */ - private String bigPicUrl; + private String description; + + /** + * PC端分类图 TODO 数据库没有这个字段 + */ + //private String bigPicUrl; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 09c4f7927..2136e1102 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -40,8 +40,8 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { public void testCreateCategory_success() { // 准备参数 ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class,o -> { - // 设置PC端图片可为空 - o.setBigPicUrl(null); + // 设置PC端图片可为空 TODO 数据库没有这个字段 + //o.setBigPicUrl(null); }); // mock 父类 From c3e36ba9da272796406ec3fcc95ef88809129caa Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 24 Apr 2023 10:50:40 +0800 Subject: [PATCH 014/232] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E8=AE=A9=E6=9C=8D=E5=8A=A1=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=EF=BC=8C=E6=94=B9=E5=8A=A8=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E9=83=BD=E5=B7=B2=E5=8A=A0=E4=B8=8ATODO=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../api/spu/dto/ProductSpuRespDTO.java | 2 +- .../enums/spu/ProductSpuSpecTypeEnum.java | 10 ++--- .../admin/spu/vo/ProductSpuBaseVO.java | 3 +- .../app/spu/vo/AppProductSpuDetailRespVO.java | 4 +- .../convert/sku/ProductSkuConvert.java | 3 +- .../dal/mysql/sku/ProductSkuMapper.java | 4 +- .../dal/mysql/spu/ProductSpuMapper.java | 3 +- .../service/sku/ProductSkuService.java | 2 +- .../service/sku/ProductSkuServiceImpl.java | 2 +- .../service/spu/ProductSpuServiceImpl.java | 7 ++-- .../spu/ProductSpuServiceImplTest.java | 42 ++++++++++--------- .../app/order/AppTradeOrderController.java | 1 + 13 files changed, 45 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index 9cb1fc48c..b3651b59a 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ yudao-module-member yudao-module-system yudao-module-infra - + yudao-module-pay diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java index 45d42f41b..5c4ee9bb7 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -79,7 +79,7 @@ public class ProductSpuRespDTO { *

* 枚举 {@link ProductSpuSpecTypeEnum} */ - private Integer specType; + private Boolean specType; /** * 最小价格,单位使用:分 *

diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java index af455bece..24488df62 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java @@ -16,15 +16,15 @@ import java.util.Arrays; @Deprecated public enum ProductSpuSpecTypeEnum implements IntArrayValuable { - RECYCLE(1, "统一规格"), - DISABLE(2, "多规格"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray(); + RECYCLE(false, "统一规格"), + DISABLE(true, "多规格"); + //public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();// TODO 暂时先这样跑起来 + public static final int[] ARRAYS = {}; /** * 规格类型 */ - private final Integer type; + private final Boolean type; /** * 规格名称 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 3f0c94a74..f69006364 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -57,8 +57,7 @@ public class ProductSpuBaseVO { @Schema(description = "规格类型", required = true, example = "1") @NotNull(message = "规格类型不能为空") - @InEnum(ProductSpuSpecTypeEnum.class) - private Integer specType; + private Boolean specType; @Schema(description = "是否展示库存", required = true, example = "true") @NotNull(message = "是否展示库存不能为空") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index cf5471cba..424843bc7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -35,8 +35,8 @@ public class AppProductSpuDetailRespVO { // ========== SKU 相关字段 ========= - @Schema(description = "规格类型", required = true, example = "1") - private Integer specType; + @Schema(description = "规格类型", required = true, example = "true") + private Boolean specType; @Schema(description = "是否展示库存", required = true, example = "true") private Boolean showStock; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index f397dfc48..9b7714bb9 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -37,7 +37,8 @@ public interface ProductSkuConvert { default List convertList06(List list, Long spuId, String spuName) { List result = convertList06(list); - result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName)); + // result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName)); TODO ProductSkuDO中已经没有name相关属性 + result.forEach(item -> item.setSpuId(spuId)); return result; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 56bc54499..96378faf7 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -26,8 +26,8 @@ public interface ProductSkuMapper extends BaseMapperX { default List selectListBySpuIdAndStatus(Long spuId, Integer status) { return selectList(new LambdaQueryWrapperX() - .eq(ProductSkuDO::getSpuId, spuId) - .eqIfPresent(ProductSkuDO::getStatus, status)); + .eq(ProductSkuDO::getSpuId, spuId)// eqIfPresent(ProductSkuDO::getStatus, status) TODO ProductSkuDO已经没有status属性 + ); } default List selectListBySpuId(Collection spuIds) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 57a3125d8..256bc43f1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -52,7 +52,8 @@ public interface ProductSpuMapper extends BaseMapperX { .eqIfPresent(ProductSpuDO::getStatus, status); // 排序逻辑 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { - query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); + // TODO ProductSpuDO 已经没有maxPrice 属性 + //query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 621e12d9f..8db4911ab 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -50,7 +50,7 @@ public interface ProductSkuService { * * @param list sku组合的集合 */ - void validateSkuList(List list, Integer specType); + void validateSkuList(List list, Boolean specType); /** * 批量创建 SKU diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 1ab2523cc..058699aeb 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -79,7 +79,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { } @Override - public void validateSkuList(List skus, Integer specType) { + public void validateSkuList(List skus, Boolean specType) { // 非多规格,不需要校验 if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) { return; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 0dd9cdf55..352c8b341 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -102,9 +102,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { */ private void initSpuFromSkus(ProductSpuDO spu, List skus) { spu.setMarketPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - spu.setMaxPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - spu.setMinPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - spu.setTotalStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + // TODO ProductSpuDO中已没有相关属性 + //spu.setMaxPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); + //spu.setMinPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); + //spu.setTotalStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); } /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index fbd50cad7..17027fc55 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -94,6 +94,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); createReqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); + // TODO ProductSpuCreateReqVO中已没有相关属性 // createReqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); // createReqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); // createReqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); @@ -118,6 +119,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { List skuCreateReqList = reqVO.getSkus(); reqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); + // TODO ProductSpuUpdateReqVO中已没有相关属性 // reqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); // reqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); // reqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); @@ -193,21 +195,21 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - o.setTotalStock(500); - o.setMinPrice(1); - o.setMaxPrice(50); + //o.setTotalStock(500); + //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 + //o.setMaxPrice(50); o.setMarketPrice(25); o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); o.setBrandId(brandId); o.setCategoryId(categoryId); - o.setClickCount(100); - o.setCode(code); + //o.setClickCount(100); + //o.setCode(code); // TODO ProductSpuDO中已没有相关属性 o.setDescription("测试商品"); o.setSliderPicUrls(new ArrayList<>()); o.setName("测试"); o.setSalesCount(100); - o.setSellPoint("超级加倍"); - o.setShowStock(true); + //o.setSellPoint("超级加倍"); + //o.setShowStock(true); // TODO ProductSpuDO中已没有相关属性 o.setVideoUrl(""); }); productSpuMapper.insert(createReqVO); @@ -241,21 +243,21 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - o.setTotalStock(1); - o.setMinPrice(1); - o.setMaxPrice(1); + //o.setTotalStock(1); + //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 + //o.setMaxPrice(1); o.setMarketPrice(1); o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); o.setBrandId(brandId); o.setCategoryId(categoryId); - o.setClickCount(1); - o.setCode(generateNo()); + //o.setClickCount(1); // TODO ProductSpuDO中已没有相关属性 + //o.setCode(generateNo()); o.setDescription("测试商品"); o.setSliderPicUrls(new ArrayList<>()); o.setName("测试"); o.setSalesCount(1); - o.setSellPoint("卖点"); - o.setShowStock(true); + //o.setSellPoint("卖点"); + //o.setShowStock(true); // TODO ProductSpuDO中已没有相关属性 }); // 准备参数 @@ -345,15 +347,15 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { public void testUpdateSpuStock() { // 准备参数 Map stockIncrCounts = MapUtil.builder(1L, 10).put(2L, -20).build(); - // mock 方法(数据) - productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(1L).setTotalStock(20))); - productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(2L).setTotalStock(30))); + // mock 方法(数据) // TODO ProductSpuDO中已没有相关属性 + //productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(1L).setTotalStock(20))); + //productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(2L).setTotalStock(30))); // 调用 productSpuService.updateSpuStock(stockIncrCounts); - // 断言 - assertEquals(productSpuService.getSpu(1L).getTotalStock(), 30); - assertEquals(productSpuService.getSpu(2L).getTotalStock(), 10); + // 断言 // TODO ProductSpuDO中已没有相关属性 + //assertEquals(productSpuService.getSpu(1L).getTotalStock(), 30); + //assertEquals(productSpuService.getSpu(2L).getTotalStock(), 10); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index f64d1376c..4a36d4acc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.controller.app.order; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; From 992a30486e60c4a3ba6c6237f68b7c826a881a4e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 24 Apr 2023 11:09:57 +0800 Subject: [PATCH 015/232] =?UTF-8?q?=E8=A1=A5=E5=85=85mall.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 327 ++++++++++++++++++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 sql/mysql/optional/mall.sql diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql new file mode 100644 index 000000000..0e8483155 --- /dev/null +++ b/sql/mysql/optional/mall.sql @@ -0,0 +1,327 @@ +/* + Navicat Premium Data Transfer + + Source Server : 127.0.0.1 MySQL + Source Server Type : MySQL + Source Server Version : 80026 + Source Host : localhost:3306 + Source Schema : ruoyi-vue-pro + + Target Server Type : MySQL + Target Server Version : 80026 + File Encoding : 65001 + + Date: 01/08/2022 23:01:36 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for market_activity +-- ---------------------------- +DROP TABLE IF EXISTS `market_activity`; +CREATE TABLE `market_activity` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '活动编号', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '活动标题', + `activity_type` tinyint NOT NULL COMMENT '活动类型', + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', + `start_time` datetime NOT NULL COMMENT '开始时间', + `end_time` datetime NOT NULL COMMENT '结束时间', + `invalid_time` datetime NULL DEFAULT NULL COMMENT '失效时间', + `delete_time` datetime NULL DEFAULT NULL COMMENT '删除时间', + `time_limited_discount` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', + `full_privilege` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '促销活动'; + +-- ---------------------------- +-- Records of market_activity +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for market_banner +-- ---------------------------- +DROP TABLE IF EXISTS `market_banner`; +CREATE TABLE `market_banner` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Banner编号', + `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'Banner标题', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图片URL', + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', + `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '跳转地址', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + `sort` tinyint NULL DEFAULT NULL COMMENT '排序', + `memo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Banner管理'; + +-- ---------------------------- +-- Records of market_banner +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for member_address +-- ---------------------------- +DROP TABLE IF EXISTS `member_address`; +CREATE TABLE `member_address` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '收件地址编号', + `user_id` bigint NOT NULL COMMENT '用户编号', + `name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件人名称', + `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '手机号', + `area_id` bigint NOT NULL COMMENT '地区编码', + `post_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '邮编', + `detail_address` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件详细地址', + `defaulted` bit(1) NOT NULL COMMENT '是否默认', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_userId`(`user_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址'; + +-- ---------------------------- +-- Records of member_address +-- ---------------------------- +BEGIN; +INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `post_code`, `detail_address`, `defaulted`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 1, 'yunai', '15601691300', 610632, '200000', '芋道源码 233 号 666 室', b'1', '1', '2022-08-01 22:46:35', '1', '2022-08-01 22:46:35', b'0', 1); +COMMIT; + +-- ---------------------------- +-- Table structure for product_brand +-- ---------------------------- +DROP TABLE IF EXISTS `product_brand`; +CREATE TABLE `product_brand` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌名称', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌图片', + `sort` int NULL DEFAULT 0 COMMENT '品牌排序', + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '品牌描述', + `status` tinyint NOT NULL COMMENT '状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品品牌'; + +-- ---------------------------- +-- Records of product_brand +-- ---------------------------- +BEGIN; +INSERT INTO `product_brand` (`id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '苹果', 'http://test.yudao.iocoder.cn/e3726713fa56db5717c78c011762fcc7a251db12735c3581470638b8e1fa17e2.jpeg', 0, '是上市', 0, '1', '2022-07-30 22:12:18', '1', '2022-07-30 22:13:55', b'0', 1); +COMMIT; + +-- ---------------------------- +-- Table structure for product_category +-- ---------------------------- +DROP TABLE IF EXISTS `product_category`; +CREATE TABLE `product_category` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', + `parent_id` bigint NOT NULL COMMENT '父分类编号', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名称', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类图片', + `sort` int NULL DEFAULT 0 COMMENT '分类排序', + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '分类描述', + `status` tinyint NOT NULL COMMENT '开启状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品分类'; + +-- ---------------------------- +-- Records of product_category +-- ---------------------------- +BEGIN; +INSERT INTO `product_category` (`id`, `parent_id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 0, '电脑办公', 'http://test.yudao.iocoder.cn/122d548e1b3cd5dec72fe8075c6977a70f9cc13541a684ab3685f1b5df42f6bd.jpeg', 1, '1234', 0, '1', '2022-07-30 16:36:35', '1', '2022-07-30 20:27:16', b'0', 1), (2, 1, '笔记本', 'http://test.yudao.iocoder.cn/72713ac7b947600a019a18786ed0e6562e8692e253dbd35110a0a85c2469bbec.jpg', 1, '

测试一下

', 0, '1', '2022-07-30 16:38:09', '1', '2022-07-30 16:38:09', b'0', 1), (3, 1, '游戏本', 'http://test.yudao.iocoder.cn/287c50dd9f5f575f57329a0c57b2095be6d1aeba83867b905fe549f54a296feb.jpg', 2, '

测试一下

', 0, '1', '2022-07-30 16:39:09', '1', '2022-07-30 20:26:59', b'0', 1), (4, 0, '手机', 'http://test.yudao.iocoder.cn/e1b63900c78dbb661b3e383960cee5cfea7e1dd2fb22cff2e317ff025faaf8b2.jpeg', 2, '

123

', 0, '1', '2022-07-30 16:40:00', '1', '2022-07-30 16:40:09', b'0', 1), (5, 4, '5G手机', 'http://test.yudao.iocoder.cn/3af6557ac7def6423f046f5b2e920b644793420b466959aaa996a2e19068bbde.jpeg', 1, '


', 0, '1', '2022-07-30 16:43:00', '1', '2022-07-30 16:43:00', b'0', 1), (6, 4, '游戏手机', 'http://test.yudao.iocoder.cn/964fe9ccd1710d64ede261dc36d231918a017641986c15293c367f9f66d94d05.jpeg', 2, NULL, 0, '1', '2022-07-30 16:43:44', '1', '2022-07-30 16:43:44', b'0', 1), (7, 5, '厉害的 5G 手机', 'http://test.yudao.iocoder.cn/b287122f277838e8de368769b96217918605743bc45f3a29bda3cc7359dc66e1.png', 0, '123', 0, '1', '2022-07-30 20:38:09', '1', '2022-07-30 20:38:09', b'0', 1); +COMMIT; + +-- ---------------------------- +-- Table structure for product_property +-- ---------------------------- +DROP TABLE IF EXISTS `product_property`; +CREATE TABLE `product_property` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格名称', + `status` tinyint NULL DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_name`(`name`(32) ASC) USING BTREE COMMENT '规格名称索引' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格名称'; + +-- ---------------------------- +-- Records of product_property +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for product_property_value +-- ---------------------------- +DROP TABLE IF EXISTS `product_property_value`; +CREATE TABLE `product_property_value` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `property_id` bigint NULL DEFAULT NULL COMMENT '规格键id', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格值名字', + `status` tinyint NULL DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格值'; + +-- ---------------------------- +-- Records of product_property_value +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for product_sku +-- ---------------------------- +DROP TABLE IF EXISTS `product_sku`; +CREATE TABLE `product_sku` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `spu_id` bigint NOT NULL COMMENT 'spu编号', + `properties` varchar(512) DEFAULT NULL COMMENT '属性数组,JSON 格式 [{propertId: , valueId: }, {propertId: , valueId: }]', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位:分', + `market_price` int DEFAULT NULL COMMENT '市场价,单位:分', + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', + `bar_code` varchar(64) DEFAULT NULL COMMENT 'SKU 的条形码', + `pic_url` varchar(256) NOT NULL COMMENT '图片地址', + `stock` int DEFAULT NULL COMMENT '库存', + `weight` double DEFAULT NULL COMMENT '商品重量,单位:kg 千克', + `volume` double DEFAULT NULL COMMENT '商品体积,单位:m^3 平米', + `sub_commission_first_price` int DEFAULT NULL COMMENT '一级分销的佣金,单位:分', + `sub_commission_second_price` int DEFAULT NULL COMMENT '二级分销的佣金,单位:分', + `sales_count` int DEFAULT NULL COMMENT '商品销量', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) DEFAULT NULL COMMENT '创建人', + `updater` double(64,0) DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', +PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='商品sku'; + +-- ---------------------------- +-- Records of product_sku +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for product_spu +-- ---------------------------- +DROP TABLE IF EXISTS `product_spu`; +CREATE TABLE `product_spu` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品 SPU 编号,自增', + `name` varchar(128) NOT NULL COMMENT '商品名称', + `keyword` varchar(256) DEFAULT NULL COMMENT '关键字', + `introduction` varchar(256) COMMENT '商品简介', + `description` text COMMENT '商品详情', + `bar_code` varchar(64) DEFAULT NULL COMMENT '条形码', + `category_id` bigint NOT NULL COMMENT '商品分类编号', + `brand_id` int DEFAULT NULL COMMENT '商品品牌编号', + `pic_url` varchar(256) NOT NULL COMMENT '商品封面图', + `slider_pic_urls` varchar(2000) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张', + `video_url` varchar(256) DEFAULT NULL COMMENT '商品视频', + `unit` tinyint NOT NULL COMMENT '单位', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', + `status` tinyint NOT NULL COMMENT '商品状态: 0 上架(开启) 1 下架(禁用)-1 回收', + `spec_type` bit(1) DEFAULT NULL COMMENT '规格类型:0 单规格 1 多规格', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位使用:分', + `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分', + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', + `stock` int NOT NULL DEFAULT '0' COMMENT '库存', + `delivery_template_id` bigint NOT NULL COMMENT '物流配置模板编号', + `recommend_hot` bit(1) DEFAULT NULL COMMENT '是否热卖推荐: 0 默认 1 热卖', + `recommend_benefit` bit(1) DEFAULT NULL COMMENT '是否优惠推荐: 0 默认 1 优选', + `recommend_best` bit(1) DEFAULT NULL COMMENT '是否精品推荐: 0 默认 1 精品', + `recommend_new` bit(1) DEFAULT NULL COMMENT '是否新品推荐: 0 默认 1 新品', + `recommend_good` bit(1) DEFAULT NULL COMMENT '是否优品推荐', + `give_integral` int NOT NULL COMMENT '赠送积分', + `give_coupon_template_ids` varchar(512) DEFAULT '' COMMENT '赠送的优惠劵编号的数组', + `sub_commission_type` bit(1) DEFAULT NULL COMMENT '分销类型', + `activity_orders` varchar(16) NOT NULL DEFAULT '' COMMENT '活动显示排序0=默认, 1=秒杀,2=砍价,3=拼团', + `sales_count` int DEFAULT '0' COMMENT '商品销量', + `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量', + `browse_count` int DEFAULT '0' COMMENT '商品点击量', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='商品spu'; + +-- ---------------------------- +-- Records of product_spu +-- ---------------------------- +BEGIN; +COMMIT; + +SET FOREIGN_KEY_CHECKS = 1; + +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 0, '/product', 'merchant', NULL, 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:26:19', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'dict', 'mall/product/category/index', 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:23:37', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2004, '分类创建', 'product:category:create', 3, 2, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2005, '分类更新', 'product:category:update', 3, 3, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2006, '分类删除', 'product:category:delete', 3, 4, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2007, '分类导出', 'product:category:export', 3, 5, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-30 13:52:13', b'1'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2008, '商品品牌', '', 2, 1, 2000, 'brand', 'dashboard', 'mall/product/brand/index', 0, b'1', b'1', '', '2022-07-30 13:52:44', '1', '2022-07-30 22:23:43', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2009, '品牌查询', 'product:brand:query', 3, 1, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2010, '品牌创建', 'product:brand:create', 3, 2, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2011, '品牌更新', 'product:brand:update', 3, 3, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2012, '品牌删除', 'product:brand:delete', 3, 4, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2013, '品牌导出', 'product:brand:export', 3, 5, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 14:15:00', b'1'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2014, '商品管理', '', 2, 0, 2000, 'spu', 'link', 'mall/product/spu/index', 0, b'1', b'1', '', '2022-07-30 14:22:58', '1', '2022-07-30 22:26:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2015, '商品查询', 'product:spu:query', 3, 1, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2016, '商品创建', 'product:spu:create', 3, 2, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2017, '商品更新', 'product:spu:update', 3, 3, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2018, '商品删除', 'product:spu:delete', 3, 4, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2019, '规格管理', '', 2, 3, 2000, 'property', '', 'mall/product/property/index', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2020, '规格查询', 'product:property:query', 3, 1, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2021, '规格创建', 'product:property:create', 3, 2, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2022, '规格更新', 'product:property:update', 3, 3, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2023, '规格删除', 'product:property:delete', 3, 4, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2024, '规格导出', 'product:property:export', 3, 5, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2025, 'Banner管理', '', 2, 1, 2000, 'brand', '', 'mall/market/banner/index', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2026, 'Banner查询', 'market:banner:query', 3, 1, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); + From a5f018104e3635b4cc583c2733b4be8c1e962f1e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 25 Apr 2023 21:33:59 +0800 Subject: [PATCH 016/232] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=95=86=E5=93=81?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../category/vo/ProductCategoryBaseVO.java | 10 +++---- .../category/ProductCategoryDO.java | 26 +++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 75a73cd41..880657da7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -21,10 +21,13 @@ public class ProductCategoryBaseVO { @NotBlank(message = "分类名称不能为空") private String name; - @Schema(description = "分类图片", required = true) - @NotBlank(message = "分类图片不能为空") + @Schema(description = "移动端分类图", required = true) + @NotBlank(message = "移动端分类图不能为空") private String picUrl; + @Schema(description = "PC 端分类图") + private String bigPicUrl; + @Schema(description = "分类排序", required = true, example = "1") private Integer sort; @@ -32,7 +35,4 @@ public class ProductCategoryBaseVO { @NotNull(message = "开启状态不能为空") private Integer status; - //@Schema(description = "PC端分类图") TODO 数据库没有这个字段 - //private String bigPicUrl; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index dfa98d80a..3756ea818 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -9,10 +9,6 @@ import lombok.*; /** * 商品分类 DO * - * 商品分类一共两类: - * 1)一级分类:{@link #parentId} 等于 0 - * 2)二级 + 三级分类:{@link #parentId} 不等于 0 - * * @author 芋道源码 */ @TableName("product_category") @@ -43,30 +39,26 @@ public class ProductCategoryDO extends BaseDO { */ private String name; /** - * 分类图片 + * 移动端分类图 * - * 一级分类:推荐 200 x 100 分辨率 - * 二级 + 三级分类:推荐 100 x 100 分辨率 + * 建议 180*180 分辨率 */ private String picUrl; + /** + * PC 端分类图 + * + * 建议 468*340 分辨率 + */ + private String bigPicUrl; /** * 分类排序 */ private Integer sort; /** * 开启状态 - *

+ * * 枚举 {@link CommonStatusEnum} */ private Integer status; - /** - * 描述 - */ - private String description; - - /** - * PC端分类图 TODO 数据库没有这个字段 - */ - //private String bigPicUrl; } From 4068548c452021595a69ea5347b885366da0a964 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 26 Apr 2023 17:38:42 +0800 Subject: [PATCH 017/232] =?UTF-8?q?=E7=A7=BB=E9=99=A4ProductSpuSpecTypeEnu?= =?UTF-8?q?m=E5=8F=8A=E7=9B=B8=E5=85=B3=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/spu/dto/ProductSpuRespDTO.java | 3 -- .../enums/spu/ProductSpuSpecTypeEnum.java | 38 ------------------- .../admin/spu/vo/ProductSpuBaseVO.java | 1 - .../dal/dataobject/spu/ProductSpuDO.java | 1 - .../service/sku/ProductSkuServiceImpl.java | 3 +- .../spu/ProductSpuServiceImplTest.java | 13 +++---- 6 files changed, 7 insertions(+), 52 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java index 5c4ee9bb7..b1c0b802f 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.api.spu.dto; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import lombok.Data; @@ -76,8 +75,6 @@ public class ProductSpuRespDTO { /** * 规格类型 - *

- * 枚举 {@link ProductSpuSpecTypeEnum} */ private Boolean specType; /** diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java deleted file mode 100644 index 24488df62..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.spu; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品 SPU 规格类型 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -@Deprecated -public enum ProductSpuSpecTypeEnum implements IntArrayValuable { - - RECYCLE(false, "统一规格"), - DISABLE(true, "多规格"); - - //public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();// TODO 暂时先这样跑起来 - public static final int[] ARRAYS = {}; - /** - * 规格类型 - */ - private final Boolean type; - /** - * 规格名称 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index f69006364..5725617d4 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index df935d74d..d09a3bb7e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 058699aeb..04430764b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyVa import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; @@ -81,7 +80,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Override public void validateSkuList(List skus, Boolean specType) { // 非多规格,不需要校验 - if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) { + if (ObjectUtil.notEqual(specType, true)) { return; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 17027fc55..8048e9344 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl; import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl; @@ -83,7 +82,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { public void testCreateSpu_success() { // 准备参数 ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> { - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setSpecType(true); o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); }); @@ -111,7 +110,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { o.setId(createReqVO.getId()); // 设置更新的 ID - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setSpecType(true); o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); }); // 调用 @@ -132,7 +131,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test public void testValidateSpuExists_exception() { ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setSpecType(true); o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); }); // 调用 @@ -199,7 +198,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 //o.setMaxPrice(50); o.setMarketPrice(25); - o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); + o.setSpecType(false); o.setBrandId(brandId); o.setCategoryId(categoryId); //o.setClickCount(100); @@ -247,7 +246,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 //o.setMaxPrice(1); o.setMarketPrice(1); - o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); + o.setSpecType(false); o.setBrandId(brandId); o.setCategoryId(categoryId); //o.setClickCount(1); // TODO ProductSpuDO中已没有相关属性 @@ -266,7 +265,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()))); productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.RECYCLE.getStatus()))); // 测试 SpecType 不匹配 - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()))); + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setSpecType(true))); // 测试 BrandId 不匹配 productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setBrandId(generateId()))); // 测试 CategoryId 不匹配 From 3ced6a3240022dcdaadd1c9807495ab3378c5b8f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 26 Apr 2023 20:13:12 +0800 Subject: [PATCH 018/232] =?UTF-8?q?=E5=AE=8C=E5=96=84=20App=20=E5=95=86?= =?UTF-8?q?=E5=93=81=E6=90=9C=E7=B4=A2=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/spu/AppProductSpuController.http | 12 ++++++- .../app/spu/AppProductSpuController.java | 4 +-- .../spu/vo/AppProductSpuPageItemRespVO.java | 20 +++++++----- .../app/spu/vo/AppProductSpuPageReqVO.java | 7 +++- .../convert/spu/ProductSpuConvert.java | 13 ++++++-- .../dal/mysql/spu/ProductSpuMapper.java | 32 ++++++++++++++----- .../service/spu/ProductSpuService.java | 7 ++-- .../service/spu/ProductSpuServiceImpl.java | 24 ++++++++++---- 8 files changed, 87 insertions(+), 32 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http index 04df7bfec..0de7583ae 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http @@ -1,8 +1,18 @@ -### 获得订单交易的分页 TODO +### 获得订单交易的分页(默认) GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10 Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} +### 获得订单交易的分页(价格) +GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10&sortField=price&sortAsc=true +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + +### 获得订单交易的分页(销售) +GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10&sortField=salesCount&sortAsc=true +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + ### 获得商品 SPU 明细 GET {{appApi}}/product/spu/get-detail?id=4 tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index d9ab87c72..783b85780 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -49,8 +49,8 @@ public class AppProductSpuController { @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { - PageResult pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus()); - return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult)); + PageResult pageResult = productSpuService.getSpuPage(pageVO); + return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult)); } @GetMapping("/get-detail") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java index d826900a6..27d577976 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.app.spu.vo; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -15,21 +16,24 @@ public class AppProductSpuPageItemRespVO { private Long id; @Schema(description = "商品名称", required = true, example = "芋道") - @NotEmpty(message = "商品名称不能为空") private String name; @Schema(description = "分类编号", required = true) - @NotNull(message = "分类编号不能为空") private Long categoryId; - @Schema(description = "商品图片的数组", required = true) - private List picUrls; + @Schema(description = "商品封面图", required = true) + private String picUrl; - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; + @Schema(description = "商品轮播图", required = true) + private List sliderPicUrls; - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; + @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") + private Integer price; + + // ========== SKU 相关字段 ========= + + @Schema(description = "库存", required = true, example = "666") + private Integer stock; // ========== 统计相关字段 ========= diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java index dcbd1e190..5050561d6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java @@ -19,18 +19,23 @@ public class AppProductSpuPageReqVO extends PageParam { public static final String SORT_FIELD_PRICE = "price"; public static final String SORT_FIELD_SALES_COUNT = "salesCount"; + public static final String RECOMMEND_TYPE_HOT = "hot"; + @Schema(description = "分类编号", example = "1") private Long categoryId; @Schema(description = "关键字", example = "好看") private String keyword; - @Schema(description = "排序字段", example = "price") // 参见 AppSpuPageReqVO.SORT_FIELD_XXX 常量 + @Schema(description = "排序字段", example = "price") // 参见 AppProductSpuPageReqVO.SORT_FIELD_XXX 常量 private String sortField; @Schema(description = "排序方式", example = "true") private Boolean sortAsc; + @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常亮 + private String recommendType; + @AssertTrue(message = "排序字段不合法") @JsonIgnore public boolean isSortFieldValid() { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index fcf6d6436..cddd742f0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import org.mapstruct.Mapper; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; import java.util.ArrayList; @@ -75,8 +76,6 @@ public interface ProductSpuConvert { List convertList03(List skus); AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); - PageResult convertPage02(PageResult page); - default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, List propertyValues) { ProductSpuDetailRespVO spuVO = convert03(spu); @@ -105,4 +104,14 @@ public interface ProductSpuConvert { List convertList04(List skus); ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); + // ========== 用户 App 相关 ========== + + default PageResult convertPageForGetSpuPage(PageResult page) { + // 累加虚拟销量 + page.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); + // 然后进行转换 + return convertPageForGetSpuPage0(page); + } + PageResult convertPageForGetSpuPage0(PageResult page); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 256bc43f1..ee0922208 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -1,11 +1,15 @@ package cn.iocoder.yudao.module.product.dal.mysql.spu; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -46,16 +50,28 @@ public interface ProductSpuMapper extends BaseMapperX { .orderByDesc(ProductSpuDO::getSort)); } - default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Integer status) { + /** + * 获得商品 SPU 分页,提供给用户 App 使用 + */ + default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Set categoryIds) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() - .eqIfPresent(ProductSpuDO::getCategoryId, pageReqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, status); + .likeIfPresent(ProductSpuDO::getName, pageReqVO.getKeyword()) // 关键字匹配,目前只匹配商品名 + .inIfPresent(ProductSpuDO::getCategoryId, categoryIds); // 分类 + query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()) // 上架状态 + .gt(ProductSpuDO::getStock, 0); // 有库存 + // 推荐类型的过滤条件 + if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { + query.eq(ProductSpuDO::getRecommendHot, true); + } // 排序逻辑 - if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { - // TODO ProductSpuDO 已经没有maxPrice 属性 - //query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); - } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { - query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); + if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { + query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC", + pageReqVO.getSortAsc() ? "ASC" : "DESC")); + } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { + query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getPrice) + .orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); + } else { + query.orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); } return selectPage(pageReqVO, query); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 0ae7359eb..dd8f77c12 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -75,7 +75,7 @@ public interface ProductSpuService { List getSpuList(); /** - * 获得商品 SPU 分页 + * 获得商品 SPU 分页,提供给挂你兰后台使用 * * @param pageReqVO 分页查询 * @return 商品spu分页 @@ -83,13 +83,12 @@ public interface ProductSpuService { PageResult getSpuPage(ProductSpuPageReqVO pageReqVO); /** - * 获得商品 SPU 分页 + * 获得商品 SPU 分页,提供给用户 App 使用 * * @param pageReqVO 分页查询 - * @param status 状态 * @return 商品 SPU 分页 */ - PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status); + PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO); /** * 更新商品 SPU 库存(增量) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 352c8b341..79a6949a5 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,14 +1,20 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; @@ -21,10 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -168,8 +171,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { } @Override - public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status) { - return productSpuMapper.selectPage(pageReqVO, status); + public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO) { + // 查找时,如果查找某个分类编号,则包含它的子分类。因为顶级分类不包含商品 + Set categoryIds = new HashSet<>(); + if (pageReqVO.getCategoryId() != null && pageReqVO.getCategoryId() > 0) { + categoryIds.add(pageReqVO.getCategoryId()); + List categoryChildren = categoryService.getEnableCategoryList(new ProductCategoryListReqVO() + .setParentId(pageReqVO.getCategoryId()).setStatus(CommonStatusEnum.ENABLE.getStatus())); + categoryIds.addAll(CollectionUtils.convertList(categoryChildren, ProductCategoryDO::getId)); + } + // 分页查询 + return productSpuMapper.selectPage(pageReqVO, categoryIds); } @Override From 2113e825d7b085478e8a352e077146f1c4e2581f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 27 Apr 2023 22:43:37 +0800 Subject: [PATCH 019/232] =?UTF-8?q?=E5=AE=8C=E5=96=84=20App=20=E5=95=86?= =?UTF-8?q?=E5=93=81=E8=AF=A6=E6=83=85=E9=80=BB=E8=BE=91=E7=9A=84=2010%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/spu/AppProductSpuController.http | 2 +- .../app/spu/AppProductSpuController.java | 2 +- .../app/spu/vo/AppProductSpuDetailRespVO.java | 24 +++---- .../spu/vo/AppProductSpuPageItemRespVO.java | 9 +-- .../convert/spu/ProductSpuConvert.java | 64 +++++++++---------- .../service/spu/ProductSpuServiceImpl.java | 7 +- 6 files changed, 50 insertions(+), 58 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http index 0de7583ae..c391b5873 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http @@ -14,5 +14,5 @@ Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} ### 获得商品 SPU 明细 -GET {{appApi}}/product/spu/get-detail?id=4 +GET {{appApi}}/product/spu/get-detail?id=102 tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 783b85780..fe1a8ee87 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -73,7 +73,7 @@ public class AppProductSpuController { List propertyValues = productPropertyValueService .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); // 拼接 - return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues)); + return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index 424843bc7..6992d83b7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -18,17 +18,17 @@ public class AppProductSpuDetailRespVO { @Schema(description = "商品名称", required = true, example = "芋道") private String name; - @Schema(description = "促销语", example = "好吃!") - private String sellPoint; - @Schema(description = "商品详情", required = true, example = "我是商品描述") private String description; @Schema(description = "商品分类编号", required = true, example = "1") private Long categoryId; - @Schema(description = "商品图片的数组", required = true) - private List picUrls; + @Schema(description = "商品封面图", required = true) + private String picUrl; + + @Schema(description = "商品轮播图", required = true) + private List sliderPicUrls; @Schema(description = "商品视频", required = true) private String videoUrl; @@ -38,14 +38,14 @@ public class AppProductSpuDetailRespVO { @Schema(description = "规格类型", required = true, example = "true") private Boolean specType; - @Schema(description = "是否展示库存", required = true, example = "true") - private Boolean showStock; + @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") + private Integer price; - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; + @Schema(description = "市场价,单位使用:分", required = true, example = "1024") + private Integer marketPrice; - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; + @Schema(description = "库存", required = true, example = "666") + private Integer stock; /** * SKU 数组 @@ -72,7 +72,7 @@ public class AppProductSpuDetailRespVO { @Schema(description = "销售价格,单位:分", required = true, example = "1024") private Integer price; - @Schema(description = "市场价", example = "1024") + @Schema(description = "市场价,单位使用:分", required = true, example = "1024") private Integer marketPrice; @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java index 27d577976..97513c3bc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java @@ -1,11 +1,8 @@ package cn.iocoder.yudao.module.product.controller.app.spu.vo; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "用户 App - 商品 SPU 分页项 Response VO") @@ -27,17 +24,17 @@ public class AppProductSpuPageItemRespVO { @Schema(description = "商品轮播图", required = true) private List sliderPicUrls; + // ========== SKU 相关字段 ========= + @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") private Integer price; - // ========== SKU 相关字段 ========= - @Schema(description = "库存", required = true, example = "666") private Integer stock; // ========== 统计相关字段 ========= - @Schema(description = "商品销量", example = "1024") + @Schema(description = "商品销量", required = true, example = "1024") private Integer salesCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index cddd742f0..1aa3a4bef 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import org.mapstruct.Mapper; -import org.mapstruct.Named; import org.mapstruct.factory.Mappers; import java.util.ArrayList; @@ -33,48 +32,18 @@ public interface ProductSpuConvert { ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); - ProductSpuDO convert(ProductSpuCreateReqVO bean); + ProductSpuDO convertForGetSpuDetail(ProductSpuCreateReqVO bean); - ProductSpuDO convert(ProductSpuUpdateReqVO bean); + ProductSpuDO convertForGetSpuDetail(ProductSpuUpdateReqVO bean); List convertList(List list); PageResult convertPage(PageResult page); - ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); - List convertList2(List list); List convertList02(List list); - default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List skus, - List propertyValues) { - AppProductSpuDetailRespVO spuVO = convert02(spu) - .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); - spuVO.setSkus(convertList03(skus)); - // 处理商品属性 - Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); - for (int i = 0; i < skus.size(); i++) { - List properties = skus.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); - sku.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); - if (propertyValue == null) { - return; - } - sku.getProperties().add(convert03(propertyValue)); - }); - } - return spuVO; - } - AppProductSpuDetailRespVO convert02(ProductSpuDO spu); - List convertList03(List skus); - AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, List propertyValues) { @@ -114,4 +83,33 @@ public interface ProductSpuConvert { } PageResult convertPageForGetSpuPage0(PageResult page); + default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus, + List propertyValues) { + AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu) + .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); + spuVO.setSkus(convertListForGetSpuDetail(skus)); + // 处理商品属性 + Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); + for (int i = 0; i < skus.size(); i++) { + List properties = skus.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); + sku.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); + if (propertyValue == null) { + return; + } + sku.getProperties().add(convertForGetSpuDetail(propertyValue)); + }); + } + return spuVO; + } + AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu); + List convertListForGetSpuDetail(List skus); + AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 79a6949a5..22b643ef5 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,12 +1,9 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; @@ -66,7 +63,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); // 插入 SPU - ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); + ProductSpuDO spu = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(createReqVO); initSpuFromSkus(spu, skuSaveReqList); productSpuMapper.insert(spu); // 插入 SKU @@ -89,7 +86,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); // 更新 SPU - ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); + ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(updateReqVO); initSpuFromSkus(updateObj, skuSaveReqList); productSpuMapper.updateById(updateObj); // 批量更新 SKU From 668d493b7f17b72826c95ab90866538c9ef102f4 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 29 Apr 2023 21:22:52 +0800 Subject: [PATCH 020/232] =?UTF-8?q?Product=E7=9B=B8=E5=85=B3Do=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0TenantBaseDO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/dal/dataobject/property/ProductPropertyDO.java | 7 ++++++- .../dal/dataobject/property/ProductPropertyValueDO.java | 3 ++- .../module/product/dal/dataobject/sku/ProductSkuDO.java | 3 ++- .../module/product/dal/dataobject/spu/ProductSpuDO.java | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index 2976674c1..bf631c420 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -19,7 +20,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyDO extends BaseDO { +public class ProductPropertyDO extends TenantBaseDO { /** * 主键 @@ -30,6 +31,10 @@ public class ProductPropertyDO extends BaseDO { * 名称 */ private String name; + /** + * 状态 + */ + private Integer status; /** * 备注 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index d73fe06b2..4043afc61 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -20,7 +21,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyValueDO extends BaseDO { +public class ProductPropertyValueDO extends TenantBaseDO { /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index a9488563a..6b37d68fa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.sku; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -27,7 +28,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductSkuDO extends BaseDO { +public class ProductSkuDO extends TenantBaseDO { /** * 商品 SKU 编号,自增 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index d09a3bb7e..1260c7170 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.spu; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; @@ -28,7 +29,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductSpuDO extends BaseDO { +public class ProductSpuDO extends TenantBaseDO { /** * 商品 SPU 编号,自增 From f56d3948305aaf92b27f8f4b3dfe4f1d9b29a71b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 29 Apr 2023 21:28:09 +0800 Subject: [PATCH 021/232] =?UTF-8?q?=E4=BF=AE=E6=94=B9ProductSpuBaseVO?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/spu/vo/ProductSpuBaseVO.java | 125 ++++++++++++++---- 1 file changed, 102 insertions(+), 23 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 5725617d4..e7a30484d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -1,7 +1,13 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -20,55 +26,128 @@ public class ProductSpuBaseVO { @NotEmpty(message = "商品名称不能为空") private String name; - @Schema(description = "商品编码", example = "yudaoyuanma") - private String code; + @Schema(description = "关键字", required = true, example = "芋道") + @NotEmpty(message = "商品关键字不能为空") + private String keyword; - @Schema(description = "促销语", example = "好吃!") - private String sellPoint; + @Schema(description = "商品简介", required = true, example = "芋道") + @NotEmpty(message = "商品简介不能为空") + private String introduction; - @Schema(description = "商品详情", required = true, example = "我是商品描述") - @NotNull(message = "商品详情不能为空") + @Schema(description = "商品详情", required = true, example = "芋道") + @NotEmpty(message = "商品详情不能为空") private String description; - @Schema(description = "商品分类编号", required = true, example = "1") - @NotNull(message = "商品分类编号不能为空") + @Schema(description = "商品条码(一维码)", required = true, example = "芋道") + @NotEmpty(message = "商品条码(一维码)不能为空") + private String barCode; + + @Schema(description = "商品分类编号", required = true, example = "芋道") + @NotEmpty(message = "商品分类编号不能为空") private Long categoryId; - @Schema(description = "商品品牌编号", example = "1") + @Schema(description = "商品品牌编号", required = true, example = "芋道") + @NotEmpty(message = "商品品牌编号不能为空") private Long brandId; - @Schema(description = "商品图片的数组", required = true) - @NotNull(message = "商品图片的数组不能为空") - private List picUrls; + @Schema(description = "商品封面图", required = true, example = "芋道") + @NotEmpty(message = "商品封面图不能为空") + private String picUrl; - @Schema(description = "商品视频", required = true) + @Schema(description = "商品轮播图", required = true) + @NotEmpty(message = "商品轮播图不能为空") + private List sliderPicUrls; + + @Schema(description = "商品视频") private String videoUrl; + @Schema(description = "单位", required = true, example = "1") + @NotEmpty(message = "商品单位不能为空") + private Integer unit; + @Schema(description = "排序字段", required = true, example = "1") + @NotEmpty(message = "商品排序字段不能为空") private Integer sort; @Schema(description = "商品状态", required = true, example = "1") - @NotNull(message = "商品状态不能为空") - @InEnum(ProductSpuStatusEnum.class) + @NotEmpty(message = "商品状态不能为空") private Integer status; // ========== SKU 相关字段 ========= - @Schema(description = "规格类型", required = true, example = "1") - @NotNull(message = "规格类型不能为空") + @Schema(description = "规格类型", required = true, example = "true") + @NotEmpty(message = "商品规格类型不能为空") private Boolean specType; - @Schema(description = "是否展示库存", required = true, example = "true") - @NotNull(message = "是否展示库存不能为空") - private Boolean showStock; + @Schema(description = "商品价格", required = true, example = "1212") + @NotEmpty(message = "商品价格不能为空") + private Integer price; - @Schema(description = "市场价", example = "1024") + @Schema(description = "市场价", required = true, example = "3") + @NotEmpty(message = "商品市场价不能为空") private Integer marketPrice; + @Schema(description = "成本价", required = true, example = "12") + @NotEmpty(message = "商品成本价不能为空") + private Integer costPrice; + + @Schema(description = "库存", required = true, example = "111") + @NotEmpty(message = "商品库存不能为空") + private Integer stock; + + // ========== 物流相关字段 ========= + + @Schema(description = "物流配置模板编号", required = true, example = "111") + @NotEmpty(message = "物流配置模板编号不能为空") + private Long deliveryTemplateId; + + // ========== 营销相关字段 ========= + + @Schema(description = "是否热卖推荐", required = true, example = "true") + @NotEmpty(message = "商品推荐不能为空") + private Boolean recommendHot; + + @Schema(description = "是否优惠推荐", required = true, example = "true") + @NotEmpty(message = "商品推荐不能为空") + private Boolean recommendBenefit; + + @Schema(description = "是否精品推荐", required = true, example = "true") + @NotEmpty(message = "商品推荐不能为空") + private Boolean recommendBest; + + @Schema(description = "是否新品推荐", required = true, example = "true") + @NotEmpty(message = "商品推荐不能为空") + private Boolean recommendNew; + + @Schema(description = "是否优品推荐", required = true, example = "true") + @NotEmpty(message = "商品推荐不能为空") + private Boolean recommendGood; + + @Schema(description = "赠送积分", required = true, example = "111") + @NotEmpty(message = "商品赠送积分不能为空") + private Integer giveIntegral; + + @Schema(description = "赠送的优惠劵编号的数组") + private List giveCouponTemplateIds; + + @Schema(description = "分销类型") + private Boolean subCommissionType; + + @Schema(description = "活动展示顺序") + private List activityOrders; + // ========== 统计相关字段 ========= - @Schema(description = "虚拟销量", required = true, example = "1024") - @NotNull(message = "虚拟销量不能为空") + @Schema(description = "商品销量", required = true, example = "芋道") + @NotEmpty(message = "商品销量不能为空") + private Integer salesCount; + + @Schema(description = "虚拟销量", required = true, example = "芋道") + @NotEmpty(message = "商品虚拟销量不能为空") private Integer virtualSalesCount; + @Schema(description = "浏览量", required = true, example = "芋道") + @NotEmpty(message = "商品浏览量不能为空") + private Integer browseCount; + } From 24a56bb45f9bd11145042aa3781aa7d51b877e3d Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 30 Apr 2023 17:34:56 +0800 Subject: [PATCH 022/232] =?UTF-8?q?=E7=A7=BB=E9=99=A4ProductSku=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84status=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9Property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductPropertyValueController.java | 13 ++++++---- .../admin/sku/vo/ProductSkuBaseVO.java | 22 ----------------- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 20 +++++++++++++--- .../admin/sku/vo/ProductSkuRespVO.java | 24 +++++++++++++++---- .../service/sku/ProductSkuServiceImpl.java | 4 ++-- .../service/sku/ProductSkuServiceTest.java | 2 -- 6 files changed, 48 insertions(+), 37 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java index 92ce6bee0..fbac32712 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.crypto.symmetric.AES; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; @@ -18,6 +20,9 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.Arrays; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - 商品属性值") @@ -32,14 +37,14 @@ public class ProductPropertyValueController { @PostMapping("/create") @Operation(summary = "创建属性值") @PreAuthorize("@ss.hasPermission('product:property:create')") - public CommonResult createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { + public CommonResult createPropertyValue(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { return success(productPropertyValueService.createPropertyValue(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新属性值") @PreAuthorize("@ss.hasPermission('product:property:update')") - public CommonResult updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { + public CommonResult updatePropertyValue(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { productPropertyValueService.updatePropertyValue(updateReqVO); return success(true); } @@ -48,7 +53,7 @@ public class ProductPropertyValueController { @Operation(summary = "删除属性值") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:delete')") - public CommonResult deleteProperty(@RequestParam("id") Long id) { + public CommonResult deletePropertyValue(@RequestParam("id") Long id) { productPropertyValueService.deletePropertyValue(id); return success(true); } @@ -57,7 +62,7 @@ public class ProductPropertyValueController { @Operation(summary = "获得属性值") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult getProperty(@RequestParam("id") Long id) { + public CommonResult getPropertyValue(@RequestParam("id") Long id) { return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id))); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index f28220046..e9c9bb48c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -38,11 +38,6 @@ public class ProductSkuBaseVO { @NotNull(message = "图片地址不能为空") private String picUrl; - @Schema(description = "SKU 状态", required = true, example = "1") - @NotNull(message = "SKU 状态不能为空") - @InEnum(CommonStatusEnum.class) - private Integer status; - @Schema(description = "库存", required = true, example = "1") @NotNull(message = "库存不能为空") private Integer stock; @@ -55,21 +50,4 @@ public class ProductSkuBaseVO { @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 private Double volume; - - @Schema(description = "商品属性") - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class Property { - - @Schema(description = "属性编号", required = true, example = "1") - @NotNull(message = "属性编号不能为空") - private Long propertyId; - - @Schema(description = "属性值编号", required = true, example = "1024") - @NotNull(message = "属性值编号不能为空") - private Long valueId; - - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 496475f99..54de91cf1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -1,10 +1,9 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import lombok.*; +import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO") @@ -12,6 +11,21 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { + @Schema(description = "商品属性") + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Property { + + @Schema(description = "属性编号", required = true, example = "1") + @NotNull(message = "属性编号不能为空") + private Long propertyId; + + @Schema(description = "属性值编号", required = true, example = "1024") + @NotNull(message = "属性值编号不能为空") + private Long valueId; + + } /** * 属性数组 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index 95e394ada..a229fa826 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -1,10 +1,9 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import lombok.*; +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; @@ -20,9 +19,26 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { @Schema(description = "创建时间") private LocalDateTime createTime; + @Schema(description = "商品属性") + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Property { + + @Schema(description = "属性编号", required = true, example = "1") + @NotNull(message = "属性编号不能为空") + private Long propertyId; + + @Schema(description = "属性值编号", required = true, example = "1024") + @NotNull(message = "属性值编号不能为空") + private Long valueId; + + @Schema(description = "属性值", example = "1024") + private String value; + } /** * 属性数组 */ - private List properties; + private List properties; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 04430764b..a314318fc 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -87,7 +87,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { // 1、校验属性项存在 Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(ProductSkuBaseVO.Property::getPropertyId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .map(ProductSkuCreateOrUpdateReqVO.Property::getPropertyId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 .collect(Collectors.toSet()); List propertyList = productPropertyService.getPropertyList(propertyIds); if (propertyList.size() != propertyIds.size()) { @@ -114,7 +114,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { // 4. 最后校验,每个 Sku 之间不是重复的 Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. for (ProductSkuCreateOrUpdateReqVO sku : skus) { - if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuBaseVO.Property::getValueId))) { // 添加失败,说明重复 + if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuCreateOrUpdateReqVO.Property::getValueId))) { // 添加失败,说明重复 throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index ec088cfdd..a6651c8b2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -68,11 +68,9 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { List skus = Arrays.asList( randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试更新 o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 20L))); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }), randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试新增 o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 40L))); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }) ); From c10ea9d9de6101e257c9e13d27f4b452f7950310 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 30 Apr 2023 17:35:05 +0800 Subject: [PATCH 023/232] =?UTF-8?q?=E7=A7=BB=E9=99=A4ProductSku=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84status=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9Property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../convert/property/ProductPropertyConvert.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java index 211bcc293..368da9416 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.convert.property; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; @@ -11,9 +12,12 @@ import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyVa import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +import java.util.Collections; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + /** * 属性项 Convert * @@ -38,7 +42,12 @@ public interface ProductPropertyConvert { Map> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId); return CollectionUtils.convertList(keys, key -> { ProductPropertyAndValueRespVO respVO = convert02(key); - respVO.setValues(convertList02(valueMap.get(key.getId()))); + // 如果属性值为空value不为null,返回空列表 + if (CollUtil.isEmpty(values)) { + respVO.setValues(Collections.emptyList()); + }else { + respVO.setValues(convertList02(valueMap.get(key.getId()))); + } return respVO; }); } From 15ced47b170f75ccb52c45953a6ea38344333c08 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 30 Apr 2023 17:35:38 +0800 Subject: [PATCH 024/232] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=9A=E7=A7=9F?= =?UTF-8?q?=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-mall/yudao-module-product-biz/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index 8a06a4cde..72c37cb20 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -35,6 +35,10 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog + + cn.iocoder.boot + yudao-spring-boot-starter-biz-tenant + From da162853ec245d4261a2a6a3c9536dca81ba1b24 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 30 Apr 2023 20:32:01 +0800 Subject: [PATCH 025/232] =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E8=B4=AD=E7=89=A9=E8=BD=A6=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/core/mapper/BaseMapperX.java | 12 ++ .../api/sku/dto/ProductSkuRespDTO.java | 12 +- .../api/spu/dto/ProductSpuRespDTO.java | 55 +++---- .../product/api/sku/ProductSkuApiImpl.java | 7 +- .../spu/vo/AppProductSpuPageItemRespVO.java | 3 + .../dal/dataobject/sku/ProductSkuDO.java | 21 ++- .../property/ProductPropertyServiceImpl.java | 1 + .../ProductPropertyValueServiceImpl.java | 1 + .../service/sku/ProductSkuServiceTest.java | 6 +- .../app/base/spu/AppProductSpuBaseRespVO.java | 2 +- .../app/cart/TradeCartController.http | 30 ++-- .../app/cart/TradeCartController.java | 47 +++--- ...ntReqVO.java => AppTradeCartAddReqVO.java} | 6 +- .../app/cart/vo/AppTradeCartDetailRespVO.java | 117 -------------- .../app/cart/vo/AppTradeCartListRespVO.java | 45 ++++++ ...eqVO.java => AppTradeCartUpdateReqVO.java} | 10 +- .../trade/convert/cart/TradeCartConvert.java | 65 ++++---- ...{TradeCartItemDO.java => TradeCartDO.java} | 52 +++--- .../dal/mysql/cart/TradeCartItemMapper.java | 47 ------ .../trade/dal/mysql/cart/TradeCartMapper.java | 56 +++++++ .../trade/service/cart/TradeCartService.java | 32 ++-- .../service/cart/TradeCartServiceImpl.java | 152 +++++++----------- 22 files changed, 349 insertions(+), 430 deletions(-) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/{AppTradeCartItemAddCountReqVO.java => AppTradeCartAddReqVO.java} (75%) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartListRespVO.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/{AppTradeCartItemUpdateCountReqVO.java => AppTradeCartUpdateReqVO.java} (60%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/{TradeCartItemDO.java => TradeCartDO.java} (61%) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java index 9819bf551..87cf0dddc 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java @@ -46,6 +46,18 @@ public interface BaseMapperX extends MPJBaseMapper { return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2)); } + default T selectOne(SFunction field1, Object value1, SFunction field2, Object value2, + SFunction field3, Object value3) { + return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2) + .eq(field3, value3)); + } + + default T selectOne(SFunction field1, Object value1, SFunction field2, Object value2, + SFunction field3, Object value3, SFunction field4, Object value4) { + return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2) + .eq(field3, value3).eq(field4, value4)); + } + default Long selectCount() { return selectCount(new QueryWrapper()); } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index aaaf767f2..9197c6147 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -28,7 +28,7 @@ public class ProductSkuRespDTO { private String spuName; /** - * 属性数组,JSON 格式 + * 属性数组 */ private List properties; /** @@ -84,12 +84,20 @@ public class ProductSkuRespDTO { * 属性编号 */ private Long propertyId; + /** + * 属性名字 + */ + private String propertyName; + /** * 属性值编号 */ private Long valueId; + /** + * 属性值名字 + */ + private String valueName; } - } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java index 5c4ee9bb7..acce738a7 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -29,17 +29,23 @@ public class ProductSpuRespDTO { */ private String name; /** - * 商品编码 + * 关键字 */ - private String code; + private String keyword; /** - * 促销语 + * 商品简介 */ - private String sellPoint; + private String introduction; /** * 商品详情 */ private String description; + // TODO @芋艿:是不是要删除 + /** + * 商品条码(一维码) + */ + private String barCode; + /** * 商品分类编号 */ @@ -49,13 +55,13 @@ public class ProductSpuRespDTO { */ private Long brandId; /** - * 商品图片的数组 - *

- * 1. 第一张图片将作为商品主图,支持同时上传多张图; - * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; - * 3. 至少 1 张,最多上传 10 张 + * 商品封面图 */ - private List picUrls; + private String picUrl; + /** + * 商品轮播图 + */ + private List sliderPicUrls; /** * 商品视频 */ @@ -76,38 +82,27 @@ public class ProductSpuRespDTO { /** * 规格类型 - *

- * 枚举 {@link ProductSpuSpecTypeEnum} + * + * false - 单规格 + * true - 多规格 */ private Boolean specType; /** - * 最小价格,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值 + * 商品价格,单位使用:分 */ - private Integer minPrice; - /** - * 最大价格,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值 - */ - private Integer maxPrice; + private Integer price; /** * 市场价,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值 */ private Integer marketPrice; /** - * 总库存 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和 + * 成本价,单位使用:分 */ - private Integer totalStock; + private Integer costPrice; /** - * 是否展示库存 + * 库存 */ - private Boolean showStock; + private Integer stock; // ========== 统计相关字段 ========= diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java index 89913c70e..6bec2a74c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java @@ -15,7 +15,8 @@ import java.util.Collections; import java.util.List; /** - * TODO LeeYan9: 类注释; + * 商品 SKU API 实现类 + * * @author LeeYan9 * @since 2022-09-06 */ @@ -28,8 +29,8 @@ public class ProductSkuApiImpl implements ProductSkuApi { @Override public ProductSkuRespDTO getSku(Long id) { - // TODO TODO LeeYan9: 需要实现 - return null; + ProductSkuDO sku = productSkuService.getSku(id); + return ProductSkuConvert.INSTANCE.convert02(sku); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java index 97513c3bc..68812b754 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java @@ -26,6 +26,9 @@ public class AppProductSpuPageItemRespVO { // ========== SKU 相关字段 ========= + @Schema(description = "规格类型", required = true, example = "true") + private Boolean specType; + @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") private Integer price; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index a9488563a..b759ae5ee 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -109,12 +109,29 @@ public class ProductSkuDO extends BaseDO { * 关联 {@link ProductPropertyDO#getId()} */ private Long propertyId; + /** + * 属性名字 + * + * 冗余 {@link ProductPropertyDO#getName()} + * + * 注意:每次属性名字发生变化时,需要更新该冗余 + */ + private String propertyName; + /** * 属性值编号 * * 关联 {@link ProductPropertyValueDO#getId()} */ private Long valueId; + /** + * 属性值名字 + * + * 冗余 {@link ProductPropertyValueDO#getName()} + * + * 注意:每次属性值名字发生变化时,需要更新该冗余 + */ + private String valueName; } @@ -139,9 +156,5 @@ public class ProductSkuDO extends BaseDO { // TODO 芋艿:pinkStock from y // TODO 芋艿:seckillStock from y - // TODO 芋艿:quota from c - // TODO 芋艿:quotaShow from c - // TODO 芋艿:attrValue from c - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index 328c343d6..3468f2d60 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -67,6 +67,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { // 更新 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); productPropertyMapper.updateById(updateObj); + // TODO 芋艿:更新时,需要看看 sku 表 } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index e5bc6874b..231b79b68 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -68,6 +68,7 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ // 更新 ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); productPropertyValueMapper.updateById(updateObj); + // TODO 芋艿:更新时,需要看看 sku 表 } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index ec088cfdd..2e8ade7fc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -54,12 +54,14 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { // mock 数据 ProductSkuDO sku01 = randomPojo(ProductSkuDO.class, o -> { // 测试更新 o.setSpuId(1L); - o.setProperties(singletonList(new ProductSkuDO.Property(10L, 20L))); + o.setProperties(singletonList(new ProductSkuDO.Property( + 10L, "颜色", 20L, "红色"))); }); productSkuMapper.insert(sku01); ProductSkuDO sku02 = randomPojo(ProductSkuDO.class, o -> { // 测试删除 o.setSpuId(1L); - o.setProperties(singletonList(new ProductSkuDO.Property(10L, 30L))); + o.setProperties(singletonList(new ProductSkuDO.Property( + 10L, "颜色", 30L, "蓝色"))); }); productSkuMapper.insert(sku02); // 准备参数 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java index b73be6e0c..04359c810 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java @@ -20,6 +20,6 @@ public class AppProductSpuBaseRespVO { private String name; @Schema(description = "商品主图地址", example = "https://www.iocoder.cn/xx.png") - private List picUrls; + private String picUrl; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http index 3ce8797fc..ead0fa72f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http @@ -1,38 +1,28 @@ -### 请求 /trade/cart/add-count 接口 => 成功 -POST {{appApi}}/trade/cart/add-count +### 请求 /trade/cart/add 接口 => 成功 +POST {{appApi}}/trade/cart/add tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} Content-Type: application/json { "skuId": 1, - "count": 1 + "count": 10, + "addStatus": true } -### 请求 /trade/cart/update-count 接口 => 成功 -PUT {{appApi}}/trade/cart/update-count +### 请求 /trade/cart/update 接口 => 成功 +PUT {{appApi}}/trade/cart/update tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} Content-Type: application/json { - "skuId": 1, + "id": 35, "count": 5 } -### 请求 /trade/cart/update-selected 接口 => 成功 -PUT {{appApi}}/trade/cart/update-selected -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} -Content-Type: application/json - -{ - "skuIds": [1], - "selected": false -} - ### 请求 /trade/cart/delete 接口 => 成功 -DELETE {{appApi}}/trade/cart/delete?skuIds=1 +DELETE {{appApi}}/trade/cart/delete?ids=1 tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} @@ -41,7 +31,7 @@ GET {{appApi}}/trade/cart/get-count tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} -### 请求 /trade/cart/get-detail 接口 => 成功 -GET {{appApi}}/trade/cart/get-detail +### 请求 /trade/cart/list 接口 => 成功 +GET {{appApi}}/trade/cart/list tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java index 46512a959..d00c2b0f3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java @@ -2,10 +2,9 @@ package cn.iocoder.yudao.module.trade.controller.app.cart; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -33,37 +32,27 @@ public class TradeCartController { @Resource private TradeCartService cartService; - @PostMapping("/add-count") - @Operation(summary = "添加商品到购物车") + @PostMapping("/add") + @Operation(summary = "添加购物车商品") @PreAuthenticated - public CommonResult addCartItemCount(@Valid @RequestBody AppTradeCartItemAddCountReqVO addCountReqVO) { - cartService.addCartItemCount(getLoginUserId(), addCountReqVO); - return success(true); + public CommonResult addCart(@Valid @RequestBody AppTradeCartAddReqVO addCountReqVO) { + return success(cartService.addCart(getLoginUserId(), addCountReqVO)); } - @PutMapping("update-count") - @Operation(summary = "更新购物车商品数量") + @PutMapping("/update") + @Operation(summary = "更新购物车商品") @PreAuthenticated - public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartItemUpdateCountReqVO updateCountReqVO) { - cartService.updateCartItemCount(getLoginUserId(), updateCountReqVO); - return success(true); - } - - @PutMapping("update-selected") - @Operation(summary = "更新购物车商品是否选中") - @PreAuthenticated - public CommonResult updateCartItemSelected(@Valid @RequestBody AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { - cartService.updateCartItemSelected(getLoginUserId(), updateSelectedReqVO); - // 获得目前购物车明细 + public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { + cartService.updateCart(getLoginUserId(), updateReqVO); return success(true); } @DeleteMapping("/delete") @Operation(summary = "删除购物车商品") - @Parameter(name = "skuIds", description = "商品 SKU 编号的数组", required = true, example = "1024,2048") + @Parameter(name = "ids", description = "购物车商品编号", required = true, example = "1024,2048") @PreAuthenticated - public CommonResult deleteCartItem(@RequestParam("skuIds") List skuIds) { - cartService.deleteCartItems(getLoginUserId(), skuIds); + public CommonResult deleteCart(@RequestParam("ids") List ids) { + cartService.deleteCart(getLoginUserId(), ids); return success(true); } @@ -74,11 +63,11 @@ public class TradeCartController { return success(cartService.getCartCount(getLoginUserId())); } - @GetMapping("/get-detail") - @Operation(summary = "查询用户的购物车的详情") + @GetMapping("/list") + @Operation(summary = "查询用户的购物车列表") @PreAuthenticated - public CommonResult getCartDetail() { - return success(cartService.getCartDetail(getLoginUserId())); + public CommonResult getCartList() { + return success(cartService.getCartList(getLoginUserId())); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java similarity index 75% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java index 9b4ba6929..c1e3ebd2f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java @@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull; @Schema(description = "用户 App - 购物车添加购物项 Request VO") @Data -public class AppTradeCartItemAddCountReqVO { +public class AppTradeCartAddReqVO { @Schema(description = "商品 SKU 编号", required = true,example = "1024") @NotNull(message = "商品 SKU 编号不能为空") @@ -19,4 +19,8 @@ public class AppTradeCartItemAddCountReqVO { @Min(message = "数量必须大于 0", value = 1L) private Integer count; + @Schema(description = "是否添加到购物车", required = true, example = "true") + @NotNull(message = "是否添加购物车不能为空") + private Boolean addStatus; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java deleted file mode 100644 index 769418528..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java +++ /dev/null @@ -1,117 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Schema(description = "用户 App - 用户的购物车明细 Response VO") -@Data -public class AppTradeCartDetailRespVO { - - /** - * 商品分组数组 - */ - private List itemGroups; - - /** - * 费用 - */ - private Order order; - - @Schema(description = "商品分组") // 多个商品,参加同一个活动,从而形成分组 - @Data - public static class ItemGroup { - - /** - * 商品数组 - */ - private List items; - /** - * 营销活动,订单级别 - */ - private Promotion promotion; - - } - - @Schema(description = "商品 SKU") - @Data - public static class Sku extends AppProductSkuBaseRespVO { - - /** - * SPU 信息 - */ - private AppProductSkuBaseRespVO spu; - - // ========== 购物车相关的字段 ========== - - @Schema(description = "商品数量", required = true, example = "1") - private Integer count; - @Schema(description = "是否选中", required = true, example = "true") - private Boolean selected; - - // ========== 价格相关的字段,对应 PriceCalculateRespDTO.OrderItem 的属性 ========== - - // TODO 芋艿:后续可以去除一些无用的字段 - - @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer originalPrice; - @Schema(description = "商品原价(总)", required = true, example = "200") - private Integer totalOriginalPrice; - @Schema(description = "商品级优惠(总)", required = true, example = "300") - private Integer totalPromotionPrice; - @Schema(description = "最终购买金额(总)", required = true, example = "400") - private Integer totalPresentPrice; - @Schema(description = "最终购买金额(单)", required = true, example = "500") - private Integer presentPrice; - @Schema(description = "应付金额(总)", required = true, example = "600") - private Integer totalPayPrice; - - // ========== 营销相关的字段 ========== - /** - * 营销活动,商品级别 - */ - private Promotion promotion; - - } - - @Schema(description = "订单") // 对应 PriceCalculateRespDTO.Order 类,用于费用(合计) - @Data - public static class Order { - - // TODO 芋艿:后续可以去除一些无用的字段 - - @Schema(description = "商品原价(总)", required = true, example = "100") - private Integer skuOriginalPrice; - @Schema(description = "商品优惠(总)", required = true, example = "200") - private Integer skuPromotionPrice; - @Schema(description = "订单优惠(总)", required = true, example = "300") - private Integer orderPromotionPrice; - @Schema(description = "运费金额", required = true, example = "400") - private Integer deliveryPrice; - @Schema(description = "应付金额(总)", required = true, example = "500") - private Integer payPrice; - - } - - @Schema(description = "营销活动") // 对应 PriceCalculateRespDTO.Promotion 类的属性 - @Data - public static class Promotion { - - @Schema(description = "营销编号", required = true, example = "1024") // 营销活动的编号、优惠劵的编号 - private Long id; - @Schema(description = "营销名字", required = true, example = "xx 活动") - private String name; - @Schema(description = "营销类型", required = true, example = "1") - private Integer type; - - // ========== 匹配情况 ========== - @Schema(description = "是否满足优惠条件", required = true, example = "true") - private Boolean meet; - @Schema(description = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") - private String meetTip; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartListRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartListRespVO.java new file mode 100644 index 000000000..5f33ece55 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartListRespVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; +import cn.iocoder.yudao.module.trade.controller.app.base.spu.AppProductSpuBaseRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 用户的购物列表 Response VO") +@Data +public class AppTradeCartListRespVO { + + /** + * 有效的购物项数组 + */ + private List validList; + + /** + * 无效的购物项数组 + */ + private List invalidList; + + @Schema(description = "购物项") + @Data + public static class Cart { + + @Schema(description = "购物项的编号", required = true, example = "1024") + private Long id; + + @Schema(description = "商品数量", required = true, example = "1") + private Integer count; + + /** + * 商品 SPU + */ + private AppProductSpuBaseRespVO spu; + /** + * 商品 SKU + */ + private AppProductSkuBaseRespVO sku; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartUpdateReqVO.java similarity index 60% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartUpdateReqVO.java index d3d12487e..4cf72bbf1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartUpdateReqVO.java @@ -6,13 +6,13 @@ import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -@Schema(description = "用户 App - 购物车更新数量 Request VO") +@Schema(description = "用户 App - 购物车更新 Request VO") @Data -public class AppTradeCartItemUpdateCountReqVO { +public class AppTradeCartUpdateReqVO { - @Schema(description = "商品 SKU 编号", required = true, example = "1024") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; + @Schema(description = "编号", required = true, example = "1024") + @NotNull(message = "编号不能为空") + private Long id; @Schema(description = "商品数量", required = true, example = "1") @NotNull(message = "数量不能为空") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java index eb696ae30..c40ce377f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java @@ -1,45 +1,52 @@ package cn.iocoder.yudao.module.trade.convert.cart; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; +import cn.iocoder.yudao.module.trade.controller.app.base.spu.AppProductSpuBaseRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; +import java.util.Map; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; @Mapper public interface TradeCartConvert { TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class); - default AppTradeCartDetailRespVO buildEmptyAppTradeCartDetailRespVO() { - return new AppTradeCartDetailRespVO().setItemGroups(Collections.emptyList()) - .setOrder(new AppTradeCartDetailRespVO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0) - .setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0)); + default AppTradeCartListRespVO convertList(List carts, + List spus, List skus) { + Map spuMap = convertMap(spus, ProductSpuRespDTO::getId); + Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); + // 遍历,开始转换 + List validList = new ArrayList<>(carts.size()); + List invalidList = new ArrayList<>(); + carts.forEach(cart -> { + AppTradeCartListRespVO.Cart cartVO = new AppTradeCartListRespVO.Cart(); + cartVO.setId(cart.getId()).setCount(cart.getCount()); + ProductSpuRespDTO spu = spuMap.get(cart.getSpuId()); + ProductSkuRespDTO sku = skuMap.get(cart.getSkuId()); + cartVO.setSpu(convert(spu)).setSku(convert(sku)); + // 如果 spu 或 sku 不存在,或者 spu 被禁用,说明是非法的,或者 sku 库存不足 + if (spu == null + || sku == null + || !ProductSpuStatusEnum.isEnable(spu.getStatus()) + || sku.getStock() <= 0) { + invalidList.add(cartVO); + } else { + validList.add(cartVO); + } + }); + return new AppTradeCartListRespVO().setValidList(validList).setValidList(invalidList); } - - default PriceCalculateReqDTO convert(Long userId, List cartItems) { - return new PriceCalculateReqDTO().setUserId(userId) - .setItems(convertList(cartItems, cartItem -> new PriceCalculateReqDTO.Item().setSkuId(cartItem.getSkuId()) - .setCount(cartItem.getSelected() ? cartItem.getCount() : 0))); - } - - // ========== AppTradeCartDetailRespVO 相关 ========== - - AppTradeCartDetailRespVO.Promotion convert(PriceCalculateRespDTO.Promotion bean); - - @Mappings({ - @Mapping(source = "cartItem.count", target = "count") - }) - AppTradeCartDetailRespVO.Sku convert(PriceCalculateRespDTO.OrderItem orderItem, TradeCartItemDO cartItem); - - AppTradeCartDetailRespVO.Order convert(PriceCalculateRespDTO.Order bean); + AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu); + AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartDO.java similarity index 61% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartDO.java index 05fbb801d..d9d9697ae 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartDO.java @@ -9,13 +9,15 @@ import lombok.experimental.Accessors; /** * 购物车的商品信息 DO * + * 每个商品,对应一条记录,通过 {@link #spuId} 和 {@link #skuId} 关联 + * * @author 芋道源码 */ -@TableName("trade_cart_item") +@TableName("trade_cart") @Data @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) -public class TradeCartItemDO extends BaseDO { +public class TradeCartDO extends BaseDO { // ========= 基础字段 BEGIN ========= @@ -23,14 +25,6 @@ public class TradeCartItemDO extends BaseDO { * 编号,唯一自增 */ private Long id; - /** - * 是否选中 - */ - private Boolean selected; - - // ========= 基础字段 END ========= - - // ========= 买家信息 BEGIN ========= /** * 用户编号 @@ -39,7 +33,25 @@ public class TradeCartItemDO extends BaseDO { */ private Long userId; - // ========= 买家信息 END ========= + /** + * 是否添加到购物车 + * + * false - 未添加:用户点击【立即购买】 + * true - 已添加:用户点击【添加购物车】 + * + * 为什么要设计这个字段? + * 配合 orderStatus 字段,可以知道有多少商品,用户点击了【立即购买】,最终多少【确认下单】 + */ + private Boolean addStatus; + /** + * 是否提交订单 + * + * false - 未下单:立即购买,或者添加到购物车,此时设置为 false + * true - 已下单:确认下单,此时设置为 true + */ + private Boolean orderStatus; + + // ========= 基础字段 END ========= // ========= 商品信息 BEGIN ========= @@ -64,27 +76,11 @@ public class TradeCartItemDO extends BaseDO { // ========= 优惠信息 BEGIN ========= -// /** -// * 商品营销活动编号 -// */ -// private Long activityId; // discount_id -// /** -// * 商品营销活动类型 -// */ -// private Integer activityType; // TODO 芋艿:combination_id 拼团 ID // TODO 芋艿:seckill_id 秒杀产品 ID // TODO 芋艿:bargain_id 砍价 ID + // TODO 芋艿:pinkId 团长拼团 ID // ========= 优惠信息 END ========= - // TODO 待确定字段:mf - // TODO 芋艿:distribution_card_no 推广员 - // TODO 芋艿:is_pay 未购买、已购买 - // TODO 芋艿:is_new 是否立即购买 - - // TODO 待确定字段: yv - // TODO isPay: 是否购买 - // TODO isNew:是否立即购买 - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java deleted file mode 100644 index fa6adbf41..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.cart; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -@Mapper -public interface TradeCartItemMapper extends BaseMapperX { - - default TradeCartItemDO selectByUserIdAndSkuId(Long userId, Long skuId) { - return selectOne(TradeCartItemDO::getUserId, userId, - TradeCartItemDO::getSkuId, skuId); - } - - default List selectListByUserIdAndSkuIds(Long userId, Collection skuIds) { - return selectList(new LambdaQueryWrapper().eq(TradeCartItemDO::getUserId, userId) - .in(TradeCartItemDO::getSkuId, skuIds)); - } - - default void updateByIds(Collection ids, TradeCartItemDO updateObject) { - update(updateObject, new LambdaQueryWrapper().in(TradeCartItemDO::getId, ids)); - } - - default Integer selectSumByUserId(Long userId) { - // SQL sum 查询 - List> result = selectMaps(new QueryWrapper() - .select("SUM(count) AS sumCount") - .eq("user_id", userId)); - // 获得数量 - return CollUtil.isNotEmpty(result) ? MapUtil.getInt(result.get(0), "sumCount") : 0; - } - - default List selectListByUserId(Long userId, Boolean selected) { - return selectList(new LambdaQueryWrapperX().eq(TradeCartItemDO::getUserId, userId) - .eqIfPresent(TradeCartItemDO::getSelected, selected)); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java new file mode 100644 index 000000000..b1a834c38 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.cart; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +@Mapper +public interface TradeCartMapper extends BaseMapperX { + + default TradeCartDO selectByUserIdAndSkuId(Long userId, Long skuId, + Boolean addStatus, Boolean orderStatus) { + return selectOne(TradeCartDO::getUserId, userId, + TradeCartDO::getSkuId, skuId, + TradeCartDO::getAddStatus, addStatus, + TradeCartDO::getOrderStatus, orderStatus); + } + + default Integer selectSumByUserId(Long userId) { + // SQL sum 查询 + List> result = selectMaps(new QueryWrapper() + .select("SUM(count) AS sumCount") + .eq("user_id", userId) + .eq("add_status", true) // 只计算添加到购物车中的 + .eq("order_status", false)); // 必须未下单 + // 获得数量 + return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; + } + + default TradeCartDO selectById(Long id, Long userId) { + return selectOne(TradeCartDO::getId, id, + TradeCartDO::getUserId, userId); + } + + default List selectListByIds(Collection ids, Long userId) { + return selectList(new LambdaQueryWrapper() + .in(TradeCartDO::getId, ids) + .eq(TradeCartDO::getUserId, userId)); + } + + default List selectListByUserId(Long userId) { + return selectList(TradeCartDO::getUserId, userId); + } + + default void updateByIds(Collection ids, TradeCartDO updateObject) { + update(updateObject, new LambdaQueryWrapper().in(TradeCartDO::getId, ids)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java index 3f46f5102..bb06374b6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.trade.service.cart; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import javax.validation.Valid; import java.util.Collection; @@ -19,9 +18,10 @@ public interface TradeCartService { * 添加商品到购物车 * * @param userId 用户编号 - * @param addCountReqVO 添加信息 + * @param addReqVO 添加信息 + * @return 购物项的编号 */ - void addCartItemCount(Long userId, @Valid AppTradeCartItemAddCountReqVO addCountReqVO); + Long addCart(Long userId, @Valid AppTradeCartAddReqVO addReqVO); /** * 更新购物车商品数量 @@ -29,23 +29,15 @@ public interface TradeCartService { * @param userId 用户编号 * @param updateCountReqVO 更新信息 */ - void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO); - - /** - * 更新购物车商品是否选中 - * - * @param userId 用户编号 - * @param updateSelectedReqVO 更新信息 - */ - void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO); + void updateCart(Long userId, AppTradeCartUpdateReqVO updateCountReqVO); /** * 删除购物车商品 * * @param userId 用户编号 - * @param skuIds SKU 编号的数组 + * @param ids 购物项的编号 */ - void deleteCartItems(Long userId, Collection skuIds); + void deleteCart(Long userId, Collection ids); /** * 查询用户在购物车中的商品数量 @@ -56,11 +48,11 @@ public interface TradeCartService { Integer getCartCount(Long userId); /** - * 查询用户的购物车详情 + * 查询用户的购物车列表 * * @param userId 用户编号 - * @return 购物车详情 + * @return 购物车列表 */ - AppTradeCartDetailRespVO getCartDetail(Long userId); + AppTradeCartListRespVO getCartList(Long userId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index ae0301e83..9539a19c5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -1,39 +1,38 @@ package cn.iocoder.yudao.module.trade.service.cart; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartItemMapper; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; +import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.List; -import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND; +import static java.util.Collections.emptyList; /** * 购物车 Service 实现类 * + * // TODO 芋艿:秒杀、拼团、砍价对购物车的影响 + * // TODO 芋艿:未来优化:购物车的价格计算,支持营销信息 + * * @author 芋道源码 */ @Service @@ -41,123 +40,92 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_N public class TradeCartServiceImpl implements TradeCartService { @Resource - private TradeCartItemMapper cartItemMapper; + private TradeCartMapper cartMapper; + @Resource + private ProductSpuApi productSpuApi; @Resource private ProductSkuApi productSkuApi; - @Resource - private PriceApi priceApi; @Override - public void addCartItemCount(Long userId, AppTradeCartItemAddCountReqVO addCountReqVO) { - Long skuId = addCountReqVO.getSkuId(); - Integer count = addCountReqVO.getCount(); - // 查询 CartItemDO - TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, addCountReqVO.getSkuId()); + public Long addCart(Long userId, AppTradeCartAddReqVO addReqVO) { + // 查询 TradeCartDO + TradeCartDO cart = cartMapper.selectByUserIdAndSkuId(userId, addReqVO.getSkuId(), + addReqVO.getAddStatus(), false); + // 校验 SKU + Integer count = cart != null && addReqVO.getAddStatus() ? + cart.getCount() + addReqVO.getCount() : addReqVO.getCount(); + ProductSkuRespDTO sku = checkProductSku(addReqVO.getSkuId(), count); - // 存在,则进行数量更新 - if (tradeItem != null) { - checkProductSku(skuId, tradeItem.getCount() + count); - cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()) - .setSelected(true).setCount(tradeItem.getCount() + count)); - return; + // 情况一:存在,则进行数量更新 + if (cart != null) { + cartMapper.updateById(new TradeCartDO().setId(cart.getId()).setCount(count)); + return cart.getId(); + // 情况二:不存在,则进行插入 + } else { + cart = new TradeCartDO().setUserId(userId) + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) + .setAddStatus(addReqVO.getAddStatus()).setOrderStatus(false); + cartMapper.insert(cart); } - - // 不存在,则进行插入 - ProductSkuRespDTO sku = checkProductSku(skuId, count); - cartItemMapper.insert(new TradeCartItemDO().setUserId(userId).setSpuId(sku.getSpuId()).setSkuId(sku.getId()) - .setSelected(true).setCount(count)); + return cart.getId(); } @Override - public void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO) { - // 校验 TradeCartItemDO 存在 - TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, updateCountReqVO.getSkuId()); - if (tradeItem == null) { + public void updateCart(Long userId, AppTradeCartUpdateReqVO updateReqVO) { + // 校验 TradeCartDO 存在 + TradeCartDO cart = cartMapper.selectById(updateReqVO.getId(), userId); + if (cart == null) { throw exception(CARD_ITEM_NOT_FOUND); } // 校验商品 SKU - checkProductSku(updateCountReqVO.getSkuId(), updateCountReqVO.getCount()); + checkProductSku(cart.getSkuId(), updateReqVO.getCount()); // 更新数量 - cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()).setCount(updateCountReqVO.getCount())); - } - - @Override - public void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { - // 查询 CartItemDO 列表 - List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, updateSelectedReqVO.getSkuIds()); - if (CollUtil.isEmpty(cartItems)) { - return; - } - - // 更新选中 - cartItemMapper.updateByIds(CollectionUtils.convertList(cartItems, TradeCartItemDO::getId), - new TradeCartItemDO().setSelected(updateSelectedReqVO.getSelected())); + cartMapper.updateById(new TradeCartDO().setId(cart.getId()) + .setCount(updateReqVO.getCount())); } /** * 购物车删除商品 * * @param userId 用户编号 - * @param skuIds 商品 SKU 编号的数组 + * @param ids 商品 SKU 编号的数组 */ @Override - public void deleteCartItems(Long userId, Collection skuIds) { - // 查询 CartItemDO 列表 - List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds); - if (CollUtil.isEmpty(cartItems)) { + public void deleteCart(Long userId, Collection ids) { + // 查询 TradeCartDO 列表 + List carts = cartMapper.selectListByIds(ids, userId); + if (CollUtil.isEmpty(carts)) { return; } // 批量标记删除 - cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(cartItems, TradeCartItemDO::getId)); + cartMapper.deleteBatchIds(ids); } @Override public Integer getCartCount(Long userId) { - return cartItemMapper.selectSumByUserId(userId); + return cartMapper.selectSumByUserId(userId); } @Override - public AppTradeCartDetailRespVO getCartDetail(Long userId) { + public AppTradeCartListRespVO getCartList(Long userId) { // 获得购物车的商品 - List cartItems = cartItemMapper.selectListByUserId(userId, null); + List carts = cartMapper.selectListByUserId(userId); + carts.sort(Comparator.comparing(TradeCartDO::getId).reversed()); // 如果未空,则返回空结果 - if (CollUtil.isEmpty(cartItems)) { - return TradeCartConvert.INSTANCE.buildEmptyAppTradeCartDetailRespVO(); + if (CollUtil.isEmpty(carts)) { + return new AppTradeCartListRespVO().setValidList(emptyList()) + .setInvalidList(emptyList()); } - // 调用价格服务,计算价格 - PriceCalculateRespDTO priceCalculate = priceApi.calculatePrice(TradeCartConvert.INSTANCE.convert(userId, cartItems)); + // 查询 SPU、SKU 列表 + List spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId)); + List skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSpuId)); - // 转换返回 - Map cartItemMap = convertMap(cartItems, TradeCartItemDO::getSkuId); - Map orderItemMap = convertMap(priceCalculate.getOrder().getItems(), - PriceCalculateRespDTO.OrderItem::getSkuId); - List itemGroups = new ArrayList<>(cartItems.size()); - // ① 场景一,营销活动,订单级别 TODO 芋艿:待测试 - priceCalculate.getPromotions().stream().filter(promotion -> PromotionLevelEnum.ORDER.getLevel().equals(promotion.getLevel())) - .forEach(promotion -> { - AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>()) - .setPromotion(TradeCartConvert.INSTANCE.convert(promotion)); - itemGroups.add(itemGroup); - promotion.getItems().forEach(promotionItem -> { - PriceCalculateRespDTO.OrderItem orderItem = orderItemMap.remove(promotionItem.getSkuId()); - Assert.notNull(orderItem, "商品 SKU({}) 对应的订单项不能为空", promotionItem.getSkuId()); - TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); - itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu - }); - }); - // ② 场景二,营销活动,商品级别 - orderItemMap.values().forEach(orderItem -> { - AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>(1)).setPromotion(null); - itemGroups.add(itemGroup); - TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); - itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu - }); - return new AppTradeCartDetailRespVO().setItemGroups(itemGroups) - .setOrder(TradeCartConvert.INSTANCE.convert(priceCalculate.getOrder())); + // 拼接数据 + return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); } /** From 6428f0fcafdb667c0266fe3d2df90ff323285b14 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 1 May 2023 14:47:00 +0800 Subject: [PATCH 026/232] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=95=86=E5=93=81?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/spu/ProductUnitEnum.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java new file mode 100644 index 000000000..6d463ffb5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.product.enums.spu; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 产品单位枚举 + * + * @author HUIHUI + */ +@Getter +@AllArgsConstructor +public enum ProductUnitEnum implements IntArrayValuable { + PIECE(1, "个"), + DOZEN(2, "打"), + BOX(3, "盒"), + BAG(4, "袋"), + CASE(5, "箱"), + SET(6, "套"), + PACK(7, "包"), + PAIR(8, "双"), + ROLL(9, "卷"), + SHEET(10, "张"), + WEIGHT(11, "克"), + KILOGRAM(12, "千克"), + MILLIGRAM(13, "毫克"), + MICROGRAM(14, "微克"), + TON(15, "吨"), + LITER(16, "升"), + MILLILITER(17, "毫升"), + SQUARE_METER(19, "平方米"), + SQUARE_KILOMETER(20, "平方千米"), + SQUARE_MILE(21, "平方英里"), + SQUARE_YARD(22, "平方码"), + SQUARE_FOOT(23, "平方英尺"), + CUBIC_METER(24, "立方米"), + CUBIC_CENTIMETER(25, "立方厘米"), + CUBIC_INCH(26, "立方英寸"), + METER(27, "米"), + CENTIMETER(29, "厘米"), + MILLIMETER(30, "毫米"), + INCH(31, "英寸"), + FOOT(32, "英尺"), + YARD(33, "码"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductUnitEnum::getStatus).toArray(); + + /** + * 状态 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} From f7fe9ad7b0c19f2c2fc12bc518b34ee991ac5283 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 1 May 2023 16:00:37 +0800 Subject: [PATCH 027/232] =?UTF-8?q?1.=20=E5=95=86=E5=9F=8E=EF=BC=9A?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=B4=AD=E7=89=A9=E8=BD=A6=E7=9A=84=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E9=80=BB=E8=BE=91=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=20SPU=20=E6=98=AF=E5=90=A6=E4=B8=8B=E6=9E=B6=202.=20?= =?UTF-8?q?=E5=95=86=E5=9F=8E=EF=BC=9A=E5=A2=9E=E5=8A=A0=E8=B4=AD=E7=89=A9?= =?UTF-8?q?=E8=BD=A6=E5=A4=B1=E6=95=88=E7=9A=84=E9=87=8D=E9=80=89=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/sku/dto/ProductSkuRespDTO.java | 11 ----- .../trade/enums/ErrorCodeConstants.java | 1 - .../app/base/sku/AppProductSkuBaseRespVO.java | 6 +-- .../app/cart/TradeCartController.java | 11 ++++- .../AppTradeCartItemUpdateSelectedReqVO.java | 21 --------- .../app/cart/vo/AppTradeCartResetReqVO.java | 26 ++++++++++ .../trade/convert/cart/TradeCartConvert.java | 8 ++-- .../trade/dal/mysql/cart/TradeCartMapper.java | 7 ++- .../trade/service/cart/TradeCartService.java | 13 ++++- .../service/cart/TradeCartServiceImpl.java | 47 +++++++++++++++++-- .../service/order/TradeOrderServiceImpl.java | 8 +--- 11 files changed, 103 insertions(+), 56 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index 9197c6147..7f5e7aed8 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.api.sku.dto; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import lombok.Data; import java.util.List; @@ -22,10 +21,6 @@ public class ProductSkuRespDTO { * SPU 编号 */ private Long spuId; - /** - * SPU 名字 - */ - private String spuName; /** * 属性数组 @@ -51,12 +46,6 @@ public class ProductSkuRespDTO { * 图片地址 */ private String picUrl; - /** - * SKU 状态 - *

- * 枚举 {@link CommonStatusEnum} - */ - private Integer status; /** * 库存 */ diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index af387ab85..d6c314147 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -14,7 +14,6 @@ public interface ErrorCodeConstants { // ========== Order 模块 1-011-000-000 ========== ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); - ErrorCode ORDER_CREATE_SKU_NOT_SALE = new ErrorCode(1011000003, "商品 SKU 不可售卖"); ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖"); ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java index 053e329b4..bb2c60482 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java @@ -17,12 +17,12 @@ public class AppProductSkuBaseRespVO { @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(description = "商品 SKU 名字", required = true, example = "芋道") - private String name; - @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") private String picUrl; + @Schema(description = "销售价格,单位:分", required = true, example = "100") + private Integer price; + @Schema(description = "库存", required = true, example = "1") private Integer stock; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java index d00c2b0f3..79105ced6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; import io.swagger.v3.oas.annotations.Operation; @@ -42,11 +43,19 @@ public class TradeCartController { @PutMapping("/update") @Operation(summary = "更新购物车商品") @PreAuthenticated - public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { + public CommonResult updateCart(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { cartService.updateCart(getLoginUserId(), updateReqVO); return success(true); } + @PutMapping("/reset") + @Operation(summary = "重置购物车商品") + @PreAuthenticated + public CommonResult resetCart(@Valid @RequestBody AppTradeCartResetReqVO updateReqVO) { + cartService.resetCart(getLoginUserId(), updateReqVO); + return success(true); + } + @DeleteMapping("/delete") @Operation(summary = "删除购物车商品") @Parameter(name = "ids", description = "购物车商品编号", required = true, example = "1024,2048") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java deleted file mode 100644 index 62327f320..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.util.Collection; - -@Schema(description = "用户 App - 购物车更新是否选中 Request VO") -@Data -public class AppTradeCartItemUpdateSelectedReqVO { - - @Schema(description = "商品 SKU 编号列表", required = true, example = "1024,2048") - @NotNull(message = "商品 SKU 编号列表不能为空") - private Collection skuIds; - - @Schema(description = "是否选中", required = true, example = "true") - @NotNull(message = "是否选中不能为空") - private Boolean selected; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java new file mode 100644 index 000000000..eb8a81c80 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 App - 购物车重置 Request VO") +@Data +public class AppTradeCartResetReqVO { + + @Schema(description = "编号", required = true, example = "1024") + @NotNull(message = "编号不能为空") + private Long id; + + @Schema(description = "商品 SKU 编号", required = true,example = "1024") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "商品数量", required = true, example = "1") + @NotNull(message = "数量不能为空") + @Min(message = "数量必须大于 0", value = 1L) + private Integer count; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java index c40ce377f..519b82fc9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java @@ -34,17 +34,17 @@ public interface TradeCartConvert { ProductSpuRespDTO spu = spuMap.get(cart.getSpuId()); ProductSkuRespDTO sku = skuMap.get(cart.getSkuId()); cartVO.setSpu(convert(spu)).setSku(convert(sku)); - // 如果 spu 或 sku 不存在,或者 spu 被禁用,说明是非法的,或者 sku 库存不足 + // 如果 SPU 不存在,或者下架,或者库存不足,说明是无效的 if (spu == null - || sku == null || !ProductSpuStatusEnum.isEnable(spu.getStatus()) - || sku.getStock() <= 0) { + || spu.getStock() <= 0) { invalidList.add(cartVO); } else { + // 虽然 SKU 可能也会不存在,但是可以通过购物车重新选择 validList.add(cartVO); } }); - return new AppTradeCartListRespVO().setValidList(validList).setValidList(invalidList); + return new AppTradeCartListRespVO().setValidList(validList).setInvalidList(invalidList); } AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu); AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java index b1a834c38..6c44dc279 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java @@ -45,8 +45,11 @@ public interface TradeCartMapper extends BaseMapperX { .eq(TradeCartDO::getUserId, userId)); } - default List selectListByUserId(Long userId) { - return selectList(TradeCartDO::getUserId, userId); + default List selectListByUserId(Long userId, Boolean addStatus, Boolean orderStatus) { + return selectList(new LambdaQueryWrapper() + .eq(TradeCartDO::getUserId, userId) + .eq(TradeCartDO::getAddStatus, addStatus) + .eq(TradeCartDO::getOrderStatus, orderStatus)); } default void updateByIds(Collection ids, TradeCartDO updateObject) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java index bb06374b6..9b87762c9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.trade.service.cart; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import javax.validation.Valid; @@ -31,6 +32,16 @@ public interface TradeCartService { */ void updateCart(Long userId, AppTradeCartUpdateReqVO updateCountReqVO); + /** + * 重置购物车商品 + * + * 使用场景:在一个购物车项对应的商品失效(例如说 SPU 被下架),可以重新选择对应的 SKU + * + * @param userId 用户编号 + * @param updateReqVO 重置信息 + */ + void resetCart(Long userId, AppTradeCartResetReqVO updateReqVO); + /** * 删除购物车商品 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index 9539a19c5..ffd75a07a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -1,18 +1,19 @@ package cn.iocoder.yudao.module.trade.service.cart; import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; @@ -86,6 +87,28 @@ public class TradeCartServiceImpl implements TradeCartService { .setCount(updateReqVO.getCount())); } + @Override + @Transactional(rollbackFor = Exception.class) + public void resetCart(Long userId, AppTradeCartResetReqVO resetReqVO) { + // 第一步:删除原本的购物项 + TradeCartDO oldCart = cartMapper.selectById(resetReqVO.getId(), userId); + if (oldCart == null) { + throw exception(CARD_ITEM_NOT_FOUND); + } + cartMapper.deleteById(oldCart.getId()); + + // 第二步:添加新的购物项 + TradeCartDO newCart = cartMapper.selectByUserIdAndSkuId(userId, resetReqVO.getSkuId(), + true, false); + if (newCart != null) { + updateCart(userId, new AppTradeCartUpdateReqVO() + .setId(newCart.getId()).setCount(resetReqVO.getCount())); + } else { + addCart(userId, new AppTradeCartAddReqVO().setAddStatus(true) + .setSkuId(resetReqVO.getSkuId()).setCount(resetReqVO.getCount())); + } + } + /** * 购物车删除商品 * @@ -111,8 +134,8 @@ public class TradeCartServiceImpl implements TradeCartService { @Override public AppTradeCartListRespVO getCartList(Long userId) { - // 获得购物车的商品 - List carts = cartMapper.selectListByUserId(userId); + // 获得购物车的商品,只查询未下单的 + List carts = cartMapper.selectListByUserId(userId, true, false); carts.sort(Comparator.comparing(TradeCartDO::getId).reversed()); // 如果未空,则返回空结果 if (CollUtil.isEmpty(carts)) { @@ -122,12 +145,26 @@ public class TradeCartServiceImpl implements TradeCartService { // 查询 SPU、SKU 列表 List spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId)); - List skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSpuId)); + List skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSkuId)); + + // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 + deleteCartIfSpuDeleted(carts, spus); // 拼接数据 return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); } + private void deleteCartIfSpuDeleted(List carts, List spus) { + // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 + carts.removeIf(cart -> { + if (spus.stream().noneMatch(spu -> spu.getId().equals(cart.getSpuId()))) { + cartMapper.deleteById(cart.getId()); + return true; + } + return false; + }); + } + /** * 校验商品 SKU 是否合法 * 1. 是否存在 @@ -140,7 +177,7 @@ public class TradeCartServiceImpl implements TradeCartService { */ private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) { ProductSkuRespDTO sku = productSkuApi.getSku(skuId); - if (sku == null || CommonStatusEnum.DISABLE.getStatus().equals(sku.getStatus())) { + if (sku == null) { throw exception(SKU_NOT_EXISTS); } if (count > sku.getStock()) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 86d84c415..464cb86a7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -5,7 +5,6 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.core.KeyValue; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -125,15 +124,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { if (items.size() != skus.size()) { throw exception(ORDER_CREATE_SKU_NOT_FOUND); } - // 校验是否禁用 or 库存不足 + // 校验库存不足 Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); items.forEach(item -> { ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); - // SKU 禁用 - if (ObjectUtil.notEqual(CommonStatusEnum.ENABLE.getStatus(), sku.getStatus())) { - throw exception(ORDER_CREATE_SKU_NOT_SALE); - } - // SKU 库存不足 if (item.getCount() > sku.getStock()) { throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); } From 70816371e51ae57c3b85ee236c28b437dfd65c81 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 2 May 2023 02:33:14 +0800 Subject: [PATCH 028/232] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=95=86=E5=93=81CRUD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/sku/vo/ProductSkuBaseVO.java | 10 +++ .../admin/spu/ProductSpuController.java | 2 +- .../admin/spu/vo/ProductSpuBaseVO.java | 61 ++++------------- .../admin/spu/vo/ProductSpuPageReqVO.java | 24 ------- .../admin/spu/vo/ProductSpuPageRespVO.java | 31 +++++++++ .../admin/spu/vo/ProductSpuRespVO.java | 18 ----- .../convert/sku/ProductSkuConvert.java | 3 +- .../convert/spu/ProductSpuConvert.java | 2 +- .../dal/dataobject/spu/ProductSpuDO.java | 6 +- .../dal/mysql/spu/ProductSpuMapper.java | 13 ---- .../category/ProductCategoryServiceImpl.java | 2 +- .../service/sku/ProductSkuService.java | 6 +- .../service/sku/ProductSkuServiceImpl.java | 30 ++++++--- .../service/spu/ProductSpuServiceImpl.java | 65 +++++++++++-------- .../service/sku/ProductSkuServiceTest.java | 2 +- .../spu/ProductSpuServiceImplTest.java | 42 +++--------- 16 files changed, 133 insertions(+), 184 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index e9c9bb48c..dde623b50 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -50,4 +50,14 @@ public class ProductSkuBaseVO { @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 private Double volume; + /** + * 一级分销的佣金,单位:分 + */ + @Schema(description = "一级分销的佣金", example = "1024") + private Integer subCommissionFirstPrice; + /** + * 二级分销的佣金,单位:分 + */ + @Schema(description = "二级分销的佣金", example = "1024") + private Integer subCommissionSecondPrice; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 85fa93f8e..f2ce90c1d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -94,7 +94,7 @@ public class ProductSpuController { @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { + public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index e7a30484d..251b4be47 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -38,16 +38,11 @@ public class ProductSpuBaseVO { @NotEmpty(message = "商品详情不能为空") private String description; - @Schema(description = "商品条码(一维码)", required = true, example = "芋道") - @NotEmpty(message = "商品条码(一维码)不能为空") - private String barCode; - @Schema(description = "商品分类编号", required = true, example = "芋道") - @NotEmpty(message = "商品分类编号不能为空") + @NotNull(message = "商品分类编号不能为空") private Long categoryId; @Schema(description = "商品品牌编号", required = true, example = "芋道") - @NotEmpty(message = "商品品牌编号不能为空") private Long brandId; @Schema(description = "商品封面图", required = true, example = "芋道") @@ -55,99 +50,71 @@ public class ProductSpuBaseVO { private String picUrl; @Schema(description = "商品轮播图", required = true) - @NotEmpty(message = "商品轮播图不能为空") private List sliderPicUrls; @Schema(description = "商品视频") private String videoUrl; @Schema(description = "单位", required = true, example = "1") - @NotEmpty(message = "商品单位不能为空") + @NotNull(message = "商品单位不能为空") private Integer unit; @Schema(description = "排序字段", required = true, example = "1") - @NotEmpty(message = "商品排序字段不能为空") + @NotNull(message = "商品排序字段不能为空") private Integer sort; - @Schema(description = "商品状态", required = true, example = "1") - @NotEmpty(message = "商品状态不能为空") - private Integer status; - // ========== SKU 相关字段 ========= @Schema(description = "规格类型", required = true, example = "true") - @NotEmpty(message = "商品规格类型不能为空") + @NotNull(message = "商品规格类型不能为空") private Boolean specType; - @Schema(description = "商品价格", required = true, example = "1212") - @NotEmpty(message = "商品价格不能为空") - private Integer price; - - @Schema(description = "市场价", required = true, example = "3") - @NotEmpty(message = "商品市场价不能为空") - private Integer marketPrice; - - @Schema(description = "成本价", required = true, example = "12") - @NotEmpty(message = "商品成本价不能为空") - private Integer costPrice; - - @Schema(description = "库存", required = true, example = "111") - @NotEmpty(message = "商品库存不能为空") - private Integer stock; - // ========== 物流相关字段 ========= @Schema(description = "物流配置模板编号", required = true, example = "111") - @NotEmpty(message = "物流配置模板编号不能为空") + @NotNull(message = "物流配置模板编号不能为空") private Long deliveryTemplateId; // ========== 营销相关字段 ========= @Schema(description = "是否热卖推荐", required = true, example = "true") - @NotEmpty(message = "商品推荐不能为空") + @NotNull(message = "商品推荐不能为空") private Boolean recommendHot; @Schema(description = "是否优惠推荐", required = true, example = "true") - @NotEmpty(message = "商品推荐不能为空") + @NotNull(message = "商品推荐不能为空") private Boolean recommendBenefit; @Schema(description = "是否精品推荐", required = true, example = "true") - @NotEmpty(message = "商品推荐不能为空") + @NotNull(message = "商品推荐不能为空") private Boolean recommendBest; @Schema(description = "是否新品推荐", required = true, example = "true") - @NotEmpty(message = "商品推荐不能为空") + @NotNull(message = "商品推荐不能为空") private Boolean recommendNew; @Schema(description = "是否优品推荐", required = true, example = "true") - @NotEmpty(message = "商品推荐不能为空") + @NotNull(message = "商品推荐不能为空") private Boolean recommendGood; @Schema(description = "赠送积分", required = true, example = "111") - @NotEmpty(message = "商品赠送积分不能为空") + @NotNull(message = "商品赠送积分不能为空") private Integer giveIntegral; - @Schema(description = "赠送的优惠劵编号的数组") + @Schema(description = "赠送的优惠劵编号的数组") // TODO 这块前端还未实现 private List giveCouponTemplateIds; @Schema(description = "分销类型") + @NotNull(message = "商品分销类型不能为空") private Boolean subCommissionType; - @Schema(description = "活动展示顺序") + @Schema(description = "活动展示顺序") // TODO 这块前端还未实现 private List activityOrders; // ========== 统计相关字段 ========= - @Schema(description = "商品销量", required = true, example = "芋道") - @NotEmpty(message = "商品销量不能为空") - private Integer salesCount; - @Schema(description = "虚拟销量", required = true, example = "芋道") - @NotEmpty(message = "商品虚拟销量不能为空") private Integer virtualSalesCount; - @Schema(description = "浏览量", required = true, example = "芋道") - @NotEmpty(message = "商品浏览量不能为空") - private Integer browseCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 0bfefb8d4..91cd54ab2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -15,31 +15,7 @@ public class ProductSpuPageReqVO extends PageParam { @Schema(description = "商品名称", example = "yutou") private String name; - @Schema(description = "商品编码", example = "yudaoyuanma") - private String code; - @Schema(description = "分类编号", example = "1") private Long categoryId; - @Schema(description = "商品品牌编号", example = "1") - private Long brandId; - - @Schema(description = "上下架状态", example = "1") - private Integer status; - - @Schema(description = "销量最小值", example = "1") - private Integer salesCountMin; - - @Schema(description = "销量最大值", example = "1024") - private Integer salesCountMax; - - @Schema(description = "市场价最小值", example = "1") - private Integer marketPriceMin; - - @Schema(description = "市场价最大值", example = "1024") - private Integer marketPriceMax; - - @Schema(description = "是否库存告警", example = "true") - private Boolean alarmStock; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java new file mode 100644 index 000000000..0517cd41c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商品 SPU 分页 response VO") +@Data +public class ProductSpuPageRespVO { + @Schema(description = "spuId", example = "1") + private Long id; + @Schema(description = "商品封面图", example = "1") + private String picUrl; + @Schema(description = "商品名称", example = "1") + private String name; + @Schema(description = "商品价格", example = "1") + private Integer price; + @Schema(description = "商品销量", example = "1") + private Integer salesCount; + @Schema(description = "商品排序", example = "1") + private Integer stock; + @Schema(description = "商品封面图", example = "1") + private Integer sort; + @Schema(description = "商品创建时间", example = "1") + private LocalDateTime createTime; + @Schema(description = "商品状态", example = "1") + private Integer status; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index 5f088b74b..d550cb0c2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -19,22 +19,4 @@ public class ProductSpuRespVO extends ProductSpuBaseVO { @Schema(description = "创建时间") private LocalDateTime createTime; - // ========== SKU 相关字段 ========= - - @Schema(description = "库存", required = true, example = "true") - private Integer totalStock; - - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; - - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; - - @Schema(description = "商品销量", example = "1024") - private Integer salesCount; - - // ========== 统计相关字段 ========= - - @Schema(description = "点击量", example = "1024") - private Integer clickCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index 9b7714bb9..8336242b4 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -35,9 +35,8 @@ public interface ProductSkuConvert { List convertList06(List list); - default List convertList06(List list, Long spuId, String spuName) { + default List convertList06(List list, Long spuId) { List result = convertList06(list); - // result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName)); TODO ProductSkuDO中已经没有name相关属性 result.forEach(item -> item.setSpuId(spuId)); return result; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index fcf6d6436..4ceddab4d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -38,7 +38,7 @@ public interface ProductSpuConvert { List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 1260c7170..e2ed9f2a1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -116,19 +116,19 @@ public class ProductSpuDO extends TenantBaseDO { /** * 商品价格,单位使用:分 * - * 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值 + * 基于其对应的 {@link ProductSkuDO#getPrice()} sku单价最低的商品的 */ private Integer price; /** * 市场价,单位使用:分 * - * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值 TODO 芋艿:待确定最大还是最小 + * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} sku单价最低的商品的 */ private Integer marketPrice; /** * 成本价,单位使用:分 * - * 基于其对应的 {@link ProductSkuDO#getCostPrice()} 最大值 TODO 芋艿:待确定最大还是最小 + * 基于其对应的 {@link ProductSkuDO#getCostPrice()} sku单价最低的商品的 */ private Integer costPrice; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 256bc43f1..6ac1e8611 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -24,11 +24,6 @@ public interface ProductSpuMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) - .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) - .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) - .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) - .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) .orderByDesc(ProductSpuDO::getSort)); } @@ -36,13 +31,7 @@ public interface ProductSpuMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) - .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) - .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) - .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) - .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) .inIfPresent(ProductSpuDO::getId, alarmStockSpuIds) // 库存告警 - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) .orderByDesc(ProductSpuDO::getSort)); } @@ -52,8 +41,6 @@ public interface ProductSpuMapper extends BaseMapperX { .eqIfPresent(ProductSpuDO::getStatus, status); // 排序逻辑 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { - // TODO ProductSpuDO 已经没有maxPrice 属性 - //query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 21dfb9dee..02bde434d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -100,7 +100,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { if (category == null) { throw exception(CATEGORY_NOT_EXISTS); } - if (Objects.equals(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + if (Objects.equals(category.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { throw exception(CATEGORY_DISABLED, category.getName()); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 8db4911ab..923603487 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -56,19 +56,17 @@ public interface ProductSkuService { * 批量创建 SKU * * @param spuId 商品 SPU 编号 - * @param spuName 商品 SPU 名称 * @param list SKU 对象集合 */ - void createSkuList(Long spuId, String spuName, List list); + void createSkuList(Long spuId, List list); /** * 根据 SPU 编号,批量更新它的 SKU 信息 * * @param spuId SPU 编码 - * @param spuName 商品 SPU 名称 * @param skus SKU 的集合 */ - void updateSkuList(Long spuId, String spuName, List skus); + void updateSkuList(Long spuId, List skus); /** * 更新 SKU 库存(增量) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index a314318fc..62e59f2c9 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -84,10 +84,17 @@ public class ProductSkuServiceImpl implements ProductSkuService { return; } + // 0、校验skus是否为空 + if (CollUtil.isEmpty(skus)){ + throw exception(SKU_NOT_EXISTS); + } + // 1、校验属性项存在 Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(ProductSkuCreateOrUpdateReqVO.Property::getPropertyId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + // 遍历多个 Property 属性 + .flatMap(p -> p.getProperties().stream()) + // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .map(ProductSkuCreateOrUpdateReqVO.Property::getPropertyId) .collect(Collectors.toSet()); List propertyList = productPropertyService.getPropertyList(propertyIds); if (propertyList.size() != propertyIds.size()) { @@ -107,22 +114,24 @@ public class ProductSkuServiceImpl implements ProductSkuService { int attrValueIdsSize = skus.get(0).getProperties().size(); for (int i = 1; i < skus.size(); i++) { if (attrValueIdsSize != skus.get(i).getProperties().size()) { - throw exception(ErrorCodeConstants.SPU_ATTR_NUMBERS_MUST_BE_EQUALS); + throw exception(SPU_ATTR_NUMBERS_MUST_BE_EQUALS); } } // 4. 最后校验,每个 Sku 之间不是重复的 - Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. + // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. + Set> skuAttrValues = new HashSet<>(); for (ProductSkuCreateOrUpdateReqVO sku : skus) { - if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuCreateOrUpdateReqVO.Property::getValueId))) { // 添加失败,说明重复 - throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE); + // 添加失败,说明重复 + if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuCreateOrUpdateReqVO.Property::getValueId))) { + throw exception(SPU_SKU_NOT_DUPLICATE); } } } @Override - public void createSkuList(Long spuId, String spuName, List skuCreateReqList) { - productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId, spuName)); + public void createSkuList(Long spuId, List skuCreateReqList) { + productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId)); } @Override @@ -152,7 +161,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Override @Transactional(rollbackFor = Exception.class) - public void updateSkuList(Long spuId, String spuName, List skus) { + public void updateSkuList(Long spuId, List skus) { // 构建属性与 SKU 的映射关系; Map existsSkuMap = convertMap(productSkuMapper.selectListBySpuId(spuId), ProductSkuConvert.INSTANCE::buildPropertyKey, ProductSkuDO::getId); @@ -160,13 +169,14 @@ public class ProductSkuServiceImpl implements ProductSkuService { // 拆分三个集合,新插入的、需要更新的、需要删除的 List insertSkus = new ArrayList<>(); List updateSkus = new ArrayList<>(); - List allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, null, spuName); + List allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, null); allUpdateSkus.forEach(sku -> { String propertiesKey = ProductSkuConvert.INSTANCE.buildPropertyKey(sku); // 1、找得到的,进行更新 Long existsSkuId = existsSkuMap.remove(propertiesKey); if (existsSkuId != null) { sku.setId(existsSkuId); + // TODO 那spuId岂不是为null了 updateSkus.add(sku); return; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 352c8b341..45bc23389 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; @@ -21,10 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -54,20 +52,21 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override @Transactional(rollbackFor = Exception.class) public Long createSpu(ProductSpuCreateReqVO createReqVO) { - // 校验分类 - validateCategory(createReqVO.getCategoryId()); - // 校验品牌 - brandService.validateProductBrand(createReqVO.getBrandId()); - // 校验SKU - List skuSaveReqList = createReqVO.getSkus(); - productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); + // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点 + //validateCategory(createReqVO.getCategoryId()); + // 校验品牌 TODO 暂不校验 + //brandService.validateProductBrand(createReqVO.getBrandId()); - // 插入 SPU + List skuSaveReqList = createReqVO.getSkus(); + // 校验SKU + productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); + // 初始化SPU中SKU相关属性 initSpuFromSkus(spu, skuSaveReqList); + // 插入 SPU productSpuMapper.insert(spu); // 插入 SKU - productSkuService.createSkuList(spu.getId(), spu.getName(), skuSaveReqList); + productSkuService.createSkuList(spu.getId(), skuSaveReqList); // 返回 return spu.getId(); } @@ -90,7 +89,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { initSpuFromSkus(updateObj, skuSaveReqList); productSpuMapper.updateById(updateObj); // 批量更新 SKU - productSkuService.updateSkuList(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus()); + productSkuService.updateSkuList(updateObj.getId(), updateReqVO.getSkus()); } /** @@ -101,11 +100,25 @@ public class ProductSpuServiceImpl implements ProductSpuService { * @param skus 商品 SKU 数组 */ private void initSpuFromSkus(ProductSpuDO spu, List skus) { - spu.setMarketPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - // TODO ProductSpuDO中已没有相关属性 - //spu.setMaxPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - //spu.setMinPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - //spu.setTotalStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + // 断言,避免告警 + assert skus.size() > 0; + // 获取sku单价最低的商品 + ProductSkuCreateOrUpdateReqVO vo = skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateReqVO::getPrice)).get(); + // sku单价最低的商品的价格 + spu.setPrice(vo.getPrice()); + // sku单价最低的商品的市场价格 + spu.setMarketPrice(vo.getMarketPrice()); + // sku单价最低的商品的成本价格 + spu.setCostPrice(vo.getCostPrice()); + // sku单价最低的商品的条形码 + spu.setBarCode(vo.getBarCode()); + // 默认状态为上架 + spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + // TODO 默认商品销量和浏览量为零 + spu.setSalesCount(0); + spu.setBrowseCount(0); + // skus库存总数 + spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); } /** @@ -155,14 +168,14 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { - // 库存告警的 SPU 编号的集合 + // 库存告警的 SPU 编号的集合 TODO 一个接口一个接口来 Set alarmStockSpuIds = null; - if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { - alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId); - if (CollUtil.isEmpty(alarmStockSpuIds)) { - return PageResult.empty(); - } - } + //if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { + // alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId); + // if (CollUtil.isEmpty(alarmStockSpuIds)) { + // return PageResult.empty(); + // } + //} // 分页查询 return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index a6651c8b2..59305e22d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -75,7 +75,7 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { ); // 调用 - productSkuService.updateSkuList(spuId, spuName, skus); + productSkuService.updateSkuList(spuId, skus); // 断言 List dbSkus = productSkuMapper.selectListBySpuId(spuId); assertEquals(dbSkus.size(), 2); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 8048e9344..d6e1bdb4e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -9,10 +9,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; @@ -37,6 +34,7 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -83,21 +81,9 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> { o.setSpecType(true); - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); }); - - // 校验SKU - List skuCreateReqList = createReqVO.getSkus(); - Long spu = productSpuService.createSpu(createReqVO); ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); - - createReqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - // TODO ProductSpuCreateReqVO中已没有相关属性 -// createReqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// createReqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// createReqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); - assertPojoEquals(createReqVO, productSpuDO); } @@ -111,18 +97,9 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { o.setId(createReqVO.getId()); // 设置更新的 ID o.setSpecType(true); - o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); }); // 调用 productSpuService.updateSpu(reqVO); - - List skuCreateReqList = reqVO.getSkus(); - reqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - // TODO ProductSpuUpdateReqVO中已没有相关属性 -// reqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// reqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// reqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); - // 校验是否更新正确 ProductSpuDO spu = productSpuMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, spu); @@ -132,7 +109,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { public void testValidateSpuExists_exception() { ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { o.setSpecType(true); - o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); }); // 调用 Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO)); @@ -175,7 +151,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { void getSpuPage_alarmStock_empty() { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(true); + //productSpuPageReqVO.setAlarmStock(true); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); @@ -225,10 +201,10 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(true); + //productSpuPageReqVO.setAlarmStock(true); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); Assertions.assertIterableEquals(result.getList(), spuPage.getList()); assertEquals(spuPage.getTotal(), result.getTotal()); } @@ -273,14 +249,14 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(false); - productSpuPageReqVO.setBrandId(brandId); - productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + //productSpuPageReqVO.setAlarmStock(false); + //productSpuPageReqVO.setBrandId(brandId); + //productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); productSpuPageReqVO.setCategoryId(categoryId); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set) null)); + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set) null)); assertEquals(result, spuPage); } From 9980b12551e9cd5ce59b5e497b6754cf8209654f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 3 May 2023 00:30:02 +0800 Subject: [PATCH 029/232] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=B4=AD=E7=89=A9?= =?UTF-8?q?=E8=BD=A6=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=94=AF=E6=8C=81=20add=20?= =?UTF-8?q?=E5=95=86=E5=93=81=E6=97=B6=EF=BC=8C=E9=80=82=E9=85=8D=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E5=8F=AF=E8=83=BD=E8=A6=81=E5=88=A0=E9=99=A4=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/app/cart/vo/AppTradeCartAddReqVO.java | 2 -- .../module/trade/service/cart/TradeCartServiceImpl.java | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java index c1e3ebd2f..1018ec9a2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.controller.app.cart.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; @Schema(description = "用户 App - 购物车添加购物项 Request VO") @@ -16,7 +15,6 @@ public class AppTradeCartAddReqVO { @Schema(description = "新增商品数量", required = true, example = "1") @NotNull(message = "数量不能为空") - @Min(message = "数量必须大于 0", value = 1L) private Integer count; @Schema(description = "是否添加到购物车", required = true, example = "true") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index ffd75a07a..f92068644 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -58,9 +58,15 @@ public class TradeCartServiceImpl implements TradeCartService { cart.getCount() + addReqVO.getCount() : addReqVO.getCount(); ProductSkuRespDTO sku = checkProductSku(addReqVO.getSkuId(), count); + // 情况零:特殊,count 小于等于 0,说明前端项目删除 // 情况一:存在,则进行数量更新 if (cart != null) { - cartMapper.updateById(new TradeCartDO().setId(cart.getId()).setCount(count)); + // 特殊情况,如果 count 小于等于 0,说明前端想要删除 + if (count <= 0) { + cartMapper.deleteById(cart.getId()); + } else { + cartMapper.updateById(new TradeCartDO().setId(cart.getId()).setCount(count)); + } return cart.getId(); // 情况二:不存在,则进行插入 } else { From e163ae8b70cca549fea70ec850f39b79eac6d85f Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 3 May 2023 02:31:50 +0800 Subject: [PATCH 030/232] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=95=86=E5=93=81?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=92=8C=E7=BC=96=E8=BE=91=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=9B=9E=E6=98=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/spu/ProductSpuStatusEnum.java | 2 +- .../property/ProductPropertyController.java | 5 +-- .../vo/property/ProductPropertyListReqVO.java | 7 ++++- .../admin/sku/vo/ProductSkuRespVO.java | 10 +++--- .../admin/spu/ProductSpuController.java | 14 +-------- .../admin/spu/vo/ProductSpuDetailRespVO.java | 25 +++++---------- .../convert/sku/ProductSkuConvert.java | 2 +- .../convert/spu/ProductSpuConvert.java | 7 +++-- .../property/ProductPropertyServiceImpl.java | 5 +++ .../service/sku/ProductSkuService.java | 2 +- .../service/spu/ProductSpuService.java | 7 +++++ .../service/spu/ProductSpuServiceImpl.java | 31 +++++++++++++++++++ 12 files changed, 72 insertions(+), 45 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java index 2223cf23d..4ba6124e0 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java @@ -17,7 +17,7 @@ public enum ProductSpuStatusEnum implements IntArrayValuable { RECYCLE(-1, "回收站"), DISABLE(0, "下架"), - ENABLE(1, "上架"),; + ENABLE(1, "上架"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray(); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java index bd063e0ec..0c203b551 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueServ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import oracle.jdbc.proxy.annotation.Post; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -81,10 +82,10 @@ public class ProductPropertyController { return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO))); } - @GetMapping("/get-value-list") + @PostMapping("/get-value-list") @Operation(summary = "获得属性项列表") @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) { + public CommonResult> getPropertyAndValueList(@Valid @RequestBody ProductPropertyListReqVO listReqVO) { // 查询属性项 List keys = productPropertyService.getPropertyList(listReqVO); if (CollUtil.isEmpty(keys)) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java index 242caff84..44935147c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -4,12 +4,17 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; +import javax.validation.constraints.NotEmpty; +import java.util.List; + @Schema(description = "管理后台 - 属性项 List Request VO") @Data @ToString(callSuper = true) public class ProductPropertyListReqVO { - @Schema(description = "名称", example = "颜色") + @Schema(description = "属性名称", example = "颜色") private String name; + @Schema(description = "属性ids", example = "1,2") + private List propertyIds; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index a229fa826..11bf4a734 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -7,6 +7,9 @@ import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; +/** + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SKU Response VO") @Data @EqualsAndHashCode(callSuper = true) @@ -16,9 +19,6 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(description = "创建时间") - private LocalDateTime createTime; - @Schema(description = "商品属性") @Data @AllArgsConstructor @@ -34,11 +34,11 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { private Long valueId; @Schema(description = "属性值", example = "1024") - private String value; + private String valueName; } /** * 属性数组 */ - private List properties; + private List properties; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index f2ce90c1d..2e2871faa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -68,19 +68,7 @@ public class ProductSpuController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null); - // 查询商品属性 - List propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); - // 拼接 - return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues)); + return success(productSpuService.getSpuDetail(id)); } @GetMapping("/get-simple-list") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index 58f9565c8..4672911ff 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -2,37 +2,26 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息 @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class ProductSpuDetailRespVO extends ProductSpuRespVO { +public class ProductSpuDetailRespVO extends ProductSpuBaseVO { + @Schema(description = "商品编号", example = "1") + private Long id; // ========== SKU 相关字段 ========= - /** - * SKU 数组 - */ - private List skus; - - @Schema(description = "管理后台 - 商品 SKU 详细 Response VO") - @Data - @EqualsAndHashCode(callSuper = true) - @ToString(callSuper = true) - public static class Sku extends ProductSkuBaseVO { - - /** - * 属性数组 - */ - private List properties; - - } + @Schema(description = "SKU 数组", example = "1") + private List skus; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index 8336242b4..dd69646af 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -43,7 +43,7 @@ public interface ProductSkuConvert { ProductSkuRespDTO convert02(ProductSkuDO bean); - List convertList03(List list); + List convertList03(List list); List convertList04(List list); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 4ceddab4d..9fd142b28 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; @@ -88,7 +89,7 @@ public interface ProductSpuConvert { if (CollUtil.isEmpty(properties)) { continue; } - ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); + ProductSkuRespVO sku = spuVO.getSkus().get(i); sku.setProperties(new ArrayList<>(properties.size())); // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 properties.forEach(property -> { @@ -96,13 +97,13 @@ public interface ProductSpuConvert { if (propertyValue == null) { return; } - sku.getProperties().add(convert04(propertyValue)); + //sku.getProperties().add(convert04(propertyValue)); TODO 需要重写 }); } return spuVO; } ProductSpuDetailRespVO convert03(ProductSpuDO spu); - List convertList04(List skus); + List convertList04(List skus); ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index 328c343d6..96b41de8d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.service.property; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; @@ -92,6 +93,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Override public List getPropertyList(ProductPropertyListReqVO listReqVO) { + // 增加使用属性id查询 + if (CollUtil.isNotEmpty(listReqVO.getPropertyIds())){ + return productPropertyMapper.selectBatchIds(listReqVO.getPropertyIds()); + } return productPropertyMapper.selectList(listReqVO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 923603487..8eb5f73fb 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -87,7 +87,7 @@ public interface ProductSkuService { /** * 基于 SPU 编号和状态,获得商品 SKU 集合 - * + * TODO SKU中已经不存在status属性 * @param spuId SPU 编号 * @param status 状态 * @return 商品 SKU 集合 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 0ae7359eb..f088a7e79 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -98,4 +98,11 @@ public interface ProductSpuService { */ void updateSpuStock(Map stockIncrCounts); + /** + * 得到spu详细 + * + * @param id id + * @return {@link ProductSpuDetailRespVO} + */ + ProductSpuDetailRespVO getSpuDetail(Long id); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 45bc23389..4355f05ab 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -4,10 +4,13 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -15,6 +18,8 @@ import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -23,6 +28,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -48,6 +54,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { private ProductBrandService brandService; @Resource private ProductCategoryService categoryService; + @Resource + private ProductPropertyValueService productPropertyValueService; @Override @Transactional(rollbackFor = Exception.class) @@ -191,4 +199,27 @@ public class ProductSpuServiceImpl implements ProductSpuService { stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); } + @Override + public ProductSpuDetailRespVO getSpuDetail(Long id) { + // 获得商品 SPU + ProductSpuDO spu = getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + ProductSpuDetailRespVO productSpuDetailRespVO = ProductSpuConvert.INSTANCE.convert03(spu); + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuId(spu.getId()); + if (CollUtil.isNotEmpty(skus)){ + List skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus); + // 获取所有的属性值id + Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet()); + List valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds); + Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); + // 设置属性值名称 + skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId()))); + productSpuDetailRespVO.setSkus(skuRespVoS); + } + return productSpuDetailRespVO; + } + } From 6b05835cb39be947a257cb2d916362c15c199d4a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 3 May 2023 09:20:17 +0800 Subject: [PATCH 031/232] =?UTF-8?q?=E8=B4=AD=E7=89=A9=E8=BD=A6=EF=BC=9A?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=BE=97=E5=95=86=E5=93=81=E6=95=B0?= =?UTF-8?q?=E9=87=8F=20Map=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/app/cart/TradeCartController.http | 5 +++++ .../controller/app/cart/TradeCartController.java | 10 +++++++++- .../trade/dal/mysql/cart/TradeCartMapper.java | 14 ++++++++++++++ .../trade/service/cart/TradeCartService.java | 9 +++++++++ .../trade/service/cart/TradeCartServiceImpl.java | 6 ++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http index ead0fa72f..b341a4886 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http @@ -31,6 +31,11 @@ GET {{appApi}}/trade/cart/get-count tenant-id: {{appTenentId}} Authorization: Bearer {{appToken}} +### 请求 /trade/cart/get-count-map 接口 => 成功 +GET {{appApi}}/trade/cart/get-count-map +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} + ### 请求 /trade/cart/list 接口 => 成功 GET {{appApi}}/trade/cart/list tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java index 79105ced6..9216773ad 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.controller.app.cart; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -72,6 +73,13 @@ public class TradeCartController { return success(cartService.getCartCount(getLoginUserId())); } + @GetMapping("get-count-map") + @Operation(summary = "查询用户在购物车中的商品 SPU 数量 Map") + @PreAuthenticated + public CommonResult> getCartCountMap() { + return success(cartService.getCartCountMap(getLoginUserId())); + } + @GetMapping("/list") @Operation(summary = "查询用户的购物车列表") @PreAuthenticated diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java index 6c44dc279..564a4f0bc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.mysql.cart; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -34,6 +35,19 @@ public interface TradeCartMapper extends BaseMapperX { return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; } + default Map selectSumMapByUserId(Long userId) { + // SQL sum 查询 + List> result = selectMaps(new QueryWrapper() + .select("spu_id, SUM(count) AS sumCount") + .eq("user_id", userId) + .eq("add_status", true) // 只计算添加到购物车中的 + .eq("order_status", false) // 必须未下单 + .groupBy("spu_id")); + // 获得数量 + return CollectionUtils.convertMap(result, item -> MapUtil.getLong(item, "spu_id"), + item -> MapUtil.getInt(item, "sumCount")); + } + default TradeCartDO selectById(Long id, Long userId) { return selectOne(TradeCartDO::getId, id, TradeCartDO::getUserId, userId); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java index 9b87762c9..9a009860d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateRe import javax.validation.Valid; import java.util.Collection; +import java.util.Map; /** * 购物车 Service 接口 @@ -66,4 +67,12 @@ public interface TradeCartService { */ AppTradeCartListRespVO getCartList(Long userId); + /** + * 获得用户的购物车商品 SPU 数量的 Map + * + * @param userId 用户编号 + * @return 购物车商品 SPU 数量的 Map + */ + Map getCartCountMap(Long userId); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index f92068644..c6fb3e0ec 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -20,6 +20,7 @@ import javax.annotation.Resource; import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -138,6 +139,11 @@ public class TradeCartServiceImpl implements TradeCartService { return cartMapper.selectSumByUserId(userId); } + @Override + public Map getCartCountMap(Long userId) { + return cartMapper.selectSumMapByUserId(userId); + } + @Override public AppTradeCartListRespVO getCartList(Long userId) { // 获得购物车的商品,只查询未下单的 From 810c7ed040242de3672494d6c366532757a70d9e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 4 May 2023 01:32:25 +0800 Subject: [PATCH 032/232] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=95=86=E5=93=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 87 +++++++++++++------ .../enums/spu/ProductSpuTabTypeEnum.java | 27 ++++++ .../admin/spu/ProductSpuController.java | 15 ++++ .../admin/spu/vo/ProductSpuPageReqVO.java | 13 ++- .../spu/vo/ProductSpuUpdateStatusReqVO.java | 26 ++++++ .../dal/mysql/spu/ProductSpuMapper.java | 58 +++++++++---- .../service/spu/ProductSpuService.java | 21 ++++- .../service/spu/ProductSpuServiceImpl.java | 80 +++++++++++------ .../spu/ProductSpuServiceImplTest.java | 9 +- 9 files changed, 257 insertions(+), 79 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 0e8483155..6a4b73e54 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -163,19 +163,20 @@ COMMIT; -- Table structure for product_property -- ---------------------------- DROP TABLE IF EXISTS `product_property`; -CREATE TABLE `product_property` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格名称', - `status` tinyint NULL DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', - `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY (`id`) USING BTREE, - INDEX `idx_name`(`name`(32) ASC) USING BTREE COMMENT '规格名称索引' -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格名称'; +CREATE TABLE `product_property` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格名称', + `status` tinyint DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_name` (`name`(32)) USING BTREE COMMENT '规格名称索引' +) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='规格名称'; -- ---------------------------- -- Records of product_property @@ -187,19 +188,20 @@ COMMIT; -- Table structure for product_property_value -- ---------------------------- DROP TABLE IF EXISTS `product_property_value`; -CREATE TABLE `product_property_value` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `property_id` bigint NULL DEFAULT NULL COMMENT '规格键id', - `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格值名字', - `status` tinyint NULL DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', - `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格值'; +CREATE TABLE `product_property_value` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `property_id` bigint DEFAULT NULL COMMENT '规格键id', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格值名字', + `status` tinyint DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='规格值'; -- ---------------------------- -- Records of product_property_value @@ -325,3 +327,36 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `system_dict_data`(`sort`,`label`,`value`,`dict_type`,`status`,`color_type`,`css_class`,`remark`,`creator`,`create_time`,`updater`,`update_time`,`deleted`) VALUES + (1,'打',2,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'盒',3,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'袋',4,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'箱',5,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'套',6,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'包',7,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'双',8,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'卷',9,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'张',10,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'克',11,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'千克',12,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'毫克',13,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'微克',14,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'吨',15,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'升',16,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1,'毫升',17,'product_unit',0,'','','',1, NOW(),1, NOW(),0), + (1, '平方米', 18, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '平方千米', 19, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '平方英里', 20, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '平方码', 21, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '平方英尺', 22, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '立方米', 23, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '立方厘米', 24, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '立方英寸', 25, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '米', 26, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '千米', 27, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '厘米', 28, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '毫米', 29, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '英寸', 30, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '英尺', 31, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1, '码', 32, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), + (1,'个',1,'product_unit',0,'','','',1, NOW(),1, NOW(),0); \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java new file mode 100644 index 000000000..13dfc1a06 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.enums.spu; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 商品spu标签枚举类型 + * + * @author HUIHUI + */ +@Getter +@AllArgsConstructor +public enum ProductSpuTabTypeEnum { + FOR_SALE(0,"出售中商品"), + IN_WAREHOUSE(1,"仓库中商品"), + SOLD_OUT(2,"已售空商品"), + ALERT_STOCK(3,"警戒库存"), + RECYCLE_BIN(4,"商品回收站"); + /** + * 状态 + */ + private final Integer type; + /** + * 状态名 + */ + private final String name; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 2e2871faa..3a4923bbe 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -54,6 +55,14 @@ public class ProductSpuController { return success(true); } + @PutMapping("/updateStatus") + @Operation(summary = "更新商品 SPU Status") + @PreAuthorize("@ss.hasPermission('product:spu:update')") + public CommonResult updateStatus(@Valid @RequestBody ProductSpuUpdateStatusReqVO updateReqVO) { + productSpuService.updateStatus(updateReqVO); + return success(true); + } + @DeleteMapping("/delete") @Operation(summary = "删除商品 SPU") @Parameter(name = "id", description = "编号", required = true, example = "1024") @@ -85,5 +94,11 @@ public class ProductSpuController { public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } + @GetMapping("/tabsCount") + @Operation(summary = "获得商品 SPU tabsCount") + @PreAuthorize("@ss.hasPermission('product:spu:query')") + public CommonResult> getTabsCount() { + return success(productSpuService.getTabsCount()); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 91cd54ab2..cee193637 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -5,6 +5,11 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "管理后台 - 商品 SPU 分页 Request VO") @Data @@ -15,7 +20,11 @@ public class ProductSpuPageReqVO extends PageParam { @Schema(description = "商品名称", example = "yutou") private String name; - @Schema(description = "分类编号", example = "1") - private Long categoryId; + @Schema(description = "前端请求的tab类型", example = "1") + private Integer tabType; + + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java new file mode 100644 index 000000000..9838dd610 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO") +@Data +public class ProductSpuUpdateStatusReqVO{ + + @Schema(description = "商品编号", required = true, example = "1") + @NotNull(message = "商品编号不能为空") + private Long id; + + @Schema(description = "商品状态", required = true, example = "1") + @NotNull(message = "商品状态不能为空") + private Integer status; + + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 6ac1e8611..f3101ab4e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -1,14 +1,20 @@ package cn.iocoder.yudao.module.product.dal.mysql.spu; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -20,29 +26,51 @@ import java.util.Set; @Mapper public interface ProductSpuMapper extends BaseMapperX { + //default PageResult selectPage(ProductSpuPageReqVO reqVO) { + // return selectPage(reqVO, new LambdaQueryWrapperX() + // .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) + // .orderByDesc(ProductSpuDO::getSort)); + //} default PageResult selectPage(ProductSpuPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() + // 商品名称 .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) - .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) + .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime()) + // 出售中商品 + .eq(ProductSpuTabTypeEnum.FOR_SALE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.ENABLE.getStatus()) + // 仓储中商品 + .eq(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.DISABLE.getStatus()) + // 已售空商品 + .eq(ProductSpuTabTypeEnum.SOLD_OUT.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,0) + // TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 + .le(ProductSpuTabTypeEnum.ALERT_STOCK.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,10) + // 回收站 + .eq(ProductSpuTabTypeEnum.RECYCLE_BIN.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.RECYCLE.getStatus()) .orderByDesc(ProductSpuDO::getSort)); } - default PageResult selectPage(ProductSpuPageReqVO reqVO, Set alarmStockSpuIds) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) - .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) - .inIfPresent(ProductSpuDO::getId, alarmStockSpuIds) // 库存告警 - .orderByDesc(ProductSpuDO::getSort)); - } - - default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Integer status) { + /** + * 获得商品 SPU 分页,提供给用户 App 使用 + */ + default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Set categoryIds) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() - .eqIfPresent(ProductSpuDO::getCategoryId, pageReqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, status); + .likeIfPresent(ProductSpuDO::getName, pageReqVO.getKeyword()) // 关键字匹配,目前只匹配商品名 + .inIfPresent(ProductSpuDO::getCategoryId, categoryIds); // 分类 + query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()) // 上架状态 + .gt(ProductSpuDO::getStock, 0); // 有库存 + // 推荐类型的过滤条件 + if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { + query.eq(ProductSpuDO::getRecommendHot, true); + } // 排序逻辑 - if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { - } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { - query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); + if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { + query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC", + pageReqVO.getSortAsc() ? "ASC" : "DESC")); + } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { + query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getPrice) + .orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); + } else { + query.orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); } return selectPage(pageReqVO, query); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index f088a7e79..4b0444018 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -75,7 +75,7 @@ public interface ProductSpuService { List getSpuList(); /** - * 获得商品 SPU 分页 + * 获得商品 SPU 分页,提供给挂你兰后台使用 * * @param pageReqVO 分页查询 * @return 商品spu分页 @@ -83,13 +83,12 @@ public interface ProductSpuService { PageResult getSpuPage(ProductSpuPageReqVO pageReqVO); /** - * 获得商品 SPU 分页 + * 获得商品 SPU 分页,提供给用户 App 使用 * * @param pageReqVO 分页查询 - * @param status 状态 * @return 商品 SPU 分页 */ - PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status); + PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO); /** * 更新商品 SPU 库存(增量) @@ -105,4 +104,18 @@ public interface ProductSpuService { * @return {@link ProductSpuDetailRespVO} */ ProductSpuDetailRespVO getSpuDetail(Long id); + + /** + * 更新状态 + * + * @param updateReqVO 更新请求签证官 + */ + void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO); + + /** + * 获取spu列表标签对应的Count数量 + * + * @return {@link Map}<{@link Integer}, {@link Integer}> + */ + Map getTabsCount(); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 4355f05ab..23421c988 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; @@ -16,11 +17,13 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -62,7 +65,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { public Long createSpu(ProductSpuCreateReqVO createReqVO) { // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点 //validateCategory(createReqVO.getCategoryId()); - // 校验品牌 TODO 暂不校验 + // 校验品牌 TODO 暂不校验,前端没有做品牌选择 //brandService.validateProductBrand(createReqVO.getBrandId()); List skuSaveReqList = createReqVO.getSkus(); @@ -84,14 +87,13 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void updateSpu(ProductSpuUpdateReqVO updateReqVO) { // 校验 SPU 是否存在 validateSpuExists(updateReqVO.getId()); - // 校验分类 - validateCategory(updateReqVO.getCategoryId()); - // 校验品牌 - brandService.validateProductBrand(updateReqVO.getBrandId()); + // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点 + //validateCategory(updateReqVO.getCategoryId()); + // 校验品牌 TODO 暂不校验,前端没有做品牌选择 + //brandService.validateProductBrand(updateReqVO.getBrandId()); // 校验SKU List skuSaveReqList = updateReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); - // 更新 SPU ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); initSpuFromSkus(updateObj, skuSaveReqList); @@ -176,21 +178,13 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { - // 库存告警的 SPU 编号的集合 TODO 一个接口一个接口来 - Set alarmStockSpuIds = null; - //if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { - // alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId); - // if (CollUtil.isEmpty(alarmStockSpuIds)) { - // return PageResult.empty(); - // } - //} - // 分页查询 - return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds); + return productSpuMapper.selectPage(pageReqVO); } @Override - public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status) { - return productSpuMapper.selectPage(pageReqVO, status); + public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO) { + //return productSpuMapper.selectPage(pageReqVO); TODO 有差异接口接受参数类型不对 + return null; } @Override @@ -211,15 +205,45 @@ public class ProductSpuServiceImpl implements ProductSpuService { List skus = productSkuService.getSkuListBySpuId(spu.getId()); if (CollUtil.isNotEmpty(skus)){ List skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus); - // 获取所有的属性值id - Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet()); - List valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds); - Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); - // 设置属性值名称 - skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId()))); + // 非多规格,不需要处理 + if (ObjectUtil.equal(productSpuDetailRespVO.getSpecType(), true)) { + // 获取所有的属性值id + Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet()); + List valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds); + Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); + // 设置属性值名称 + skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId()))); + } productSpuDetailRespVO.setSkus(skuRespVoS); } return productSpuDetailRespVO; } + @Override + @Transactional(rollbackFor = Exception.class) + public void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO) { + // 校验存在 + validateSpuExists(updateReqVO.getId()); + // 更新状态 + ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus()); + productSpuMapper.updateById(productSpuDO); + + } + + @Override + public Map getTabsCount() { + Map map = new HashMap<>(); + // 查询销售中的商品数量 + map.put(ProductSpuTabTypeEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); + // 查询仓库中的商品数量 + map.put(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); + // 查询售空的商品数量 + map.put(ProductSpuTabTypeEnum.SOLD_OUT.getType(),productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); + // 查询触发警戒库存的商品数量 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 + map.put(ProductSpuTabTypeEnum.ALERT_STOCK.getType(),productSpuMapper.selectCount(new LambdaQueryWrapperX().le(ProductSpuDO::getStock, 10))); + // 查询回收站中的商品数量 + map.put(ProductSpuTabTypeEnum.RECYCLE_BIN.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + return map; + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index d6e1bdb4e..bd61c4e93 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -189,7 +189,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { }); productSpuMapper.insert(createReqVO); - Set alarmStockSpuIds = SetUtils.asSet(createReqVO.getId()); + //Set alarmStockSpuIds = SetUtils.asSet(createReqVO.getId()); TODO 查询接口已改变没有使用到这个变量 List productSpuDOS = Arrays.asList(randomPojo(ProductSkuDO.class, o -> { o.setSpuId(createReqVO.getId()); @@ -204,7 +204,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { //productSpuPageReqVO.setAlarmStock(true); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO)); Assertions.assertIterableEquals(result.getList(), spuPage.getList()); assertEquals(spuPage.getTotal(), result.getTotal()); } @@ -249,14 +249,15 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); + // TODO 已暂时没有相关属性,等用到时再添加 //productSpuPageReqVO.setAlarmStock(false); //productSpuPageReqVO.setBrandId(brandId); //productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - productSpuPageReqVO.setCategoryId(categoryId); + //productSpuPageReqVO.setCategoryId(categoryId); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set) null)); + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO)); assertEquals(result, spuPage); } From 7345d80b53350da3d5b52afd0d31b0e974ea9e07 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 4 May 2023 15:52:42 +0800 Subject: [PATCH 033/232] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=95=86=E5=93=81?= =?UTF-8?q?=E6=94=B6=E8=97=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 19 ++++++ .../product/enums/ErrorCodeConstants.java | 4 ++ .../favorite/ProductFavoriteTypeEnum.java | 34 ++++++++++ .../app/favorite/AppFavoriteController.java | 51 +++++++++++++++ .../app/favorite/vo/AppFavoritePageReqVO.java | 24 +++++++ .../app/favorite/vo/AppFavoriteReqVO.java | 29 +++++++++ .../app/favorite/vo/AppFavoriteRespVO.java | 31 ++++++++++ .../favorite/ProductFavoriteConvert.java | 19 ++++++ .../favorite/ProductFavoriteDO.java | 12 ++-- .../mysql/favorite/ProductFavoriteMapper.java | 42 +++++++++++++ .../favorite/ProductFavoriteService.java | 34 ++++++++++ .../favorite/ProductFavoriteServiceImpl.java | 62 +++++++++++++++++++ .../mapper/favorite/ProductFavoriteMapper.xml | 22 +++++++ 13 files changed, 378 insertions(+), 5 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 6a4b73e54..77356cf65 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -289,6 +289,25 @@ CREATE TABLE `product_spu` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='商品spu'; +-- ---------------------------- +-- Table structure for product_favorite +-- ---------------------------- +DROP TABLE IF EXISTS `product_favorite`; +CREATE TABLE `product_favorite` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `spu_id` bigint NOT NULL COMMENT '商品 SPU 编号', + `user_id` bigint NOT NULL COMMENT '用户id', + `type` int(10) NOT NULL DEFAULT 1 COMMENT '类型1:收藏 2:点赞', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='喜欢的商品表'; + + -- ---------------------------- -- Records of product_spu -- ---------------------------- diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index fe9319dae..4338103b4 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -48,4 +48,8 @@ public interface ErrorCodeConstants { ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作"); ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); + // ========== 喜爱商品 1008008000 ========== + ErrorCode COLLECTION_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); + ErrorCode COLLECTION_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); + } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java new file mode 100644 index 000000000..3dee472fb --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.enums.favorite; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 喜爱商品类型 枚举 + * + * @author jason + */ +@Getter +@AllArgsConstructor +public enum ProductFavoriteTypeEnum implements IntArrayValuable { + COLLECT(1,"收藏"), + THUMBS_UP(2, "点赞"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductFavoriteTypeEnum::getType).toArray(); + /** + * 类型 + */ + private final Integer type; + /** + * 描述 + */ + private final String desc; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java new file mode 100644 index 000000000..385cde3ec --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.product.controller.app.favorite; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; +import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum.COLLECT; + +/** + * @author jason + */ +@Tag(name = "用户 APP - 喜爱商品") +@RestController +@RequestMapping("/product/favorite") +public class AppFavoriteController { + + @Resource + private ProductFavoriteService productFavoriteService; + + @PostMapping(value = "/collect") + @Operation(summary = "商品收藏") + public CommonResult collect(@RequestBody @Valid AppFavoriteReqVO reqVO) { + Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配"); + return success(productFavoriteService.collect(reqVO)); + } + + @PostMapping(value = "/cancelCollect") + @Operation(summary = "取消商品收藏(通过商品详情)") + public CommonResult cancelCollect(@RequestBody @Valid AppFavoriteReqVO reqVO) { + Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配"); + return success(productFavoriteService.cancelCollect(reqVO)); + } + + @GetMapping(value = "/collectList") + @Operation(summary = "商品收藏列表") + public CommonResult> pageCollectList(AppFavoritePageReqVO reqVO) { + return success(productFavoriteService.pageCollectList(reqVO)); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java new file mode 100644 index 000000000..ef68cb736 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.controller.app.favorite.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +/** + * @author jason + */ +@Schema(description = "用户APP - 喜爱商品分页查询 Request VO") +@Data +public class AppFavoritePageReqVO extends PageParam { + + @Schema(description = "类型 1:收藏 2:点赞", requiredMode = REQUIRED, example = "1") + @NotNull(message = "类型不能为空") + @InEnum(ProductFavoriteTypeEnum.class) + private Integer type; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java new file mode 100644 index 000000000..b611922cc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.app.favorite.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + + + +/** + * @author jason + */ +@Schema(description = "用户APP - 喜爱商品创建 Request VO") +@Data +public class AppFavoriteReqVO { + + @Schema(description = "商品SPU编号", requiredMode = REQUIRED, example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "类型 1:收藏 2:点赞", requiredMode = REQUIRED, example = "1") + @NotNull(message = "类型不能为空") + @InEnum(ProductFavoriteTypeEnum.class) + private Integer type; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java new file mode 100644 index 000000000..b15c49a62 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.product.controller.app.favorite.vo; + +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author jason + */ +@Schema(description = "用户APP - 喜爱商品 Response VO") +@Data +public class AppFavoriteRespVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "商品SPU编号", example = "29502") + private Long spuId; + + @Schema(description = "商品SPU名称", example = "赵六") + private String spuName; + + @Schema(description = "商品封面图", example = "https://domain/pic.png") + private String picUrl; + + @Schema(description = "商品单价", example = "100") + private Integer price; + + @Schema(description = "类型 1:收藏 2:点赞", example = "1") + private Integer type; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java new file mode 100644 index 000000000..04b6dc56a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.product.convert.favorite; + +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 喜爱商品 Convert + * + * @author jason + */ +@Mapper +public interface ProductFavoriteConvert { + + ProductFavoriteConvert INSTANCE = Mappers.getMapper(ProductFavoriteConvert.class); + + ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO); +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java index 54d4b31ac..20b712aff 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.favorite; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; /** - * 商品收藏 DO + * 喜爱商品 DO * * @author 芋道源码 */ @@ -20,7 +20,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductFavoriteDO extends BaseDO { +public class ProductFavoriteDO extends TenantBaseDO { /** * 编号,主键自增 @@ -39,7 +39,9 @@ public class ProductFavoriteDO extends BaseDO { * 关联 {@link ProductSpuDO#getId()} */ private Long spuId; - - // TODO 芋艿:type 1 收藏;2 点赞 + /** + * 类型 1 收藏;2 点赞 + */ + private Integer type; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java new file mode 100644 index 000000000..e9ee46a7f --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.product.dal.mysql.favorite; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 喜爱商品 Mapper + * + * @author jason + */ +@Mapper +public interface ProductFavoriteMapper extends BaseMapperX { + + default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type){ + Assert.notNull(userId, "the userId argument must not be null"); + Assert.notNull(spuId, "the spuId argument must not be null"); + Assert.notNull(type, "the type argument must not be null"); + return selectOne(new LambdaQueryWrapperX() + .eq(ProductFavoriteDO::getUserId, userId) + .eq(ProductFavoriteDO::getSpuId, spuId) + .eq(ProductFavoriteDO::getType, type)); + } + + default PageResult selectPageByUserAndType(Long userId, Integer type, PageParam pageParam){ + Page page = MyBatisUtils.buildPage(pageParam); + page = selectFavoriteProductList(page, userId, type); + return new PageResult<>(page.getRecords(), page.getTotal()); + } + + Page selectFavoriteProductList(Page page, + @Param("userId") Long userId, + @Param("type") Integer type); +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java new file mode 100644 index 000000000..c1b85af17 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.service.favorite; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; + +import javax.validation.Valid; + +/** + * 喜爱商品 Service 接口 + * + * @author jason + */ +public interface ProductFavoriteService { + + /** + * 商品收藏 + * @param reqVO 请求vo + */ + Boolean collect(@Valid AppFavoriteReqVO reqVO); + + /** + * 取消商品收藏 (通过商品详情页面) + * @param reqVO 请求vo + */ + Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO); + + /** + * 分页查询用户收藏列表 + * @param reqVO 请求 vo + */ + PageResult pageCollectList(@Valid AppFavoritePageReqVO reqVO); +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java new file mode 100644 index 000000000..1b295157c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.product.service.favorite; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; +import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_NOT_EXISTS; + +/** + * 喜爱商品 Service 实现类 + * + * @author jason + */ +@Service +@Validated +public class ProductFavoriteServiceImpl implements ProductFavoriteService { + + @Resource + private ProductFavoriteMapper mapper; + + @Override + public Boolean collect(@Valid AppFavoriteReqVO reqVO) { + Long userId = getLoginUserId(); + ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); + if (Objects.nonNull(favoriteDO)) { + throw exception(COLLECTION_EXISTS); + } + ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); + int count = mapper.insert(entity); + return count == 1; + } + + @Override + public Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO) { + Long loginUserId = getLoginUserId(); + ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(loginUserId, reqVO.getSpuId(), reqVO.getType()); + if (Objects.isNull(favoriteDO)) { + throw exception(COLLECTION_NOT_EXISTS); + } + int count = mapper.deleteById(favoriteDO.getId()); + return count == 1; + } + + @Override + public PageResult pageCollectList(@Valid AppFavoritePageReqVO reqVO) { + Long userId = getLoginUserId(); + return mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml b/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml new file mode 100644 index 000000000..8d2741e03 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + \ No newline at end of file From cd86620b74eeff4c507aa9678c7969e1b806c224 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 5 May 2023 23:01:23 +0800 Subject: [PATCH 034/232] =?UTF-8?q?REVIEW=20=E5=95=86=E5=93=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/spu/ProductSpuTabTypeEnum.java | 4 +++ .../product/enums/spu/ProductUnitEnum.java | 2 ++ .../yudao-module-product-biz/pom.xml | 1 + .../property/ProductPropertyController.java | 4 +-- .../vo/property/ProductPropertyListReqVO.java | 5 ++-- .../admin/sku/vo/ProductSkuBaseVO.java | 5 +--- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 1 + .../admin/sku/vo/ProductSkuRespVO.java | 8 +++--- .../admin/spu/ProductSpuController.java | 7 ++--- .../admin/spu/vo/ProductSpuBaseVO.java | 9 ------ .../admin/spu/vo/ProductSpuDetailRespVO.java | 4 +-- .../admin/spu/vo/ProductSpuPageReqVO.java | 1 + .../admin/spu/vo/ProductSpuPageRespVO.java | 5 ++-- .../convert/spu/ProductSpuConvert.java | 2 +- .../property/ProductPropertyDO.java | 3 +- .../property/ProductPropertyValueDO.java | 3 +- .../dal/dataobject/sku/ProductSkuDO.java | 7 ++--- .../dal/mysql/spu/ProductSpuMapper.java | 16 ++--------- .../property/ProductPropertyService.java | 1 + .../property/ProductPropertyServiceImpl.java | 2 +- .../service/sku/ProductSkuService.java | 4 ++- .../service/spu/ProductSpuServiceImpl.java | 28 +++++++++++-------- .../spu/ProductSpuServiceImplTest.java | 22 +++++---------- 23 files changed, 62 insertions(+), 82 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java index 13dfc1a06..86b5a9e8c 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.enums.spu; import lombok.AllArgsConstructor; import lombok.Getter; +// TODO @puhui999:中英文之间要有空格; 商品 spu Tab 标签枚举;这个类可以改成 ProductSpuPageTabEnum 会更好一点哈;分页 Tab 的意思; /** * 商品spu标签枚举类型 * @@ -11,11 +12,13 @@ import lombok.Getter; @Getter @AllArgsConstructor public enum ProductSpuTabTypeEnum { + FOR_SALE(0,"出售中商品"), IN_WAREHOUSE(1,"仓库中商品"), SOLD_OUT(2,"已售空商品"), ALERT_STOCK(3,"警戒库存"), RECYCLE_BIN(4,"商品回收站"); + /** * 状态 */ @@ -24,4 +27,5 @@ public enum ProductSpuTabTypeEnum { * 状态名 */ private final String name; + } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java index 6d463ffb5..8753824dc 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java @@ -6,6 +6,7 @@ import lombok.Getter; import java.util.Arrays; +// TODO @puhui999:是不是放到数据字典里? /** * 产品单位枚举 * @@ -14,6 +15,7 @@ import java.util.Arrays; @Getter @AllArgsConstructor public enum ProductUnitEnum implements IntArrayValuable { + PIECE(1, "个"), DOZEN(2, "打"), BOX(3, "盒"), diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index 72c37cb20..b04e03208 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -35,6 +35,7 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog + cn.iocoder.boot yudao-spring-boot-starter-biz-tenant diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java index 0c203b551..831319ed5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java @@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueServ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import oracle.jdbc.proxy.annotation.Post; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -85,7 +84,8 @@ public class ProductPropertyController { @PostMapping("/get-value-list") @Operation(summary = "获得属性项列表") @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyAndValueList(@Valid @RequestBody ProductPropertyListReqVO listReqVO) { + public CommonResult> getPropertyAndValueList( + @Valid @RequestBody ProductPropertyListReqVO listReqVO) { // 查询属性项 List keys = productPropertyService.getPropertyList(listReqVO); if (CollUtil.isEmpty(keys)) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java index 44935147c..e366864eb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -4,7 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; -import javax.validation.constraints.NotEmpty; import java.util.List; @Schema(description = "管理后台 - 属性项 List Request VO") @@ -15,6 +14,8 @@ public class ProductPropertyListReqVO { @Schema(description = "属性名称", example = "颜色") private String name; - @Schema(description = "属性ids", example = "1,2") + // TODO @puhui999:这个查询条件的作用是啥呀? + @Schema(description = "属性编号的数组", example = "1,2") private List propertyIds; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index dde623b50..4cc258082 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -1,11 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -50,6 +46,7 @@ public class ProductSkuBaseVO { @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 private Double volume; + // TODO @pitui999:注释可以去掉,VO 使用 @Schema 作为注释 /** * 一级分销的佣金,单位:分 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 54de91cf1..a1253ca26 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -11,6 +11,7 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { + @Schema(description = "商品属性") @Data @AllArgsConstructor diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index 11bf4a734..815761615 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -4,12 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; import java.util.List; -/** - * @author HUIHUI - */ @Schema(description = "管理后台 - 商品 SKU Response VO") @Data @EqualsAndHashCode(callSuper = true) @@ -29,13 +25,17 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { @NotNull(message = "属性编号不能为空") private Long propertyId; + // TODO @puhui999:propertyName 是不是也返回下 + @Schema(description = "属性值编号", required = true, example = "1024") @NotNull(message = "属性值编号不能为空") private Long valueId; @Schema(description = "属性值", example = "1024") private String valueName; + } + /** * 属性数组 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 3a4923bbe..698681856 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -3,12 +3,9 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; @@ -23,9 +20,7 @@ import javax.validation.Valid; import java.util.List; import java.util.Map; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; @Tag(name = "管理后台 - 商品 SPU") @RestController @@ -94,6 +89,8 @@ public class ProductSpuController { public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } + + // TODO @tuihui999:get-count;另外,url 使用 - 拆分 @GetMapping("/tabsCount") @Operation(summary = "获得商品 SPU tabsCount") @PreAuthorize("@ss.hasPermission('product:spu:query')") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 251b4be47..5a0a64ef3 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -1,13 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -116,5 +108,4 @@ public class ProductSpuBaseVO { @Schema(description = "虚拟销量", required = true, example = "芋道") private Integer virtualSalesCount; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index 4672911ff..51ea5d38a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -1,14 +1,11 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息 @@ -19,6 +16,7 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { @Schema(description = "商品编号", example = "1") private Long id; + // ========== SKU 相关字段 ========= @Schema(description = "SKU 数组", example = "1") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index cee193637..9c3b51e21 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -20,6 +20,7 @@ public class ProductSpuPageReqVO extends PageParam { @Schema(description = "商品名称", example = "yutou") private String name; + // TODO @puhui999:加下 @InEnum 校验 @Schema(description = "前端请求的tab类型", example = "1") private Integer tabType; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java index 0517cd41c..83933ebdb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java @@ -1,15 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import com.baomidou.mybatisplus.annotation.FieldFill; -import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:可以直接继承 ProductSpuRespVO 么?一般情况下,多返回一些字段问题不大的;另外,是不是使用 ProductSpuRespVO 替代 @Schema(description = "管理后台 - 商品 SPU 分页 response VO") @Data public class ProductSpuPageRespVO { + @Schema(description = "spuId", example = "1") private Long id; @Schema(description = "商品封面图", example = "1") @@ -28,4 +28,5 @@ public class ProductSpuPageRespVO { private LocalDateTime createTime; @Schema(description = "商品状态", example = "1") private Integer status; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index dc4198186..79091974b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -47,7 +47,7 @@ public interface ProductSpuConvert { List convertList02(List list); - + // TODO @puhui999:是不是可以删除啦 default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, List propertyValues) { ProductSpuDetailRespVO spuVO = convert03(spu); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index bf631c420..6da6af9fe 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -20,7 +19,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyDO extends TenantBaseDO { +public class ProductPropertyDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index 4043afc61..be64373a5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -21,7 +20,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyValueDO extends TenantBaseDO { +public class ProductPropertyValueDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 1b6f54ae2..4e6c7f8a1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.sku; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; @@ -28,7 +27,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductSkuDO extends TenantBaseDO { +public class ProductSkuDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? /** * 商品 SKU 编号,自增 @@ -116,7 +115,7 @@ public class ProductSkuDO extends TenantBaseDO { // * 冗余 {@link ProductPropertyDO#getName()} // * // * 注意:每次属性名字发生变化时,需要更新该冗余 - // */ TODO 与已有代码逻辑存在冲突 + // */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀? //private String propertyName; /** @@ -131,7 +130,7 @@ public class ProductSkuDO extends TenantBaseDO { // * 冗余 {@link ProductPropertyValueDO#getName()} // * // * 注意:每次属性值名字发生变化时,需要更新该冗余 - // */ TODO 与已有代码逻辑存在冲突 + // */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀? //private String valueName; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index f3101ab4e..ae4389eb2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -1,11 +1,9 @@ package cn.iocoder.yudao.module.product.dal.mysql.spu; import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -14,24 +12,14 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; -import java.util.Map; import java.util.Objects; import java.util.Set; -/** - * 商品spu Mapper - * - * @author 芋道源码 - */ @Mapper public interface ProductSpuMapper extends BaseMapperX { - //default PageResult selectPage(ProductSpuPageReqVO reqVO) { - // return selectPage(reqVO, new LambdaQueryWrapperX() - // .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) - // .orderByDesc(ProductSpuDO::getSort)); - //} default PageResult selectPage(ProductSpuPageReqVO reqVO) { + // TODO @puhui999:多个 tab,写 if else 去补条件,可阅读性会好点哈 return selectPage(reqVO, new LambdaQueryWrapperX() // 商品名称 .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) @@ -42,7 +30,7 @@ public interface ProductSpuMapper extends BaseMapperX { .eq(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.DISABLE.getStatus()) // 已售空商品 .eq(ProductSpuTabTypeEnum.SOLD_OUT.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,0) - // TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 + // TODO @phuui999:警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 .le(ProductSpuTabTypeEnum.ALERT_STOCK.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,10) // 回收站 .eq(ProductSpuTabTypeEnum.RECYCLE_BIN.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.RECYCLE.getStatus()) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java index 564bc82a9..6a1ceb95a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java @@ -40,6 +40,7 @@ public interface ProductPropertyService { /** * 获得属性项列表 + * * @param listReqVO 集合查询 * @return 属性项集合 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index 7554a508e..d33d4df15 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -94,7 +94,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Override public List getPropertyList(ProductPropertyListReqVO listReqVO) { - // 增加使用属性id查询 + // 增加使用属性 id 查询 if (CollUtil.isNotEmpty(listReqVO.getPropertyIds())){ return productPropertyMapper.selectBatchIds(listReqVO.getPropertyIds()); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 8eb5f73fb..0b34cc2d8 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -87,7 +87,9 @@ public interface ProductSkuService { /** * 基于 SPU 编号和状态,获得商品 SKU 集合 - * TODO SKU中已经不存在status属性 + * + * TODO @puhui999:SKU中已经不存在status属性;芋艿:那就去掉 status 哈 + * * @param spuId SPU 编号 * @param status 状态 * @return 商品 SKU 集合 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 23421c988..fd1cac880 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,12 +1,9 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; @@ -23,7 +20,6 @@ import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,7 +30,7 @@ import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR; @@ -63,17 +59,18 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override @Transactional(rollbackFor = Exception.class) public Long createSpu(ProductSpuCreateReqVO createReqVO) { - // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点 + // 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别; //validateCategory(createReqVO.getCategoryId()); - // 校验品牌 TODO 暂不校验,前端没有做品牌选择 + // 校验品牌 TODO puhui999:暂不校验,前端没有做品牌选择;芋艿:可以加下哈 //brandService.validateProductBrand(createReqVO.getBrandId()); List skuSaveReqList = createReqVO.getSkus(); - // 校验SKU + // 校验 SKU productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); - // 初始化SPU中SKU相关属性 + // 初始化 SPU 中 SKU 相关属性 initSpuFromSkus(spu, skuSaveReqList); + // 插入 SPU productSpuMapper.insert(spu); // 插入 SKU @@ -193,6 +190,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); } + // TODO @puhui999:Service 尽量不做一些跟 VO 相关的拼接逻辑,目的是让 Service 更加简洁一点哈。 @Override public ProductSpuDetailRespVO getSpuDetail(Long id) { // 获得商品 SPU @@ -204,12 +202,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); if (CollUtil.isNotEmpty(skus)){ + // TODO @puhui999:skuVOs 更简洁一点。然后大小写要注释哈。RespVOs;因为 VO 是缩写,s 是复数 List skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus); // 非多规格,不需要处理 + // TODO @puhui999:统一模型,即使是单规格,也查询下,问题不大的 if (ObjectUtil.equal(productSpuDetailRespVO.getSpecType(), true)) { - // 获取所有的属性值id - Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet()); + // 获取所有的属性值 id + Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()) + .map(ProductSkuDO.Property::getValueId) + .collect(Collectors.toSet()); List valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds); + // TODO @puhui999:拼接的逻辑,最好查询好后,丢到 convert 里面统一处理;这样 Service or Controller 也可以更简洁;原则上,Controller 去组合;Service 写逻辑;Convert 转换 Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); // 设置属性值名称 skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId()))); @@ -232,6 +235,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public Map getTabsCount() { + // TODO @puhui999:map =》counts;尽量避免出现 map 这种命名,无命名含义哈 Map map = new HashMap<>(); // 查询销售中的商品数量 map.put(ProductSpuTabTypeEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); @@ -240,6 +244,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 查询售空的商品数量 map.put(ProductSpuTabTypeEnum.SOLD_OUT.getType(),productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); // 查询触发警戒库存的商品数量 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 + // TODO @puhui999:要有空格;, productSpuMapper + // TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈 map.put(ProductSpuTabTypeEnum.ALERT_STOCK.getType(),productSpuMapper.selectCount(new LambdaQueryWrapperX().le(ProductSpuDO::getStock, 10))); // 查询回收站中的商品数量 map.put(ProductSpuTabTypeEnum.RECYCLE_BIN.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index bd61c4e93..b6f150a11 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -5,11 +5,11 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageRespVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; @@ -34,7 +34,6 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -79,13 +78,10 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test public void testCreateSpu_success() { // 准备参数 - ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> { - o.setSpecType(true); - }); + ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class); Long spu = productSpuService.createSpu(createReqVO); ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); assertPojoEquals(createReqVO, productSpuDO); - } @Test @@ -96,7 +92,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { o.setId(createReqVO.getId()); // 设置更新的 ID - o.setSpecType(true); }); // 调用 productSpuService.updateSpu(reqVO); @@ -107,9 +102,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test public void testValidateSpuExists_exception() { - ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { - o.setSpecType(true); - }); + ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class); // 调用 Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO)); } @@ -174,7 +167,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 //o.setMaxPrice(50); o.setMarketPrice(25); - o.setSpecType(false); o.setBrandId(brandId); o.setCategoryId(categoryId); //o.setClickCount(100); @@ -222,8 +214,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 //o.setMaxPrice(1); o.setMarketPrice(1); - o.setSpecType(false); o.setBrandId(brandId); + o.setSpecType(false); o.setCategoryId(categoryId); //o.setClickCount(1); // TODO ProductSpuDO中已没有相关属性 //o.setCode(generateNo()); From 96e2bf020f0e30209d57fa0a343d7f811270e820 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 5 May 2023 23:38:31 +0800 Subject: [PATCH 035/232] =?UTF-8?q?REVIEW=20=E5=95=86=E5=93=81=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 2 +- .../favorite/ProductFavoriteTypeEnum.java | 4 +++- .../app/favorite/AppFavoriteController.java | 12 +++++++---- .../app/favorite/vo/AppFavoritePageReqVO.java | 8 +++----- .../app/favorite/vo/AppFavoriteReqVO.java | 14 +++++-------- .../app/favorite/vo/AppFavoriteRespVO.java | 20 ++++++++++--------- .../favorite/ProductFavoriteConvert.java | 5 ----- .../favorite/ProductFavoriteDO.java | 4 ++-- .../mysql/favorite/ProductFavoriteMapper.java | 8 ++------ .../favorite/ProductFavoriteServiceImpl.java | 9 ++++++++- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 4338103b4..5c36a2328 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -48,7 +48,7 @@ public interface ErrorCodeConstants { ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作"); ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); - // ========== 喜爱商品 1008008000 ========== + // ========== 商品 收藏 1008008000 ========== ErrorCode COLLECTION_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); ErrorCode COLLECTION_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java index 3dee472fb..4d28ae8ae 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java @@ -7,17 +7,19 @@ import lombok.Getter; import java.util.Arrays; /** - * 喜爱商品类型 枚举 + * 商品收藏的类型枚举 * * @author jason */ @Getter @AllArgsConstructor public enum ProductFavoriteTypeEnum implements IntArrayValuable { + COLLECT(1,"收藏"), THUMBS_UP(2, "点赞"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductFavoriteTypeEnum::getType).toArray(); + /** * 类型 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 385cde3ec..9d1d53dd3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -18,10 +18,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum.COLLECT; -/** - * @author jason - */ -@Tag(name = "用户 APP - 喜爱商品") +@Tag(name = "用户 APP - 商品收藏") @RestController @RequestMapping("/product/favorite") public class AppFavoriteController { @@ -29,6 +26,7 @@ public class AppFavoriteController { @Resource private ProductFavoriteService productFavoriteService; + // TODO @jason:创建;create @PostMapping(value = "/collect") @Operation(summary = "商品收藏") public CommonResult collect(@RequestBody @Valid AppFavoriteReqVO reqVO) { @@ -36,16 +34,22 @@ public class AppFavoriteController { return success(productFavoriteService.collect(reqVO)); } + // TODO @jason:创建;delete;使用 @DeleteMapping @PostMapping(value = "/cancelCollect") @Operation(summary = "取消商品收藏(通过商品详情)") public CommonResult cancelCollect(@RequestBody @Valid AppFavoriteReqVO reqVO) { + // TODO @jason:是不是不用校验呀? Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配"); return success(productFavoriteService.cancelCollect(reqVO)); } + // TODO @jason:page;分页 @GetMapping(value = "/collectList") @Operation(summary = "商品收藏列表") public CommonResult> pageCollectList(AppFavoritePageReqVO reqVO) { return success(productFavoriteService.pageCollectList(reqVO)); } + + // TODO @json:需要在给一个,用户查询某个商品是否收藏;详情页要用 + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java index ef68cb736..3ca8b6da6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java @@ -10,15 +10,13 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -/** - * @author jason - */ -@Schema(description = "用户APP - 喜爱商品分页查询 Request VO") +@Schema(description = "用户APP - 商品收藏分页查询 Request VO") @Data public class AppFavoritePageReqVO extends PageParam { - @Schema(description = "类型 1:收藏 2:点赞", requiredMode = REQUIRED, example = "1") + @Schema(description = "类型", requiredMode = REQUIRED, example = "1") @NotNull(message = "类型不能为空") @InEnum(ProductFavoriteTypeEnum.class) private Integer type; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index b611922cc..d4f2ba760 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -9,21 +9,17 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; - - -/** - * @author jason - */ -@Schema(description = "用户APP - 喜爱商品创建 Request VO") +@Schema(description = "用户 APP - 商品收藏创建 Request VO") @Data public class AppFavoriteReqVO { - @Schema(description = "商品SPU编号", requiredMode = REQUIRED, example = "29502") - @NotNull(message = "商品SPU编号不能为空") + @Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502") + @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; - @Schema(description = "类型 1:收藏 2:点赞", requiredMode = REQUIRED, example = "1") + @Schema(description = "类型", requiredMode = REQUIRED, example = "1") @NotNull(message = "类型不能为空") @InEnum(ProductFavoriteTypeEnum.class) private Integer type; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java index b15c49a62..686a24d6d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -1,23 +1,27 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -/** - * @author jason - */ -@Schema(description = "用户APP - 喜爱商品 Response VO") +@Schema(description = "用户APP - 商品收藏 Response VO") @Data public class AppFavoriteRespVO { + // TODO @jason:required true 哈 @Schema(description = "编号", example = "1") private Long id; - @Schema(description = "商品SPU编号", example = "29502") + // TODO @jason:required true 哈 + @Schema(description = "商品 SPU 编号", example = "29502") private Long spuId; - @Schema(description = "商品SPU名称", example = "赵六") + // TODO @jason:required true 哈 + @Schema(description = "类型", example = "1") + private Integer type; + + // ========== 商品相关字段 ========== + + @Schema(description = "商品 SPU 名称", example = "赵六") private String spuName; @Schema(description = "商品封面图", example = "https://domain/pic.png") @@ -26,6 +30,4 @@ public class AppFavoriteRespVO { @Schema(description = "商品单价", example = "100") private Integer price; - @Schema(description = "类型 1:收藏 2:点赞", example = "1") - private Integer type; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index 04b6dc56a..03fb1caf9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -5,11 +5,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; -/** - * 喜爱商品 Convert - * - * @author jason - */ @Mapper public interface ProductFavoriteConvert { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java index 20b712aff..356bba065 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -20,7 +20,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductFavoriteDO extends TenantBaseDO { +public class ProductFavoriteDO extends TenantBaseDO { // TODO @jason:如无必要,使用 BaseDO 哈。例如说 tenant_id 在业务里,是否需要使用到 /** * 编号,主键自增 @@ -40,7 +40,7 @@ public class ProductFavoriteDO extends TenantBaseDO { */ private Long spuId; /** - * 类型 1 收藏;2 点赞 + * 类型 1 收藏;2 点赞 // TODO @jason:不要注释 1 收藏 2 点赞;而是注释好,它对应的枚举类 */ private Integer type; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index e9ee46a7f..435152ea7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -12,15 +12,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -/** - * 喜爱商品 Mapper - * - * @author jason - */ @Mapper public interface ProductFavoriteMapper extends BaseMapperX { - default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type){ + default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) { Assert.notNull(userId, "the userId argument must not be null"); Assert.notNull(spuId, "the spuId argument must not be null"); Assert.notNull(type, "the type argument must not be null"); @@ -36,6 +31,7 @@ public interface ProductFavoriteMapper extends BaseMapperX { return new PageResult<>(page.getRecords(), page.getTotal()); } + // TODO @jason:内存中拼接哈。这样好兼容更多的 db 类型; Page selectFavoriteProductList(Page page, @Param("userId") Long userId, @Param("type") Integer type); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index 1b295157c..8300cbc8c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -20,7 +20,7 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTIO import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_NOT_EXISTS; /** - * 喜爱商品 Service 实现类 + * 商品收藏 Service 实现类 * * @author jason */ @@ -33,11 +33,15 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Override public Boolean collect(@Valid AppFavoriteReqVO reqVO) { + // TODO @jason:userId 要从 Controller 传递过来,Service 不能有转台 Long userId = getLoginUserId(); + // TODO @jason:代码缩进不对; ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.nonNull(favoriteDO)) { throw exception(COLLECTION_EXISTS); } + + // TODO @jason:插入只有成功,不用判断 1 ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); int count = mapper.insert(entity); return count == 1; @@ -45,11 +49,13 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Override public Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO) { + // TODO @jason:代码缩进不对; Long loginUserId = getLoginUserId(); ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(loginUserId, reqVO.getSpuId(), reqVO.getType()); if (Objects.isNull(favoriteDO)) { throw exception(COLLECTION_NOT_EXISTS); } + // TODO @jason:插入只有成功,不用判断 1 int count = mapper.deleteById(favoriteDO.getId()); return count == 1; } @@ -59,4 +65,5 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { Long userId = getLoginUserId(); return mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); } + } From 14d02bdfb3931be8f98ebdcb4bfd6737e27d876b Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 6 May 2023 11:58:27 +0800 Subject: [PATCH 036/232] =?UTF-8?q?=E5=95=86=E5=93=81=E6=94=B6=E8=97=8F?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 4 +- .../app/favorite/AppFavoriteController.java | 43 ++++++----- .../app/favorite/vo/AppFavoriteReqVO.java | 2 +- .../app/favorite/vo/AppFavoriteRespVO.java | 12 ++-- .../favorite/ProductFavoriteConvert.java | 6 ++ .../favorite/ProductFavoriteDO.java | 9 ++- .../mysql/favorite/ProductFavoriteMapper.java | 26 +++---- .../favorite/ProductFavoriteService.java | 19 +++-- .../favorite/ProductFavoriteServiceImpl.java | 72 ++++++++++++------- .../mapper/favorite/ProductFavoriteMapper.xml | 22 ------ 10 files changed, 117 insertions(+), 98 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 5c36a2328..0ae400999 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -49,7 +49,7 @@ public interface ErrorCodeConstants { ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); // ========== 商品 收藏 1008008000 ========== - ErrorCode COLLECTION_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); - ErrorCode COLLECTION_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); + ErrorCode PRODUCT_FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); + ErrorCode PRODUCT_FAVORITE_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 9d1d53dd3..1b085e144 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -1,22 +1,20 @@ package cn.iocoder.yudao.module.product.controller.app.favorite; -import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; -import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.Objects; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum.COLLECT; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 APP - 商品收藏") @RestController @@ -26,30 +24,31 @@ public class AppFavoriteController { @Resource private ProductFavoriteService productFavoriteService; - // TODO @jason:创建;create - @PostMapping(value = "/collect") + @PostMapping(value = "/create") @Operation(summary = "商品收藏") - public CommonResult collect(@RequestBody @Valid AppFavoriteReqVO reqVO) { - Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配"); - return success(productFavoriteService.collect(reqVO)); + public CommonResult create(@RequestBody @Valid AppFavoriteReqVO reqVO) { + Long loginUserId = getLoginUserId(); + return success(productFavoriteService.create(loginUserId, reqVO)); } - // TODO @jason:创建;delete;使用 @DeleteMapping - @PostMapping(value = "/cancelCollect") + @DeleteMapping(value = "/delete") @Operation(summary = "取消商品收藏(通过商品详情)") - public CommonResult cancelCollect(@RequestBody @Valid AppFavoriteReqVO reqVO) { - // TODO @jason:是不是不用校验呀? - Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配"); - return success(productFavoriteService.cancelCollect(reqVO)); + public CommonResult delete(@RequestBody @Valid AppFavoriteReqVO reqVO) { + Long loginUserId = getLoginUserId(); + return success(productFavoriteService.delete(loginUserId,reqVO)); } - // TODO @jason:page;分页 - @GetMapping(value = "/collectList") - @Operation(summary = "商品收藏列表") - public CommonResult> pageCollectList(AppFavoritePageReqVO reqVO) { - return success(productFavoriteService.pageCollectList(reqVO)); + @GetMapping(value = "/page") + @Operation(summary = "分页获取商品收藏列表") + public CommonResult> page(AppFavoritePageReqVO reqVO) { + Long userId = getLoginUserId(); + return success(productFavoriteService.page(userId,reqVO)); } - // TODO @json:需要在给一个,用户查询某个商品是否收藏;详情页要用 - + @GetMapping(value = "/checkFavorite") + @Operation(summary = "检查是否收藏过商品") + public CommonResult checkFavorite(AppFavoriteReqVO reqVO) { + Long userId = getLoginUserId(); + return success(productFavoriteService.checkFavorite(userId,reqVO)); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index d4f2ba760..292750a7b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -@Schema(description = "用户 APP - 商品收藏创建 Request VO") +@Schema(description = "用户 APP - 商品收藏 Request VO") @Data public class AppFavoriteReqVO { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java index 686a24d6d..da6937c5b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -3,24 +3,22 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + @Schema(description = "用户APP - 商品收藏 Response VO") @Data public class AppFavoriteRespVO { - // TODO @jason:required true 哈 - @Schema(description = "编号", example = "1") + @Schema(description = "编号", requiredMode = REQUIRED, example = "1") private Long id; - // TODO @jason:required true 哈 - @Schema(description = "商品 SPU 编号", example = "29502") + @Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502") private Long spuId; - // TODO @jason:required true 哈 - @Schema(description = "类型", example = "1") + @Schema(description = "类型", requiredMode = REQUIRED, example = "1") private Integer type; // ========== 商品相关字段 ========== - @Schema(description = "商品 SPU 名称", example = "赵六") private String spuName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index 03fb1caf9..0d9e5e809 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.product.convert.favorite; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper @@ -11,4 +14,7 @@ public interface ProductFavoriteConvert { ProductFavoriteConvert INSTANCE = Mappers.getMapper(ProductFavoriteConvert.class); ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO); + @Mapping(target = "id", source = "favoriteDO.id") + @Mapping(target = "spuName", source = "spuDO.name") + AppFavoriteRespVO convert(ProductSpuDO spuDO, ProductFavoriteDO favoriteDO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java index 356bba065..177087646 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.product.dal.dataobject.favorite; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -20,7 +21,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductFavoriteDO extends TenantBaseDO { // TODO @jason:如无必要,使用 BaseDO 哈。例如说 tenant_id 在业务里,是否需要使用到 +public class ProductFavoriteDO extends BaseDO { /** * 编号,主键自增 @@ -40,7 +41,9 @@ public class ProductFavoriteDO extends TenantBaseDO { // TODO @jason:如无必 */ private Long spuId; /** - * 类型 1 收藏;2 点赞 // TODO @jason:不要注释 1 收藏 2 点赞;而是注释好,它对应的枚举类 + * 类型 + * + * 枚举 {@link ProductFavoriteTypeEnum} */ private Integer type; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index 435152ea7..a9c19026a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -15,24 +16,23 @@ import org.apache.ibatis.annotations.Param; @Mapper public interface ProductFavoriteMapper extends BaseMapperX { - default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) { - Assert.notNull(userId, "the userId argument must not be null"); - Assert.notNull(spuId, "the spuId argument must not be null"); - Assert.notNull(type, "the type argument must not be null"); + default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) { + Assert.notNull(userId, "the userId must not be null"); + Assert.notNull(spuId, "the spuId must not be null"); + Assert.notNull(type, "the type must not be null"); return selectOne(new LambdaQueryWrapperX() .eq(ProductFavoriteDO::getUserId, userId) .eq(ProductFavoriteDO::getSpuId, spuId) .eq(ProductFavoriteDO::getType, type)); } - default PageResult selectPageByUserAndType(Long userId, Integer type, PageParam pageParam){ - Page page = MyBatisUtils.buildPage(pageParam); - page = selectFavoriteProductList(page, userId, type); - return new PageResult<>(page.getRecords(), page.getTotal()); + default PageResult selectPageByUserAndType(Long userId, Integer type, PageParam pageParam) { + Assert.notNull(userId, "the userId must not be null"); + Assert.notNull(type, "the type must not be null"); + Assert.notNull(pageParam, "the pageParam must not be null"); + return selectPage(pageParam, new LambdaQueryWrapper() + .eq(ProductFavoriteDO::getUserId, userId) + .eq(ProductFavoriteDO::getType, type) + .orderByDesc(ProductFavoriteDO::getId)); } - - // TODO @jason:内存中拼接哈。这样好兼容更多的 db 类型; - Page selectFavoriteProductList(Page page, - @Param("userId") Long userId, - @Param("type") Integer type); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index c1b85af17..d75cb4a2d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -15,20 +15,31 @@ import javax.validation.Valid; public interface ProductFavoriteService { /** - * 商品收藏 + * 创建商品收藏 + * @param userId 用户id * @param reqVO 请求vo */ - Boolean collect(@Valid AppFavoriteReqVO reqVO); + Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO); /** * 取消商品收藏 (通过商品详情页面) + * @param userId 用户id * @param reqVO 请求vo */ - Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO); + Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO); /** * 分页查询用户收藏列表 + * @param userId 用户id * @param reqVO 请求 vo */ - PageResult pageCollectList(@Valid AppFavoritePageReqVO reqVO); + PageResult page(Long userId, @Valid AppFavoritePageReqVO reqVO); + + /** + * 检查是否收藏过商品 + * @param userId 用户id + * @param reqVO 请求 vo + * @return true: 已收藏 false: 未收藏 + */ + Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index 8300cbc8c..d2c741045 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -1,23 +1,29 @@ package cn.iocoder.yudao.module.product.service.favorite; +import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_NOT_EXISTS; /** * 商品收藏 Service 实现类 @@ -27,43 +33,61 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTIO @Service @Validated public class ProductFavoriteServiceImpl implements ProductFavoriteService { - + @Resource + private ProductSpuService productSpuService; @Resource private ProductFavoriteMapper mapper; @Override - public Boolean collect(@Valid AppFavoriteReqVO reqVO) { - // TODO @jason:userId 要从 Controller 传递过来,Service 不能有转台 - Long userId = getLoginUserId(); - // TODO @jason:代码缩进不对; + public Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO) { + Assert.notNull(userId, "the userId must not be null"); ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.nonNull(favoriteDO)) { - throw exception(COLLECTION_EXISTS); + throw exception(PRODUCT_FAVORITE_EXISTS); } - - // TODO @jason:插入只有成功,不用判断 1 ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); - int count = mapper.insert(entity); - return count == 1; + mapper.insert(entity); + return Boolean.TRUE; } @Override - public Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO) { - // TODO @jason:代码缩进不对; - Long loginUserId = getLoginUserId(); - ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(loginUserId, reqVO.getSpuId(), reqVO.getType()); + public Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO) { + Assert.notNull(userId, "the userId must not be null "); + ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.isNull(favoriteDO)) { - throw exception(COLLECTION_NOT_EXISTS); + throw exception(PRODUCT_FAVORITE_NOT_EXISTS); } - // TODO @jason:插入只有成功,不用判断 1 - int count = mapper.deleteById(favoriteDO.getId()); - return count == 1; + mapper.deleteById(favoriteDO.getId()); + return Boolean.TRUE; } @Override - public PageResult pageCollectList(@Valid AppFavoritePageReqVO reqVO) { - Long userId = getLoginUserId(); - return mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + public PageResult page(Long userId, @Valid AppFavoritePageReqVO reqVO) { + Assert.notNull(userId, "the userId must not be null "); + PageResult favorites = mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + if (favorites.getTotal() > 0) { + PageResult pageResult = new PageResult<>(favorites.getTotal()); + List list = favorites.getList(); + //得到商品spu 信息 + List spuIds = CollectionUtils.convertList(list, ProductFavoriteDO::getSpuId); + Map spuMap = CollectionUtils.convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId, val -> val); + List resultList = new ArrayList<>(list.size()); + for (ProductFavoriteDO item : list) { + ProductSpuDO spuDO = spuMap.get(item.getSpuId()); + resultList.add(ProductFavoriteConvert.INSTANCE.convert(spuDO, item)); + } + pageResult.setList(resultList); + return pageResult; + }else { + return PageResult.empty(); + } + } + + @Override + public Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { + Assert.notNull(userId, "the userId must not be null "); + ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); + return Objects.nonNull(favoriteDO); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml b/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml deleted file mode 100644 index 8d2741e03..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - \ No newline at end of file From 0ffa7ff4c8244e208753780602335dc4f78979b7 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Fri, 12 May 2023 19:39:48 +0800 Subject: [PATCH 037/232] =?UTF-8?q?=E5=8F=91=E8=B4=A7=E9=85=8D=E9=80=81?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E8=A1=A8=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 87 ++++++++++++++++++- .../delivery/DeliveryChargeDetailDO.java | 63 ++++++++++++++ .../delivery/DeliveryFreeDetailDO.java | 48 ++++++++++ .../delivery/DeliveryTemplateDO.java | 24 +++++ .../dataobject/delivery/PickUpStoreDO.java | 85 ++++++++++++++++++ .../favorite/ProductFavoriteDO.java | 2 +- .../delivery/DeliveryChargeDetailMapper.java | 14 +++ .../delivery/DeliveryFreeDetailMapper.java | 14 +++ .../delivery/DeliveryTemplateMapper.java | 10 +++ .../dal/mysql/delivery/PickUpStoreMapper.java | 14 +++ .../mysql/favorite/ProductFavoriteMapper.java | 4 - .../favorite/ProductFavoriteService.java | 2 +- 12 files changed, 359 insertions(+), 8 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 77356cf65..ccd975150 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -305,12 +305,95 @@ CREATE TABLE `product_favorite` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='喜欢的商品表'; +) ENGINE=InnoDB COMMENT='商品收藏表'; -- ---------------------------- --- Records of product_spu +-- Table structure for delivery_template -- ---------------------------- +DROP TABLE IF EXISTS `delivery_template`; +CREATE TABLE `delivery_template` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `name` varchar(64) NOT NULL COMMENT '模板名称', + `charge_type` tinyint NOT NULL DEFAULT 1 COMMENT '配送费用类型 1:全区域包邮 2:非全区域包邮', + `charge_mode` tinyint NOT NULL DEFAULT 1 COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', + `sort` int NOT NULL DEFAULT 0 COMMENT '排序', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='配送模板'; + +-- ---------------------------- +-- Table structure for delivery_free_detail +-- ---------------------------- +DROP TABLE IF EXISTS `delivery_free_detail`; +CREATE TABLE `delivery_free_detail` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', + `area_id` int NOT NULL COMMENT '包邮区域id', + `free_price` int NOT NULL COMMENT '包邮金额(单位分) 订单总金额>包邮金额才免运费', + `free_number` int NOT NULL DEFAULT 0 COMMENT '包邮件数,订单总件数>包邮件数才免运费', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='配送包邮详情'; + +-- ---------------------------- +-- Table structure for delivery_charge_detail +-- ---------------------------- +DROP TABLE IF EXISTS `delivery_charge_detail`; +CREATE TABLE `delivery_charge_detail` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', + `area_id` int NOT NULL COMMENT '配送区域id 1:适用于全国', + `charge_mode` tinyint NOT NULL COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', + `start_quantity` double NOT NULL COMMENT '起步数量(件数,重量,或体积)', + `start_price` int NOT NULL COMMENT '起步价(单位分)', + `extra_quantity` double NOT NULL COMMENT '续(件,重量,或体积)', + `extra_price` int NOT NULL COMMENT '额外价(单位分)', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='配送费用详情'; + +-- ---------------------------- +-- Table structure for pick_up_store +-- ---------------------------- +DROP TABLE IF EXISTS `pick_up_store`; +CREATE TABLE `pick_up_store` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `name` varchar(64) NOT NULL COMMENT '门店名称', + `introduction` varchar(256) COMMENT '门店简介', + `phone` varchar(16) NOT NULL COMMENT '门店手机', + `area_id` int NOT NULL COMMENT '区域id', + `address` varchar(256) NOT NULL COMMENT '门店详细地址', + `logo` varchar(256) NOT NULL COMMENT '门店logo', + `opening_time` time NOT NULL COMMENT '营业开始时间', + `closing_time` time NOT NULL COMMENT '营业结束时间', + `latitude` varchar(128) NOT NULL COMMENT '纬度', + `longitude` varchar(128) NOT NULL COMMENT '经度', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '门店状态(0正常 1停用)', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='自提门店'; + BEGIN; COMMIT; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java new file mode 100644 index 000000000..5ee061b93 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 配送费用详情 DO + * + * @author jason + */ +@TableName(value ="delivery_charge_detail") +@KeySequence("delivery_charge_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class DeliveryChargeDetailDO extends BaseDO { + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 配送模板编号, 对应delivery_template表id + */ + private Long templateId; + + /** + * 配送区域id 1:适用于全国 + */ + private Integer areaId; + + /** + * 配送计费方式 1:按件 2:按重量 3:按体积 + */ + private Integer chargeMode; + + /** + * 起步数量(件数,重量,或体积) + */ + private Double startQuantity; + + /** + * 起步价(单位分) + */ + private Integer startPrice; + + /** + * 续(件,重量,或体积) + */ + private Double extraQuantity; + + /** + * 额外价(单位分) + */ + private Integer extraPrice; + + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java new file mode 100644 index 000000000..5ac4bd2cc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 配送包邮详情 DO + * + * @author jason + */ +@TableName(value ="delivery_free_detail") +@KeySequence("delivery_free_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class DeliveryFreeDetailDO extends BaseDO { + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 配送模板编号, 对应delivery_template表id + */ + private Long templateId; + + /** + * 包邮区域id + */ + private Integer areaId; + + /** + * 包邮金额(单位分) 订单总金额>包邮金额才免运费 + */ + private Integer freePrice; + + /** + * 包邮件数,订单总件数>包邮件数才免运费 + */ + private Integer freeNumber; + + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java index 70445dc01..b35dc6574 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -27,4 +28,27 @@ public class DeliveryTemplateDO extends BaseDO { @TableId private Long id; + /** + * 模板名称 + */ + private String name; + + /** + * 配送费用类型 1:全区域包邮 2:非全区域包邮 + */ + private Integer chargeType; + + /** + * 配送计费方式 1:按件 2:按重量 3:按体积 + */ + private Integer chargeMode; + + /** + * 排序 + */ + private Integer sort; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java new file mode 100644 index 000000000..b773aefd4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java @@ -0,0 +1,85 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalTime; + +/** + * 自提门店 DO + * + * @author jason + */ +@TableName(value ="pick_up_store") +@KeySequence("pick_up_store_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class PickUpStoreDO extends BaseDO { + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 门店名称 + */ + private String name; + + /** + * 门店简介 + */ + private String introduction; + + /** + * 门店手机 + */ + private String phone; + + /** + * 区域id + */ + private Integer areaId; + + /** + * 门店详细地址 + */ + private String address; + + /** + * 门店logo + */ + private String logo; + + /** + * 营业开始时间 + */ + private LocalTime openingTime; + + /** + * 营业结束时间 + */ + private LocalTime closingTime; + + /** + * 纬度 + */ + private String latitude; + + /** + * 经度 + */ + private String longitude; + + /** + * 门店状态(0正常 1停用) + */ + private Integer status; + + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java index 177087646..d99ae0fe6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -9,7 +9,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; /** - * 喜爱商品 DO + * 商品收藏 DO * * @author 芋道源码 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java new file mode 100644 index 000000000..55658efc1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.dal.mysql.delivery; + +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryChargeDetailDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryChargeDetailMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java new file mode 100644 index 000000000..abb0e080a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.dal.mysql.delivery; + +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryFreeDetailDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryFreeDetailMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java new file mode 100644 index 000000000..d6f7fed6b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.module.product.dal.mysql.delivery; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryTemplateMapper extends BaseMapperX { +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java new file mode 100644 index 000000000..d2e81df95 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.dal.mysql.delivery; + +import cn.iocoder.yudao.module.product.dal.dataobject.delivery.PickUpStoreDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PickUpStoreMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index a9c19026a..b9a8c8353 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -5,13 +5,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; @Mapper public interface ProductFavoriteMapper extends BaseMapperX { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index d75cb4a2d..cf245f781 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRes import javax.validation.Valid; /** - * 喜爱商品 Service 接口 + * 商品收藏 Service 接口 * * @author jason */ From 467811a42eeb7f7bb54c3b6d7c73b11c13f786a9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 May 2023 09:07:45 +0800 Subject: [PATCH 038/232] =?UTF-8?q?REVIEW=20=E5=95=86=E5=93=81=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E7=9A=84=E9=80=BB=E8=BE=91=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/favorite/AppFavoriteController.java | 26 ++++++------- .../app/favorite/vo/AppFavoriteReqVO.java | 2 +- .../app/favorite/vo/AppFavoriteRespVO.java | 2 +- .../mysql/favorite/ProductFavoriteMapper.java | 1 + .../favorite/ProductFavoriteService.java | 39 +++++++++++-------- .../favorite/ProductFavoriteServiceImpl.java | 25 ++++++++---- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 1b085e144..4359dd124 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -26,29 +26,27 @@ public class AppFavoriteController { @PostMapping(value = "/create") @Operation(summary = "商品收藏") - public CommonResult create(@RequestBody @Valid AppFavoriteReqVO reqVO) { - Long loginUserId = getLoginUserId(); - return success(productFavoriteService.create(loginUserId, reqVO)); + public CommonResult createFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { + return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO)); } @DeleteMapping(value = "/delete") - @Operation(summary = "取消商品收藏(通过商品详情)") - public CommonResult delete(@RequestBody @Valid AppFavoriteReqVO reqVO) { - Long loginUserId = getLoginUserId(); - return success(productFavoriteService.delete(loginUserId,reqVO)); + @Operation(summary = "取消商品收藏") + public CommonResult deleteFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { + return success(productFavoriteService.deleteFavorite(getLoginUserId(), reqVO)); } @GetMapping(value = "/page") @Operation(summary = "分页获取商品收藏列表") - public CommonResult> page(AppFavoritePageReqVO reqVO) { - Long userId = getLoginUserId(); - return success(productFavoriteService.page(userId,reqVO)); + public CommonResult> getFavoritePage(AppFavoritePageReqVO reqVO) { + return success(productFavoriteService.getFavoritePage(getLoginUserId(),reqVO)); } - @GetMapping(value = "/checkFavorite") + + @GetMapping(value = "/exits") @Operation(summary = "检查是否收藏过商品") - public CommonResult checkFavorite(AppFavoriteReqVO reqVO) { - Long userId = getLoginUserId(); - return success(productFavoriteService.checkFavorite(userId,reqVO)); + public CommonResult isFavoriteExists(AppFavoriteReqVO reqVO) { + return success(productFavoriteService.checkFavorite(getLoginUserId(), reqVO)); } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index 292750a7b..95fa8e867 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -@Schema(description = "用户 APP - 商品收藏 Request VO") +@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏 @Data public class AppFavoriteReqVO { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java index da6937c5b..a0f81a909 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; - import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; @Schema(description = "用户APP - 商品收藏 Response VO") @@ -19,6 +18,7 @@ public class AppFavoriteRespVO { private Integer type; // ========== 商品相关字段 ========== + @Schema(description = "商品 SPU 名称", example = "赵六") private String spuName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index b9a8c8353..33e027aa6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -31,4 +31,5 @@ public interface ProductFavoriteMapper extends BaseMapperX { .eq(ProductFavoriteDO::getType, type) .orderByDesc(ProductFavoriteDO::getId)); } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index cf245f781..262cef1af 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -16,30 +16,37 @@ public interface ProductFavoriteService { /** * 创建商品收藏 - * @param userId 用户id - * @param reqVO 请求vo - */ - Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO); - - /** - * 取消商品收藏 (通过商品详情页面) - * @param userId 用户id - * @param reqVO 请求vo - */ - Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO); - - /** - * 分页查询用户收藏列表 - * @param userId 用户id + * + * @param userId 用户 id * @param reqVO 请求 vo */ - PageResult page(Long userId, @Valid AppFavoritePageReqVO reqVO); + Boolean createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + /** + * 取消商品收藏 + * + * @param userId 用户 id + * @param reqVO 请求 vo + */ + Boolean deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + + // TODO @Jason:VO 拼接,可以交给 Controller 哈,Service 尽量简洁 + /** + * 分页查询用户收藏列表 + * + * @param userId 用户 id + * @param reqVO 请求 vo + */ + PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO); + + // TODO @Jason 这个方法最好返回 FavoriteDO 就好。Service 要通用; /** * 检查是否收藏过商品 + * * @param userId 用户id * @param reqVO 请求 vo * @return true: 已收藏 false: 未收藏 */ Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index d2c741045..77d592f6d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -22,8 +22,8 @@ import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.FAVORITE_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.FAVORITE_NOT_EXISTS; /** * 商品收藏 Service 实现类 @@ -33,47 +33,56 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_F @Service @Validated public class ProductFavoriteServiceImpl implements ProductFavoriteService { + @Resource private ProductSpuService productSpuService; + + // TODO @JASON:ProductFavoriteMapper 最好全一点哈。productFavoriteMapper @Resource private ProductFavoriteMapper mapper; @Override - public Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO) { + public Boolean createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { + // TODO @JASON:userId 校验可以去掉,直接在 Controller 要求登录,通过 @PreAuthenticated 注解 Assert.notNull(userId, "the userId must not be null"); ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.nonNull(favoriteDO)) { - throw exception(PRODUCT_FAVORITE_EXISTS); + throw exception(FAVORITE_EXISTS); } ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); mapper.insert(entity); + // TODO @JASON:可以返回 Long id; return Boolean.TRUE; } @Override - public Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO) { + public Boolean deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { Assert.notNull(userId, "the userId must not be null "); ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.isNull(favoriteDO)) { - throw exception(PRODUCT_FAVORITE_NOT_EXISTS); + throw exception(FAVORITE_NOT_EXISTS); } mapper.deleteById(favoriteDO.getId()); + // TODO 可以不返回 return Boolean.TRUE; } @Override - public PageResult page(Long userId, @Valid AppFavoritePageReqVO reqVO) { + public PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO) { Assert.notNull(userId, "the userId must not be null "); PageResult favorites = mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + // TODO @Jason:if return 更好;例如说,如果判断是空,就 return 掉; if (favorites.getTotal() > 0) { PageResult pageResult = new PageResult<>(favorites.getTotal()); List list = favorites.getList(); - //得到商品spu 信息 + // 得到商品 spu 信息 List spuIds = CollectionUtils.convertList(list, ProductFavoriteDO::getSpuId); + // TODO @Jason:这里可以用默认的方法,不用 , val -> val 拉 Map spuMap = CollectionUtils.convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId, val -> val); List resultList = new ArrayList<>(list.size()); for (ProductFavoriteDO item : list) { ProductSpuDO spuDO = spuMap.get(item.getSpuId()); + // TODO @Jason:可以让 convert 整个 convert 放到 mapstruct 里。convert 就是用于各种数据转换,不带逻辑的那种。 resultList.add(ProductFavoriteConvert.INSTANCE.convert(spuDO, item)); } pageResult.setList(resultList); From c21e88860f1c4120772d518023108efa67bbd9aa Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 May 2023 17:35:17 +0800 Subject: [PATCH 039/232] =?UTF-8?q?REVIEW=20=E7=89=A9=E6=B5=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9B=B8=E5=85=B3=E7=9A=84=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../delivery/DeliveryChargeDetailDO.java | 27 +++++++++++-------- .../delivery/DeliveryFreeDetailDO.java | 21 +++++++++------ .../delivery/DeliveryTemplateDO.java | 12 ++++++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java index 5ee061b93..ccbf0bd51 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.product.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +// TODO @Jason:要不就叫 DeliveryExpressTemplateChargeDO;detail 主要用来作为明细,不适合作为条目 /** * 配送费用详情 DO * @@ -16,6 +16,7 @@ import lombok.Data; @KeySequence("delivery_charge_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryChargeDetailDO extends BaseDO { + /** * 编号,自增 */ @@ -24,9 +25,14 @@ public class DeliveryChargeDetailDO extends BaseDO { /** * 配送模板编号, 对应delivery_template表id + * + * // TODO @Jason:如果关联,写法如下 + * + * 关联 {@link DeliveryTemplateDO#getId()} */ private Long templateId; + // TODO @Jason:全国最好使用 0 /** * 配送区域id 1:适用于全国 */ @@ -34,30 +40,29 @@ public class DeliveryChargeDetailDO extends BaseDO { /** * 配送计费方式 1:按件 2:按重量 3:按体积 + * + * 冗余 {@link DeliveryTemplateDO#getChargeMode()} */ private Integer chargeMode; + // TODO @Jason:startCount;一般 count 作为数量哈 /** - * 起步数量(件数,重量,或体积) + * 首件数量(件数,重量,或体积) */ private Double startQuantity; - /** - * 起步价(单位分) + * 起步价,单位:分 */ private Integer startPrice; + // TODO @Jason:startCount;一般 count 作为数量哈 /** - * 续(件,重量,或体积) + * 续件数量(件,重量,或体积) */ private Double extraQuantity; - /** - * 额外价(单位分) + * 额外价,单位:分 */ private Integer extraPrice; - - @TableField(exist = false) - private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java index 5ac4bd2cc..de6fc9a1e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.product.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +// TODO @Jason:要不就叫 DeliveryExpressTemplateFreeDO;detail 主要用来作为明细,不适合作为条目 /** * 配送包邮详情 DO * @@ -16,6 +16,7 @@ import lombok.Data; @KeySequence("delivery_free_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryFreeDetailDO extends BaseDO { + /** * 编号,自增 */ @@ -23,7 +24,9 @@ public class DeliveryFreeDetailDO extends BaseDO { private Long id; /** - * 配送模板编号, 对应delivery_template表id + * 配送模板编号 + * + * 关联 {@link DeliveryTemplateDO#getId()} */ private Long templateId; @@ -33,16 +36,18 @@ public class DeliveryFreeDetailDO extends BaseDO { private Integer areaId; /** - * 包邮金额(单位分) 订单总金额>包邮金额才免运费 + * 包邮金额,单位:分 + * + * 订单总金额 > 包邮金额时,才免运费 */ private Integer freePrice; + // TODO @Jason:freeCount;一般 count 作为数量哈 /** - * 包邮件数,订单总件数>包邮件数才免运费 + * 包邮件数 + * + * 订单总件数 > 包邮件数时,才免运费 */ private Integer freeNumber; - - @TableField(exist = false) - private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java index b35dc6574..815d85617 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java @@ -2,11 +2,16 @@ package cn.iocoder.yudao.module.product.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +// TODO @Jason:配送放到 trade 里。然后属于 deliver 配送;配送分成两个方式:1)快递 express;2)自提 pickup; +// 这样的话,实体名字一个是 DeliveryExpressTemplateDO;长一点没关系哈;还有一个 DeliveryPickUpStoreDO 自提门店; +// 表名的话,还是加上 trade_delivery_ 前缀,主要归属在交易域 + +// TODO @Jason:额外补充,不是这个类哈。应该还有个快递;DeliveryExpress;需要设计下这个表 + /** * 配送模板 SPU DO * @@ -33,11 +38,13 @@ public class DeliveryTemplateDO extends BaseDO { */ private String name; + // TODO @Jason 我看了下,crmeb 界面是假的,没有全国包邮、部分包邮、自定义;直接干掉这个字段号了;没啥用。 /** * 配送费用类型 1:全区域包邮 2:非全区域包邮 */ private Integer chargeType; + // TODO @Jason:1:按件 2:按重量 3:按体积 枚举,然后关联下 /** * 配送计费方式 1:按件 2:按重量 3:按体积 */ @@ -48,7 +55,4 @@ public class DeliveryTemplateDO extends BaseDO { */ private Integer sort; - @TableField(exist = false) - private static final long serialVersionUID = 1L; - } From 7fef594390687955ba85d220d06d108131b06a54 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 May 2023 17:35:34 +0800 Subject: [PATCH 040/232] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E7=9A=84=E6=A2=B3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 4 +- .../dataobject/delivery/PickUpStoreDO.java | 20 +-- .../service/spu/ProductSpuServiceImpl.java | 16 +- .../seckilltime/SeckillTimeMapper.java | 5 - .../enums/order/TradeOrderStatusEnum.java | 2 - .../admin/order/vo/TradeOrderBaseVO.java | 4 - .../app/order/AppTradeOrderController.http | 6 +- .../app/order/AppTradeOrderController.java | 109 ++++++++++-- .../order/vo/AppTradeOrderCreateReqVO.java | 34 +--- .../order/vo/AppTradeOrderDetailRespVO.java | 9 +- .../vo/AppTradeOrderGetCreateInfoRespVO.java | 168 ------------------ .../order/vo/AppTradeOrderPageItemRespVO.java | 5 + .../vo/AppTradeOrderSettlementReqVO.java | 23 +++ .../vo/AppTradeOrderSettlementRespVO.java | 116 ++++++++++++ .../convert/order/TradeOrderConvert.java | 1 - .../dal/dataobject/order/TradeOrderDO.java | 4 - .../dataobject/order/TradeOrderItemDO.java | 7 + .../service/order/TradeOrderServiceImpl.java | 54 +++--- .../service/order/TradeOrderServiceTest.java | 12 +- .../app/address/vo/AppAddressBaseVO.java | 7 +- .../dal/dataobject/address/AddressDO.java | 4 - .../admin/order/vo/PayOrderBaseVO.java | 4 + .../app/order/AppPayOrderController.java | 19 +- .../pay/convert/order/PayOrderConvert.java | 2 +- 24 files changed, 344 insertions(+), 291 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 0ae400999..ed0a95445 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -49,7 +49,7 @@ public interface ErrorCodeConstants { ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); // ========== 商品 收藏 1008008000 ========== - ErrorCode PRODUCT_FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); - ErrorCode PRODUCT_FAVORITE_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); + ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); + ErrorCode FAVORITE_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在"); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java index b773aefd4..ce381123d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.module.product.dal.dataobject.delivery; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalTime; +// TODO @Jason:DeliveryPickUpStoreDO /** * 自提门店 DO * @@ -18,6 +19,7 @@ import java.time.LocalTime; @KeySequence("pick_up_store_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class PickUpStoreDO extends BaseDO { + /** * 编号,自增 */ @@ -40,17 +42,18 @@ public class PickUpStoreDO extends BaseDO { private String phone; /** - * 区域id + * 区域 id */ private Integer areaId; + // TODO Jason:改成 detailAddress,主要和 AddressDO 保持一致哈 /** * 门店详细地址 */ private String address; /** - * 门店logo + * 门店 logo */ private String logo; @@ -58,7 +61,6 @@ public class PickUpStoreDO extends BaseDO { * 营业开始时间 */ private LocalTime openingTime; - /** * 营业结束时间 */ @@ -68,18 +70,16 @@ public class PickUpStoreDO extends BaseDO { * 纬度 */ private String latitude; - /** * 经度 */ private String longitude; /** - * 门店状态(0正常 1停用) + * 门店状态 + * + * 枚举 {@link CommonStatusEnum} */ private Integer status; - - @TableField(exist = false) - private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index fd1cac880..b047dec4e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -2,14 +2,18 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; @@ -180,8 +184,16 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO) { - //return productSpuMapper.selectPage(pageReqVO); TODO 有差异接口接受参数类型不对 - return null; + // 查找时,如果查找某个分类编号,则包含它的子分类。因为顶级分类不包含商品 + Set categoryIds = new HashSet<>(); + if (pageReqVO.getCategoryId() != null && pageReqVO.getCategoryId() > 0) { + categoryIds.add(pageReqVO.getCategoryId()); + List categoryChildren = categoryService.getEnableCategoryList(new ProductCategoryListReqVO() + .setParentId(pageReqVO.getCategoryId()).setStatus(CommonStatusEnum.ENABLE.getStatus())); + categoryIds.addAll(CollectionUtils.convertList(categoryChildren, ProductCategoryDO::getId)); + } + // 分页查询 + return productSpuMapper.selectPage(pageReqVO, categoryIds); } @Override diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java index c34484e8c..46cfe5d3a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java @@ -10,11 +10,6 @@ import java.time.LocalTime; import java.util.Collection; import java.util.List; -/** - * 秒杀时段 Mapper - * - * @author halfninety - */ @Mapper public interface SeckillTimeMapper extends BaseMapperX { diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java index 06fc3821e..86d3d996f 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java @@ -23,8 +23,6 @@ public enum TradeOrderStatusEnum implements IntArrayValuable { COMPLETED(30, "已完成"), CANCELED(40, "已取消"); - // TODO 芋艿: TAKE("待核验"):虚拟订单需要核验商品 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderStatusEnum::getStatus).toArray(); /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java index b7e034bbb..a1428c436 100755 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java @@ -4,7 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -import java.util.Date; /** * 交易订单 Base VO,提供给添加、修改、详细的子 VO 使用 @@ -118,9 +117,6 @@ public class TradeOrderBaseVO { @Schema(description = "收件人地区编号", required = true, example = "110000") private Integer receiverAreaId; - @Schema(description = "收件人邮编", required = true, example = "100000") - private Integer receiverPostCode; - @Schema(description = "收件人详细地址", required = true, example = "中关村大街 1 号") private String receiverDetailAddress; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http index 8e7746359..8a3ed4867 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -1,6 +1,6 @@ -### /trade-order/confirm-create-order-info 基于商品,确认创建订单 -GET {{appApi}}/trade/order/get-create-info?items[0].skuId=1&items[0].count=1 -Authorization: Bearer {{user-access-token}} +### /trade-order/settlement 获得订单结算信息 +GET {{appApi}}/trade/order/settlement?cartIds=1 +Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} ### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 4a36d4acc..945964b16 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.trade.controller.app.order; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -21,7 +21,11 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -40,12 +44,78 @@ public class AppTradeOrderController { @Resource private ProductPropertyValueApi productPropertyValueApi; - @GetMapping("/get-create-info") - @Operation(summary = "基于商品,确认创建订单") + @GetMapping("/settlement") + @Operation(summary = "获得订单结算信息") @PreAuthenticated - public CommonResult getOrderCreateInfo(AppTradeOrderCreateReqVO createReqVO) { + public CommonResult settlementOrder( + @Valid AppTradeOrderSettlementReqVO settlementReqVO) { // return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); - return null; + AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO(); + + AppTradeOrderSettlementRespVO.Price price = new AppTradeOrderSettlementRespVO.Price(); + price.setOriginalPrice(1000); + price.setDeliveryPrice(200); + price.setCouponPrice(100); + price.setPointPrice(50); + price.setPayPrice(950); + + List skus = new ArrayList<>(); + + AppTradeOrderSettlementRespVO.Item item1 = new AppTradeOrderSettlementRespVO.Item(); + item1.setCartId(1L); + item1.setSpuId(2048L); + item1.setSpuName("Apple iPhone 12"); + item1.setSkuId(1024); + item1.setPrice(500); + item1.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); + item1.setCount(2); + List properties1 = new ArrayList<>(); + AppProductPropertyValueDetailRespVO property1 = new AppProductPropertyValueDetailRespVO(); + property1.setPropertyId(1L); + property1.setPropertyName("尺寸"); + property1.setValueId(2L); + property1.setValueName("大"); + properties1.add(property1); + item1.setProperties(properties1); + + AppTradeOrderSettlementRespVO.Item item2 = new AppTradeOrderSettlementRespVO.Item(); + item2.setCartId(2L); + item2.setSpuId(3072L); + item2.setSpuName("Samsung Galaxy S21"); + item2.setSkuId(2048); + item2.setPrice(800); + item2.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); + item2.setCount(1); + List properties2 = new ArrayList<>(); + AppProductPropertyValueDetailRespVO property2 = new AppProductPropertyValueDetailRespVO(); + property2.setPropertyId(10L); + property2.setPropertyName("颜色"); + property2.setValueId(20L); + property2.setValueName("白色"); + properties2.add(property2); + item2.setProperties(properties2); + + skus.add(item1); + skus.add(item2); + + settlement.setItems(skus); + settlement.setPrice(price); + + AppTradeOrderSettlementRespVO.Address address = new AppTradeOrderSettlementRespVO.Address(); + address.setId(1L); + address.setName("John"); + address.setMobile("18888888888"); + address.setProvinceId(1L); + address.setProvinceName("Beijing"); + address.setCityId(1L); + address.setCityName("Beijing"); + address.setDistrictId(1L); + address.setDistrictName("Chaoyang Distripct"); + address.setDetailAddress("No. 10, Xinzhong Street, Chaoyang District"); + address.setDefaulted(true); + settlement.setAddress(address); + + return success(settlement); } @PostMapping("/create") @@ -53,12 +123,13 @@ public class AppTradeOrderController { @PreAuthenticated public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, HttpServletRequest servletRequest) { - // 获取登录用户、用户 IP 地址 - Long loginUserId = getLoginUserId(); - String clientIp = ServletUtils.getClientIP(servletRequest); - // 创建交易订单,预支付记录 - Long orderId = tradeOrderService.createOrder(loginUserId, clientIp, createReqVO); - return success(orderId); + return success(1L); +// // 获取登录用户、用户 IP 地址 +// Long loginUserId = getLoginUserId(); +// String clientIp = ServletUtils.getClientIP(servletRequest); +// // 创建交易订单,预支付记录 +// Long orderId = tradeOrderService.createOrder(loginUserId, clientIp, createReqVO); +// return success(orderId); } @PostMapping("/update-paid") @@ -85,7 +156,7 @@ public class AppTradeOrderController { } @GetMapping("/page") - @Operation(summary = "获得订单交易分页") + @Operation(summary = "获得交易订单分页") public CommonResult> getOrderPage(AppTradeOrderPageReqVO reqVO) { // 查询订单 PageResult pageResult = tradeOrderService.getOrderPage(getLoginUserId(), reqVO); @@ -99,4 +170,18 @@ public class AppTradeOrderController { return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems, propertyValueDetails)); } + // TODO 芋艿:后续实现 + @GetMapping("/get-count") + @Operation(summary = "获得交易订单数量") + public CommonResult> getOrderCount() { + Map orderCount = new HashMap<>(); + orderCount.put("allCount", 10); + orderCount.put("unpaidCount", 5); + orderCount.put("undeliveredCount", 2); + orderCount.put("deliveredCount", 1); + orderCount.put("uncommentedCount", 3); + orderCount.put("allPrice", 300); + return success(orderCount); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java index 6c881defe..26c48954c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.Valid; -import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; @@ -20,33 +18,13 @@ public class AppTradeOrderCreateReqVO { @Schema(description = "优惠劵编号", example = "1024") private Long couponId; + @Schema(description = "购物车项的编号数组", required = true, example = "true") + @NotEmpty(message = "购物车项不能为空") + private List cartIds; + + // ========== 非 AppTradeOrderSettlementReqVO 字段 ========== + @Schema(description = "备注", example = "这个是我的订单哟") private String remark; - @Schema(description = "是否来自购物车", required = true, example = "true") // true - 来自购物车;false - 立即购买 - @NotNull(message = "是否来自购物车不能为空") - private Boolean fromCart; - - /** - * 订单商品项列表 - */ - @NotEmpty(message = "必须选择购买的商品") - @Valid - private List items; - - @Schema(description = "订单商品项") - @Data - public static class Item { - - @Schema(description = "商品 SKU 编号", required = true, example = "111") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "商品 SKU 购买数量", required = true, example = "1024") - @NotNull(message = "商品 SKU 购买数量不能为空") - @Min(value = 1, message = "商品 SKU 购买数量必须大于 0") - private Integer count; - - } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java index c8a57bacb..54d012fdd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java @@ -40,12 +40,18 @@ public class AppTradeOrderDetailRespVO { // ========== 价格 + 支付基本信息 ========== + @Schema(description = "是否已支付", required = true, example = "true") + private Boolean payed; + @Schema(description = "支付订单编号", required = true, example = "1024") private Long payOrderId; @Schema(description = "付款时间") private LocalDateTime payTime; + @Schema(description = "支付渠道", required = true, example = "wx_lite_pay") + private String payChannelCode; + @Schema(description = "商品原价(总)", required = true, example = "1000") private Integer originalPrice; @@ -87,9 +93,6 @@ public class AppTradeOrderDetailRespVO { @Schema(description = "收件人地区名字", required = true, example = "上海 上海市 普陀区") private String receiverAreaName; - @Schema(description = "收件人邮编", required = true, example = "100000") - private Integer receiverPostCode; - @Schema(description = "收件人详细地址", required = true, example = "中关村大街 1 号") private String receiverDetailAddress; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java deleted file mode 100644 index 86a1b61b7..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java +++ /dev/null @@ -1,168 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.List; - -@Schema(description = "用户 App - 订单获得创建信息 Response VO") -@Data -public class AppTradeOrderGetCreateInfoRespVO { - - /** - * 商品分组数组 - */ - private List itemGroups; - /** - * 费用 - */ - private Fee fee; - -// /** -// * 优惠劵列表 TODO 芋艿,后续改改 -// */ -// private List coupons; - - @Schema(description = "商品分组") // 多个商品,参加同一个活动,从而形成分组 - @Data - public static class ItemGroup { - -// /** -// * 优惠活动 -// */ -// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 - /** - * 商品 SKU 数组 - */ - private List items; - - } - - @Schema(description = "商品 SKU") - @Data - public static class Sku { - - // SKU 自带信息 - @Schema(description = "SKU 编号", required = true, example = "1024") - private Integer id; - /** - * SPU 信息 - */ - private Spu spu; - /** - * 图片地址 - */ - private String picURL; -// /** -// * 属性数组 -// */ -// private List attrs; // TODO 后面改下 - /** - * 价格,单位:分 - */ - private Integer price; - /** - * 库存数量 - */ - private Integer stock; - - // 非 SKU 自带信息 - - /** - * 购买数量 - */ - private Integer buyQuantity; -// /** -// * 优惠活动 -// */ -// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 - /** - * 原始单价,单位:分。 - */ - private Integer originPrice; - /** - * 购买单价,单位:分 - */ - private Integer buyPrice; - /** - * 最终价格,单位:分。 - */ - private Integer presentPrice; - /** - * 购买总金额,单位:分 - * - * 用途类似 {@link #presentTotal} - */ - private Integer buyTotal; - /** - * 优惠总金额,单位:分。 - */ - private Integer discountTotal; - /** - * 最终总金额,单位:分。 - * - * 注意,presentPrice * quantity 不一定等于 presentTotal 。 - * 因为,存在无法整除的情况。 - * 举个例子,presentPrice = 8.33 ,quantity = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。 - * 所以,需要存储一个该字段。 - */ - private Integer presentTotal; - - } - - @Data - public static class Spu { - - /** - * SPU 编号 - */ - private Integer id; - - // ========== 基本信息 ========= - /** - * SPU 名字 - */ - private String name; - /** - * 分类编号 - */ - private Integer cid; - /** - * 商品主图地址 - * - * 数组,以逗号分隔 - * - * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张 - */ - private List picUrls; - - } - - @Schema(description = "费用(合计)") - @Data - @AllArgsConstructor - public static class Fee { - - @Schema(description = "购买总价", required = true, example = "1024") - private Integer buyPrice; - /** - * 优惠总价 - * - * 注意,满多少元包邮,不算在优惠中。 - */ - private Integer discountTotal; - /** - * 邮费 - */ - private Integer postageTotal; - /** - * 最终价格 - * - * 计算公式 = 总价 - 优惠总价 + 邮费 - */ - private Integer presentTotal; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java index d601553e6..75928c946 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -22,6 +22,11 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "购买的商品数量", required = true, example = "10") private Integer productCount; + // ========== 价格 + 支付基本信息 ========== + + @Schema(description = "应付金额,单位:分", required = true, example = "1000") + private Integer payPrice; + /** * 订单项数组 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java new file mode 100644 index 000000000..973db183e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Schema(description = "用户 App - 交易订单结算 Request VO") +@Data +public class AppTradeOrderSettlementReqVO { + + @Schema(description = "收件地址编号", example = "1") + private Long addressId; + + @Schema(description = "优惠劵编号", example = "1024") + private Long couponId; + + @Schema(description = "购物车项的编号数组", required = true, example = "true") + @NotEmpty(message = "购物车项不能为空") + private List cartIds; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java new file mode 100644 index 000000000..3e3dc9d08 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Schema(description = "用户 App - 交易订单结算信息 Response VO") +@Data +public class AppTradeOrderSettlementRespVO { + + @Schema(description = "购物项数组", required = true) + private List items; + + @Schema(description = "费用", required = true) + private Price price; + + @Schema(description = "收件地址", required = true) + private Address address; + + @Schema(description = "购物项") + @Data + public static class Item { + + // ========== SPU 信息 ========== + + @Schema(description = "SPU 编号", required = true, example = "2048") + private Long spuId; + @Schema(description = "SPU 名字", required = true, example = "Apple iPhone 12") + private String spuName; + + // ========== SKU 信息 ========== + + @Schema(description = "SKU 编号", required = true, example = "1024") + private Integer skuId; + @Schema(description = "价格,单位:分", required = true, example = "100") + private Integer price; + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "属性数组", required = true, example = "100") + private List properties; + + // ========== 购物车信息 ========== + + @Schema(description = "购物车编号", required = true, example = "100") + private Long cartId; + + @Schema(description = "购买数量", required = true, example = "1") + private Integer count; + + } + + @Schema(description = "费用(合计)") + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Price { + + @Schema(description = "商品原价(总),单位:分", required = true, example = "500") + private Integer originalPrice; + + @Schema(description = "运费金额,单位:分", required = true, example = "50") + private Integer deliveryPrice; + + @Schema(description = "优惠劵减免金额,单位:分", required = true, example = "100") + private Integer couponPrice; + + @Schema(description = "积分抵扣的金额,单位:分", required = true, example = "50") + private Integer pointPrice; + + @Schema(description = "实际支付金额(总),单位:分", required = true, example = "450") + private Integer payPrice; + + } + + @Schema(description = "费用(合计)") + @Data + public static class Address { + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "收件人名称", required = true, example = "小王") + private String name; + + @Schema(description = "手机号", required = true, example = "15601691300") + private String mobile; + + @Schema(description = "省份编号", required = true, example = "1") + private Long provinceId; + @Schema(description = "省份名字", required = true, example = "北京") + private String provinceName; + + @Schema(description = "城市编号", required = true, example = "1") + private Long cityId; + @Schema(description = "城市名字", required = true, example = "北京") + private String cityName; + + @Schema(description = "地区编号", required = true, example = "1") + private Long districtId; + @Schema(description = "地区名字", required = true, example = "朝阳区") + private String districtName; + + @Schema(description = "详细地址", required = true, example = "望京悠乐汇 A 座") + private String detailAddress; + + @Schema(description = "是否默认收件地址", required = true, example = "true") + private Boolean defaulted; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index b1f0b4b2a..db8ea6879 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -50,7 +50,6 @@ public interface TradeOrderConvert { @Mapping(source = "address.name", target = "receiverName"), @Mapping(source = "address.mobile", target = "receiverMobile"), @Mapping(source = "address.areaId", target = "receiverAreaId"), - @Mapping(source = "address.postCode", target = "receiverPostCode"), @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"), }) TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 49d60ee37..9d031a905 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -212,10 +212,6 @@ public class TradeOrderDO extends BaseDO { * 收件人地区编号 */ private Integer receiverAreaId; - /** - * 收件人邮编 - */ - private Integer receiverPostCode; /** * 收件人详细地址 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index f8438030b..0bc403f0e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; @@ -42,6 +43,12 @@ public class TradeOrderItemDO extends BaseDO { * 关联 {@link TradeOrderDO#getId()} */ private Long orderId; + /** + * 购物车项编号 + * + * 关联 {@link TradeCartDO#getId()} + */ + private Long cartId; // ========== 商品基本信息; 冗余较多字段,减少关联查询 ========== /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 464cb86a7..9ae7def15 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -30,7 +30,6 @@ import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -49,7 +48,8 @@ import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; @@ -92,7 +92,8 @@ public class TradeOrderServiceImpl implements TradeOrderService { @Transactional(rollbackFor = Exception.class) public Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { // 商品 SKU 检查:可售状态、库存 - List skus = validateSkuSaleable(createReqVO.getItems()); +// List skus = validateSkuSaleable(createReqVO.getItems()); // TODO 芋艿,临时关闭。 + List skus = null; // 商品 SPU 检查:可售状态 List spus = validateSpuSaleable(convertSet(skus, ProductSkuRespDTO::getSpuId)); // 用户收件地址的校验 @@ -112,28 +113,28 @@ public class TradeOrderServiceImpl implements TradeOrderService { return tradeOrderDO.getId(); } - /** - * 校验商品 SKU 是否可出售 - * - * @param items 商品 SKU - * @return 商品 SKU 数组 - */ - private List validateSkuSaleable(List items) { - List skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); - // SKU 不存在 - if (items.size() != skus.size()) { - throw exception(ORDER_CREATE_SKU_NOT_FOUND); - } - // 校验库存不足 - Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); - items.forEach(item -> { - ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); - if (item.getCount() > sku.getStock()) { - throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); - } - }); - return skus; - } +// /** +// * 校验商品 SKU 是否可出售 +// * +// * @param items 商品 SKU +// * @return 商品 SKU 数组 +// */ +// private List validateSkuSaleable(List items) { +// List skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); +// // SKU 不存在 +// if (items.size() != skus.size()) { +// throw exception(ORDER_CREATE_SKU_NOT_FOUND); +// } +// // 校验库存不足 +// Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); +// items.forEach(item -> { +// ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); +// if (item.getCount() > sku.getStock()) { +// throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); +// } +// }); +// return skus; +// } /** * 校验商品 SPU 是否可出售 @@ -506,6 +507,9 @@ public class TradeOrderServiceImpl implements TradeOrderService { @Override public List getOrderItemListByOrderId(Collection orderIds) { + if (CollUtil.isEmpty(orderIds)) { + return Collections.emptyList(); + } return tradeOrderItemMapper.selectListByOrderId(orderIds); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 3c1a44057..55418d52b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.service.order; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.member.api.address.AddressApi; @@ -93,10 +92,12 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { // 准备参数 Long userId = 100L; String userIp = "127.0.0.1"; - AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() - .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) - .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), - new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); +// AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() +// .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) +// .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), +// new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); + AppTradeOrderCreateReqVO reqVO = null; + // TODO 芋艿:重新高下 // mock 方法(商品 SKU 检查) ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) .setPrice(50).setStock(100) @@ -183,7 +184,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); - assertEquals(tradeOrderDO.getReceiverPostCode(), 85757); assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); assertEquals(tradeOrderDO.getAfterSaleStatus(), TradeOrderAfterSaleStatusEnum.NONE.getStatus()); assertEquals(tradeOrderDO.getRefundPrice(), 0); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java index f207ad8be..480403271 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java @@ -1,10 +1,11 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; + import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +// TODO 芋艿:example 缺失 /** * 用户收件地址 Base VO,提供给添加、修改、详细的子 VO 使用 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 @@ -24,10 +25,6 @@ public class AppAddressBaseVO { @NotNull(message = "地区编号不能为空") private Long areaId; - @Schema(description = "邮编", required = true) - @NotEmpty(message = "邮编不能为空") - private String postCode; - @Schema(description = "收件详细地址", required = true) @NotNull(message = "收件详细地址不能为空") private String detailAddress; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java index 467432460..7d8a96250 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java @@ -40,10 +40,6 @@ public class AddressDO extends BaseDO { * 地区编号 */ private Long areaId; - /** - * 邮编 - */ - private String postCode; /** * 收件详细地址 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java index 7991c7c7e..123a119f8 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java @@ -55,6 +55,10 @@ public class PayOrderBaseVO { @NotNull(message = "支付金额,单位:分不能为空") private Long amount; + @Schema(description = "支付金额,单位:分", required = true) + @NotNull(message = "支付金额,单位:分不能为空") + private Long price; + @Schema(description = "渠道手续费,单位:百分比") private Double channelFeeRate; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java index 24a208662..b634909df 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.pay.controller.app.order; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -28,12 +27,20 @@ import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getCli public class AppPayOrderController { @Resource - private PayOrderService orderService; + private PayOrderService payOrderService; + + // TODO 芋艿:临时 demo,技术打样。 + @GetMapping("/get") + @Operation(summary = "获得支付订单") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getOrder(@RequestParam("id") Long id) { + return success(PayOrderConvert.INSTANCE.convert(payOrderService.getOrder(id))); + } @PostMapping("/submit") @Operation(summary = "提交支付订单") public CommonResult submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) { - PayOrderSubmitRespVO respVO = orderService.submitPayOrder(reqVO, getClientIP()); + PayOrderSubmitRespVO respVO = payOrderService.submitPayOrder(reqVO, getClientIP()); return success(PayOrderConvert.INSTANCE.convert3(respVO)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java index 825b8e740..a73d528ba 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespD import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; @@ -28,6 +27,7 @@ public interface PayOrderConvert { PayOrderConvert INSTANCE = Mappers.getMapper(PayOrderConvert.class); + @Mapping(source = "amount", target = "price") PayOrderRespVO convert(PayOrderDO bean); PayOrderRespDTO convert2(PayOrderDO order); From 7a792a7d48306b2cd8091a28f0ccf743840bbb35 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 14 May 2023 23:39:05 +0800 Subject: [PATCH 041/232] =?UTF-8?q?=E5=95=86=E5=93=81=E6=94=B6=E8=97=8F?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/favorite/AppFavoriteController.java | 32 +++++++++-- .../app/favorite/vo/AppFavoriteReqVO.java | 2 +- .../favorite/ProductFavoriteConvert.java | 16 ++++++ .../favorite/ProductFavoriteService.java | 14 ++--- .../favorite/ProductFavoriteServiceImpl.java | 56 ++++--------------- 5 files changed, 63 insertions(+), 57 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 4359dd124..9859e433e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -2,10 +2,15 @@ package cn.iocoder.yudao.module.product.controller.app.favorite; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; @@ -13,6 +18,9 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.List; +import java.util.Objects; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -23,30 +31,46 @@ public class AppFavoriteController { @Resource private ProductFavoriteService productFavoriteService; + @Resource + private ProductSpuService productSpuService; @PostMapping(value = "/create") @Operation(summary = "商品收藏") - public CommonResult createFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { + //@PreAuthenticated TODO 暂时注释 + public CommonResult createFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO)); } @DeleteMapping(value = "/delete") @Operation(summary = "取消商品收藏") public CommonResult deleteFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { - return success(productFavoriteService.deleteFavorite(getLoginUserId(), reqVO)); + productFavoriteService.deleteFavorite(getLoginUserId(), reqVO); + return success(Boolean.TRUE); } @GetMapping(value = "/page") @Operation(summary = "分页获取商品收藏列表") public CommonResult> getFavoritePage(AppFavoritePageReqVO reqVO) { - return success(productFavoriteService.getFavoritePage(getLoginUserId(),reqVO)); + PageResult favorites = productFavoriteService.getFavoritePage(getLoginUserId(), reqVO); + if (favorites.getTotal() <= 0) { + return success(PageResult.empty()); + } + List productFavoriteList = favorites.getList(); + // 得到商品 spu 信息 + List spuIds = CollectionUtils.convertList(productFavoriteList, ProductFavoriteDO::getSpuId); + List spuList = productSpuService.getSpuList(spuIds); + //转换 VO + PageResult pageResult = new PageResult<>(favorites.getTotal()); + pageResult.setList(ProductFavoriteConvert.INSTANCE.convertList(productFavoriteList, spuList)); + return success(pageResult); } @GetMapping(value = "/exits") @Operation(summary = "检查是否收藏过商品") public CommonResult isFavoriteExists(AppFavoriteReqVO reqVO) { - return success(productFavoriteService.checkFavorite(getLoginUserId(), reqVO)); + ProductFavoriteDO favoriteDO = productFavoriteService.getFavorite(getLoginUserId(), reqVO); + return success(Objects.nonNull(favoriteDO)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index 95fa8e867..415b474ab 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏 +@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏, 获取收藏 @Data public class AppFavoriteReqVO { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index 0d9e5e809..097a877fc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.convert.favorite; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; @@ -8,13 +9,28 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + @Mapper public interface ProductFavoriteConvert { ProductFavoriteConvert INSTANCE = Mappers.getMapper(ProductFavoriteConvert.class); ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO); + @Mapping(target = "id", source = "favoriteDO.id") @Mapping(target = "spuName", source = "spuDO.name") AppFavoriteRespVO convert(ProductSpuDO spuDO, ProductFavoriteDO favoriteDO); + + default List convertList(List productFavoriteDOList, List productSpuDOList) { + List resultList = new ArrayList<>(productFavoriteDOList.size()); + Map spuMap = CollectionUtils.convertMap(productSpuDOList, ProductSpuDO::getId); + for (ProductFavoriteDO item : productFavoriteDOList) { + ProductSpuDO spuDO = spuMap.get(item.getSpuId()); + resultList.add(convert(spuDO, item)); + } + return resultList; + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index 262cef1af..2c6076969 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import javax.validation.Valid; @@ -20,7 +21,7 @@ public interface ProductFavoriteService { * @param userId 用户 id * @param reqVO 请求 vo */ - Boolean createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + Long createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); /** * 取消商品收藏 @@ -28,25 +29,22 @@ public interface ProductFavoriteService { * @param userId 用户 id * @param reqVO 请求 vo */ - Boolean deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + void deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); - // TODO @Jason:VO 拼接,可以交给 Controller 哈,Service 尽量简洁 /** * 分页查询用户收藏列表 * * @param userId 用户 id * @param reqVO 请求 vo */ - PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO); + PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO); - // TODO @Jason 这个方法最好返回 FavoriteDO 就好。Service 要通用; /** - * 检查是否收藏过商品 + * 获取收藏过商品 * * @param userId 用户id * @param reqVO 请求 vo - * @return true: 已收藏 false: 未收藏 */ - Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + ProductFavoriteDO getFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index 77d592f6d..25ae0966a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -35,68 +35,36 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.FAVORITE_ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Resource - private ProductSpuService productSpuService; - - // TODO @JASON:ProductFavoriteMapper 最好全一点哈。productFavoriteMapper - @Resource - private ProductFavoriteMapper mapper; + private ProductFavoriteMapper productFavoriteMapper; @Override - public Boolean createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - // TODO @JASON:userId 校验可以去掉,直接在 Controller 要求登录,通过 @PreAuthenticated 注解 - Assert.notNull(userId, "the userId must not be null"); - ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); + public Long createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { + ProductFavoriteDO favoriteDO = productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.nonNull(favoriteDO)) { throw exception(FAVORITE_EXISTS); } ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); - mapper.insert(entity); - // TODO @JASON:可以返回 Long id; - return Boolean.TRUE; + productFavoriteMapper.insert(entity); + return entity.getId(); } @Override - public Boolean deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - Assert.notNull(userId, "the userId must not be null "); - ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); + public void deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { + ProductFavoriteDO favoriteDO = productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); if (Objects.isNull(favoriteDO)) { throw exception(FAVORITE_NOT_EXISTS); } - mapper.deleteById(favoriteDO.getId()); - // TODO 可以不返回 - return Boolean.TRUE; + productFavoriteMapper.deleteById(favoriteDO.getId()); } @Override - public PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO) { - Assert.notNull(userId, "the userId must not be null "); - PageResult favorites = mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); - // TODO @Jason:if return 更好;例如说,如果判断是空,就 return 掉; - if (favorites.getTotal() > 0) { - PageResult pageResult = new PageResult<>(favorites.getTotal()); - List list = favorites.getList(); - // 得到商品 spu 信息 - List spuIds = CollectionUtils.convertList(list, ProductFavoriteDO::getSpuId); - // TODO @Jason:这里可以用默认的方法,不用 , val -> val 拉 - Map spuMap = CollectionUtils.convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId, val -> val); - List resultList = new ArrayList<>(list.size()); - for (ProductFavoriteDO item : list) { - ProductSpuDO spuDO = spuMap.get(item.getSpuId()); - // TODO @Jason:可以让 convert 整个 convert 放到 mapstruct 里。convert 就是用于各种数据转换,不带逻辑的那种。 - resultList.add(ProductFavoriteConvert.INSTANCE.convert(spuDO, item)); - } - pageResult.setList(resultList); - return pageResult; - }else { - return PageResult.empty(); - } + public PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO) { + return productFavoriteMapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); } @Override - public Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - Assert.notNull(userId, "the userId must not be null "); - ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); - return Objects.nonNull(favoriteDO); + public ProductFavoriteDO getFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { + return productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); } } From 4b643a7b3405baedf9d07b906ee93a63db89f0cb Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 15 May 2023 23:05:39 +0800 Subject: [PATCH 042/232] =?UTF-8?q?=E7=89=A9=E6=B5=81=E9=85=8D=E9=80=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E8=A1=A8=E7=BB=93=E6=9E=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 98 ++++++++++++++----- .../delivery/DeliveryChargeDetailDO.java | 68 ------------- .../dal/dataobject/spu/ProductSpuDO.java | 4 +- .../delivery/DeliveryChargeDetailMapper.java | 14 --- .../delivery/DeliveryFreeDetailMapper.java | 14 --- .../delivery/DeliveryTemplateMapper.java | 10 -- .../dal/mysql/delivery/PickUpStoreMapper.java | 14 --- .../DeliveryExpressChargeModeEnum.java | 35 +++++++ .../delivery/DeliveryExpressDO.java | 52 ++++++++++ .../DeliveryExpressTemplateChargeDO.java | 63 ++++++++++++ .../delivery/DeliveryExpressTemplateDO.java} | 29 ++---- .../DeliveryExpressTemplateFreeDO.java} | 16 ++- .../delivery/DeliveryPickUpStoreDO.java} | 12 +-- .../delivery/DeliveryPickUpStoreStaffDO.java | 43 ++++++++ .../mysql/delivery/DeliveryExpressMapper.java | 14 +++ .../DeliveryExpressTemplateChargeMapper.java | 15 +++ .../DeliveryExpressTemplateFreeMapper.java | 14 +++ .../DeliveryExpressTemplateMapper.java | 11 +++ .../delivery/DeliveryPickUpStoreMapper.java | 13 +++ .../DeliveryPickUpStoreStaffMapper.java | 14 +++ 20 files changed, 371 insertions(+), 182 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java rename yudao-module-mall/{yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java => yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java} (53%) rename yudao-module-mall/{yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java => yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java} (55%) rename yudao-module-mall/{yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java => yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java} (73%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreStaffMapper.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index ccd975150..cc95883a8 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -307,15 +307,12 @@ CREATE TABLE `product_favorite` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='商品收藏表'; - +-- Table structure for trade_delivery_express_template -- ---------------------------- --- Table structure for delivery_template --- ---------------------------- -DROP TABLE IF EXISTS `delivery_template`; -CREATE TABLE `delivery_template` ( +DROP TABLE IF EXISTS `trade_delivery_express_template`; +CREATE TABLE `trade_delivery_express_template` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', `name` varchar(64) NOT NULL COMMENT '模板名称', - `charge_type` tinyint NOT NULL DEFAULT 1 COMMENT '配送费用类型 1:全区域包邮 2:非全区域包邮', `charge_mode` tinyint NOT NULL DEFAULT 1 COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', @@ -325,18 +322,18 @@ CREATE TABLE `delivery_template` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='配送模板'; +) ENGINE=InnoDB COMMENT='快递运费模板'; -- ---------------------------- --- Table structure for delivery_free_detail +-- Table structure for trade_delivery_express_template_free -- ---------------------------- -DROP TABLE IF EXISTS `delivery_free_detail`; -CREATE TABLE `delivery_free_detail` ( +DROP TABLE IF EXISTS `trade_delivery_express_template_free`; +CREATE TABLE `trade_delivery_express_template_free` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', `area_id` int NOT NULL COMMENT '包邮区域id', `free_price` int NOT NULL COMMENT '包邮金额(单位分) 订单总金额>包邮金额才免运费', - `free_number` int NOT NULL DEFAULT 0 COMMENT '包邮件数,订单总件数>包邮件数才免运费', + `free_count` int NOT NULL DEFAULT 0 COMMENT '包邮件数,订单总件数>包邮件数才免运费', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -344,20 +341,20 @@ CREATE TABLE `delivery_free_detail` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='配送包邮详情'; +) ENGINE=InnoDB COMMENT='快递运费模板包邮配置'; -- ---------------------------- --- Table structure for delivery_charge_detail +-- Table structure for trade_delivery_express_template_charge -- ---------------------------- -DROP TABLE IF EXISTS `delivery_charge_detail`; -CREATE TABLE `delivery_charge_detail` ( +DROP TABLE IF EXISTS `trade_delivery_express_template_charge`; +CREATE TABLE `trade_delivery_express_template_charge` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', `area_id` int NOT NULL COMMENT '配送区域id 1:适用于全国', `charge_mode` tinyint NOT NULL COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', - `start_quantity` double NOT NULL COMMENT '起步数量(件数,重量,或体积)', + `start_count` double NOT NULL COMMENT '首件数量(件数,重量,或体积)', `start_price` int NOT NULL COMMENT '起步价(单位分)', - `extra_quantity` double NOT NULL COMMENT '续(件,重量,或体积)', + `extra_count` double NOT NULL COMMENT '续件数量(件,重量,或体积)', `extra_price` int NOT NULL COMMENT '额外价(单位分)', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', @@ -366,19 +363,19 @@ CREATE TABLE `delivery_charge_detail` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='配送费用详情'; +) ENGINE=InnoDB COMMENT='快递运费模板计费配置'; -- ---------------------------- --- Table structure for pick_up_store +-- Table structure for trade_delivery_pick_up_store -- ---------------------------- -DROP TABLE IF EXISTS `pick_up_store`; -CREATE TABLE `pick_up_store` ( +DROP TABLE IF EXISTS `trade_delivery_pick_up_store`; +CREATE TABLE `trade_delivery_pick_up_store` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', `name` varchar(64) NOT NULL COMMENT '门店名称', `introduction` varchar(256) COMMENT '门店简介', `phone` varchar(16) NOT NULL COMMENT '门店手机', `area_id` int NOT NULL COMMENT '区域id', - `address` varchar(256) NOT NULL COMMENT '门店详细地址', + `detail_address` varchar(256) NOT NULL COMMENT '门店详细地址', `logo` varchar(256) NOT NULL COMMENT '门店logo', `opening_time` time NOT NULL COMMENT '营业开始时间', `closing_time` time NOT NULL COMMENT '营业结束时间', @@ -394,8 +391,61 @@ CREATE TABLE `pick_up_store` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='自提门店'; -BEGIN; -COMMIT; +-- ---------------------------- +-- Table structure for trade_delivery_pick_up_store_staff +-- ---------------------------- +DROP TABLE IF EXISTS `trade_delivery_pick_up_store_staff`; +CREATE TABLE `trade_delivery_pick_up_store_staff` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + store_id bigint NOT NULL COMMENT '自提门店编号', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='自提门店店员'; + +-- ---------------------------- +-- Table structure for trade_delivery_pick_up_store_staff +-- ---------------------------- +DROP TABLE IF EXISTS `trade_delivery_pick_up_store_staff`; +CREATE TABLE `trade_delivery_pick_up_store_staff` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `admin_user_id` bigint NOT NULL COMMENT '管理员用户id', + store_id bigint NOT NULL COMMENT '自提门店编号', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='自提门店店员'; + + +-- ---------------------------- +-- Table structure for trade_delivery_express +-- ---------------------------- +DROP TABLE IF EXISTS `trade_delivery_express`; +CREATE TABLE `trade_delivery_express` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `code` varchar(64) NOT NULL COMMENT '快递公司 code', + `name` varchar(64) NOT NULL COMMENT '快递公司名称', + `logo` varchar(256) COMMENT '快递公司logo', + `sort` int NOT NULL DEFAULT 0 COMMENT '排序', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='配送快递公司'; SET FOREIGN_KEY_CHECKS = 1; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java deleted file mode 100644 index ccbf0bd51..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryChargeDetailDO.java +++ /dev/null @@ -1,68 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.delivery; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; - -// TODO @Jason:要不就叫 DeliveryExpressTemplateChargeDO;detail 主要用来作为明细,不适合作为条目 -/** - * 配送费用详情 DO - * - * @author jason - */ -@TableName(value ="delivery_charge_detail") -@KeySequence("delivery_charge_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -public class DeliveryChargeDetailDO extends BaseDO { - - /** - * 编号,自增 - */ - @TableId - private Long id; - - /** - * 配送模板编号, 对应delivery_template表id - * - * // TODO @Jason:如果关联,写法如下 - * - * 关联 {@link DeliveryTemplateDO#getId()} - */ - private Long templateId; - - // TODO @Jason:全国最好使用 0 - /** - * 配送区域id 1:适用于全国 - */ - private Integer areaId; - - /** - * 配送计费方式 1:按件 2:按重量 3:按体积 - * - * 冗余 {@link DeliveryTemplateDO#getChargeMode()} - */ - private Integer chargeMode; - - // TODO @Jason:startCount;一般 count 作为数量哈 - /** - * 首件数量(件数,重量,或体积) - */ - private Double startQuantity; - /** - * 起步价,单位:分 - */ - private Integer startPrice; - - // TODO @Jason:startCount;一般 count 作为数量哈 - /** - * 续件数量(件,重量,或体积) - */ - private Double extraQuantity; - /** - * 额外价,单位:分 - */ - private Integer extraPrice; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index e2ed9f2a1..0a14919d3 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -1,10 +1,8 @@ package cn.iocoder.yudao.module.product.dal.dataobject.spu; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -143,7 +141,7 @@ public class ProductSpuDO extends TenantBaseDO { /** * 物流配置模板编号 * - * 关联 {@link DeliveryTemplateDO#getId()} + * 关联 { TradeDeliveryExpressTemplateDO#getId()} */ private Long deliveryTemplateId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java deleted file mode 100644 index 55658efc1..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryChargeDetailMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.delivery; - -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryChargeDetailDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface DeliveryChargeDetailMapper extends BaseMapperX { - -} - - - - diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java deleted file mode 100644 index abb0e080a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryFreeDetailMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.delivery; - -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryFreeDetailDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface DeliveryFreeDetailMapper extends BaseMapperX { - -} - - - - diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java deleted file mode 100644 index d6f7fed6b..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/DeliveryTemplateMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.delivery; - - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface DeliveryTemplateMapper extends BaseMapperX { -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java deleted file mode 100644 index d2e81df95..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/delivery/PickUpStoreMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.delivery; - -import cn.iocoder.yudao.module.product.dal.dataobject.delivery.PickUpStoreDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PickUpStoreMapper extends BaseMapperX { - -} - - - - diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java new file mode 100644 index 000000000..2a2a45ee4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.trade.enums.delivery; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 快递配送计费方式枚举 + * + * @author jason + */ +@AllArgsConstructor +@Getter +public enum DeliveryExpressChargeModeEnum implements IntArrayValuable { + BY_PIECE(1, "按件"), + BY_WEIGHT(2,"按重量"), + BY_VOLUME(3, "按体积"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryExpressChargeModeEnum::getType).toArray(); + /** + * 类型 + */ + private final Integer type; + /** + * 描述 + */ + private final String desc; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java new file mode 100644 index 000000000..4adab07ff --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 配送快递公司 DO + * + * @author jason + */ +@TableName(value ="trade_delivery_express") +@KeySequence("trade_delivery_express_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class DeliveryExpressDO extends BaseDO { + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 快递公司 code + */ + private String code; + + /** + * 快递公司名称 + */ + private String name; + + /** + * 快递公司logo + */ + private String logo; + + /** + * 排序 + */ + private Integer sort; + + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java new file mode 100644 index 000000000..17912f15b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 快递运费模板计费配置 DO + * + * @author jason + */ +@TableName(value ="trade_delivery_express_template_charge") +@KeySequence("trade_delivery_express_template_charge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class DeliveryExpressTemplateChargeDO extends BaseDO { + + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 配送模板编号 + * + * 关联 {@link DeliveryExpressTemplateDO#getId()} + */ + private Long templateId; + + // TODO @Jason:全国最好使用 0 @芋艿 Area.ID_CHINA 是 1 + /** + * 配送区域id 1:适用于全国 + */ + private Integer areaId; + + /** + * 配送计费方式 + * + * 冗余 {@link DeliveryExpressTemplateDO#getChargeMode()} + */ + private Integer chargeMode; + + /** + * 首件数量(件数,重量,或体积) + */ + private Double startCount; + /** + * 起步价,单位:分 + */ + private Integer startPrice; + + /** + * 续件数量(件, 重量,或体积) + */ + private Double extraCount; + /** + * 额外价,单位:分 + */ + private Integer extraPrice; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java similarity index 53% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java index 815d85617..b542f7702 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java @@ -1,6 +1,7 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.delivery; +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -13,19 +14,14 @@ import lombok.*; // TODO @Jason:额外补充,不是这个类哈。应该还有个快递;DeliveryExpress;需要设计下这个表 /** - * 配送模板 SPU DO + * 快递运费模板 DO * - * @author 芋道源码 + * @author jason */ -@TableName("delivery_template") -@KeySequence("delivery_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName("trade_delivery_express_template") +@KeySequence("trade_delivery_express_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class DeliveryTemplateDO extends BaseDO { +public class DeliveryExpressTemplateDO extends BaseDO { /** * 编号,自增 @@ -38,15 +34,10 @@ public class DeliveryTemplateDO extends BaseDO { */ private String name; - // TODO @Jason 我看了下,crmeb 界面是假的,没有全国包邮、部分包邮、自定义;直接干掉这个字段号了;没啥用。 /** - * 配送费用类型 1:全区域包邮 2:非全区域包邮 - */ - private Integer chargeType; - - // TODO @Jason:1:按件 2:按重量 3:按体积 枚举,然后关联下 - /** - * 配送计费方式 1:按件 2:按重量 3:按体积 + * 配送计费方式 + * + * 枚举 {@link DeliveryExpressChargeModeEnum} */ private Integer chargeMode; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java similarity index 55% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java index de6fc9a1e..ffc59a615 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryFreeDetailDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.delivery; +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -6,16 +6,15 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -// TODO @Jason:要不就叫 DeliveryExpressTemplateFreeDO;detail 主要用来作为明细,不适合作为条目 /** - * 配送包邮详情 DO + * 快递运费模板包邮配置 DO * * @author jason */ -@TableName(value ="delivery_free_detail") -@KeySequence("delivery_free_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName(value ="trade_delivery_express_template_free") +@KeySequence("trade_delivery_express_template_free_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -public class DeliveryFreeDetailDO extends BaseDO { +public class DeliveryExpressTemplateFreeDO extends BaseDO { /** * 编号,自增 @@ -26,7 +25,7 @@ public class DeliveryFreeDetailDO extends BaseDO { /** * 配送模板编号 * - * 关联 {@link DeliveryTemplateDO#getId()} + * 关联 {@link DeliveryExpressTemplateDO#getId()} */ private Long templateId; @@ -42,12 +41,11 @@ public class DeliveryFreeDetailDO extends BaseDO { */ private Integer freePrice; - // TODO @Jason:freeCount;一般 count 作为数量哈 /** * 包邮件数 * * 订单总件数 > 包邮件数时,才免运费 */ - private Integer freeNumber; + private Integer freeCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java similarity index 73% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java index ce381123d..12c698665 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/PickUpStoreDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.delivery; +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @@ -9,16 +9,15 @@ import lombok.Data; import java.time.LocalTime; -// TODO @Jason:DeliveryPickUpStoreDO /** * 自提门店 DO * * @author jason */ -@TableName(value ="pick_up_store") -@KeySequence("pick_up_store_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName(value ="trade_delivery_pick_up_store") +@KeySequence("trade_delivery_pick_up_store_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -public class PickUpStoreDO extends BaseDO { +public class DeliveryPickUpStoreDO extends BaseDO { /** * 编号,自增 @@ -46,11 +45,10 @@ public class PickUpStoreDO extends BaseDO { */ private Integer areaId; - // TODO Jason:改成 detailAddress,主要和 AddressDO 保持一致哈 /** * 门店详细地址 */ - private String address; + private String detailAddress; /** * 门店 logo diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java new file mode 100644 index 000000000..3bec270de --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 自提门店店员 DO + * + * @author jason + */ +@TableName(value ="trade_delivery_pick_up_store_staff") +@KeySequence("trade_delivery_pick_up_store_staff_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class DeliveryPickUpStoreStaffDO extends BaseDO { + /** + * 编号,自增 + */ + @TableId + private Long id; + + /** + * 自提门店编号 + */ + private Long storeId; + + /** + * 管理员用户id + * + * 关联 {AdminUserDO#getId()} + */ + private Long adminUserId; + + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java new file mode 100644 index 000000000..d2346f21f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryExpressMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java new file mode 100644 index 000000000..c8f36d542 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java new file mode 100644 index 000000000..2e8c47379 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX { + +} + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java new file mode 100644 index 000000000..fa356b51e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; + +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryExpressTemplateMapper extends BaseMapperX { +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java new file mode 100644 index 000000000..d68924047 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryPickUpStoreMapper extends BaseMapperX { +} + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreStaffMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreStaffMapper.java new file mode 100644 index 000000000..06cc14e26 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreStaffMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreStaffDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeliveryPickUpStoreStaffMapper extends BaseMapperX { + +} + + + + From 8ed52701fd0c651b609c632b35447f572c1c0628 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 16 May 2023 19:14:00 +0800 Subject: [PATCH 043/232] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=95=86=E5=93=81?= =?UTF-8?q?=E6=94=B6=E8=97=8F=E7=9A=84=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/favorite/AppFavoriteController.java | 22 +++++++++-------- .../app/favorite/vo/AppFavoriteReqVO.java | 2 +- .../favorite/ProductFavoriteConvert.java | 22 +++++++++-------- .../mysql/favorite/ProductFavoriteMapper.java | 7 ------ .../favorite/ProductFavoriteServiceImpl.java | 24 ++++++++----------- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 9859e433e..f2a41ac5a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.product.controller.app.favorite; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; @@ -17,11 +17,11 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; - import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 APP - 商品收藏") @@ -51,17 +51,19 @@ public class AppFavoriteController { @GetMapping(value = "/page") @Operation(summary = "分页获取商品收藏列表") public CommonResult> getFavoritePage(AppFavoritePageReqVO reqVO) { - PageResult favorites = productFavoriteService.getFavoritePage(getLoginUserId(), reqVO); - if (favorites.getTotal() <= 0) { + PageResult favoritePage = productFavoriteService.getFavoritePage(getLoginUserId(), reqVO); + if (CollUtil.isEmpty(favoritePage.getList())) { return success(PageResult.empty()); } - List productFavoriteList = favorites.getList(); + // 得到商品 spu 信息 - List spuIds = CollectionUtils.convertList(productFavoriteList, ProductFavoriteDO::getSpuId); - List spuList = productSpuService.getSpuList(spuIds); - //转换 VO - PageResult pageResult = new PageResult<>(favorites.getTotal()); - pageResult.setList(ProductFavoriteConvert.INSTANCE.convertList(productFavoriteList, spuList)); + List favorites = favoritePage.getList(); + List spuIds = convertList(favorites, ProductFavoriteDO::getSpuId); + List spus = productSpuService.getSpuList(spuIds); + + // 转换 VO 结果 + PageResult pageResult = new PageResult<>(favoritePage.getTotal()); + pageResult.setList(ProductFavoriteConvert.INSTANCE.convertList(favorites, spus)); return success(pageResult); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index 415b474ab..63da3340b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏, 获取收藏 +@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏、获取收藏 @Data public class AppFavoriteReqVO { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index 097a877fc..d19f67c49 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.convert.favorite; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; @@ -13,6 +12,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + @Mapper public interface ProductFavoriteConvert { @@ -20,17 +21,18 @@ public interface ProductFavoriteConvert { ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO); - @Mapping(target = "id", source = "favoriteDO.id") - @Mapping(target = "spuName", source = "spuDO.name") - AppFavoriteRespVO convert(ProductSpuDO spuDO, ProductFavoriteDO favoriteDO); + @Mapping(target = "id", source = "favorite.id") + @Mapping(target = "spuName", source = "spu.name") + AppFavoriteRespVO convert(ProductSpuDO spu, ProductFavoriteDO favorite); - default List convertList(List productFavoriteDOList, List productSpuDOList) { - List resultList = new ArrayList<>(productFavoriteDOList.size()); - Map spuMap = CollectionUtils.convertMap(productSpuDOList, ProductSpuDO::getId); - for (ProductFavoriteDO item : productFavoriteDOList) { - ProductSpuDO spuDO = spuMap.get(item.getSpuId()); - resultList.add(convert(spuDO, item)); + default List convertList(List favorites, List spus) { + List resultList = new ArrayList<>(favorites.size()); + Map spuMap = convertMap(spus, ProductSpuDO::getId); + for (ProductFavoriteDO favorite : favorites) { + ProductSpuDO spuDO = spuMap.get(favorite.getSpuId()); + resultList.add(convert(spuDO, favorite)); } return resultList; } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index 33e027aa6..0246e0fee 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.dal.mysql.favorite; -import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -13,9 +12,6 @@ import org.apache.ibatis.annotations.Mapper; public interface ProductFavoriteMapper extends BaseMapperX { default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) { - Assert.notNull(userId, "the userId must not be null"); - Assert.notNull(spuId, "the spuId must not be null"); - Assert.notNull(type, "the type must not be null"); return selectOne(new LambdaQueryWrapperX() .eq(ProductFavoriteDO::getUserId, userId) .eq(ProductFavoriteDO::getSpuId, spuId) @@ -23,9 +19,6 @@ public interface ProductFavoriteMapper extends BaseMapperX { } default PageResult selectPageByUserAndType(Long userId, Integer type, PageParam pageParam) { - Assert.notNull(userId, "the userId must not be null"); - Assert.notNull(type, "the type must not be null"); - Assert.notNull(pageParam, "the pageParam must not be null"); return selectPage(pageParam, new LambdaQueryWrapper() .eq(ProductFavoriteDO::getUserId, userId) .eq(ProductFavoriteDO::getType, type) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index 25ae0966a..b1dd84fa5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -1,24 +1,16 @@ package cn.iocoder.yudao.module.product.service.favorite; -import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -39,10 +31,12 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Override public Long createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - ProductFavoriteDO favoriteDO = productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); - if (Objects.nonNull(favoriteDO)) { + ProductFavoriteDO favorite = productFavoriteMapper.selectByUserAndSpuAndType( + userId, reqVO.getSpuId(), reqVO.getType()); + if (Objects.nonNull(favorite)) { throw exception(FAVORITE_EXISTS); } + ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); productFavoriteMapper.insert(entity); return entity.getId(); @@ -50,16 +44,18 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Override public void deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - ProductFavoriteDO favoriteDO = productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); - if (Objects.isNull(favoriteDO)) { + ProductFavoriteDO favorite = productFavoriteMapper.selectByUserAndSpuAndType( + userId, reqVO.getSpuId(), reqVO.getType()); + if (Objects.isNull(favorite)) { throw exception(FAVORITE_NOT_EXISTS); } - productFavoriteMapper.deleteById(favoriteDO.getId()); + + productFavoriteMapper.deleteById(favorite.getId()); } @Override public PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO) { - return productFavoriteMapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + return productFavoriteMapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); } @Override From db73ddc942fc34427b659e053ea0858ba64246fe Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 16 May 2023 19:17:25 +0800 Subject: [PATCH 044/232] =?UTF-8?q?REVIEW=20=E7=89=A9=E6=B5=81=E9=85=8D?= =?UTF-8?q?=E9=80=81=E7=AE=A1=E7=90=86=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/delivery/DeliveryExpressChargeModeEnum.java | 9 ++++++--- .../trade/dal/dataobject/delivery/DeliveryExpressDO.java | 5 +++-- .../delivery/DeliveryExpressTemplateChargeDO.java | 3 +-- .../dataobject/delivery/DeliveryExpressTemplateDO.java | 6 ------ .../dataobject/delivery/DeliveryPickUpStoreStaffDO.java | 7 ++++++- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java index 2a2a45ee4..8ac37e382 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java @@ -14,11 +14,13 @@ import java.util.Arrays; @AllArgsConstructor @Getter public enum DeliveryExpressChargeModeEnum implements IntArrayValuable { - BY_PIECE(1, "按件"), - BY_WEIGHT(2,"按重量"), - BY_VOLUME(3, "按体积"); + + PIECE(1, "按件"), + WEIGHT(2,"按重量"), + VOLUME(3, "按体积"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryExpressChargeModeEnum::getType).toArray(); + /** * 类型 */ @@ -32,4 +34,5 @@ public enum DeliveryExpressChargeModeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java index 4adab07ff..604ce225b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java @@ -16,6 +16,7 @@ import lombok.Data; @KeySequence("trade_delivery_express_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryExpressDO extends BaseDO { + /** * 编号,自增 */ @@ -33,7 +34,7 @@ public class DeliveryExpressDO extends BaseDO { private String name; /** - * 快递公司logo + * 快递公司 logo */ private String logo; @@ -49,4 +50,4 @@ public class DeliveryExpressDO extends BaseDO { */ private Integer status; -} \ No newline at end of file +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java index 17912f15b..803576503 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java @@ -29,9 +29,8 @@ public class DeliveryExpressTemplateChargeDO extends BaseDO { */ private Long templateId; - // TODO @Jason:全国最好使用 0 @芋艿 Area.ID_CHINA 是 1 /** - * 配送区域id 1:适用于全国 + * 配送区域 */ private Integer areaId; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java index b542f7702..b6d6db3b7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java @@ -7,12 +7,6 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -// TODO @Jason:配送放到 trade 里。然后属于 deliver 配送;配送分成两个方式:1)快递 express;2)自提 pickup; -// 这样的话,实体名字一个是 DeliveryExpressTemplateDO;长一点没关系哈;还有一个 DeliveryPickUpStoreDO 自提门店; -// 表名的话,还是加上 trade_delivery_ 前缀,主要归属在交易域 - -// TODO @Jason:额外补充,不是这个类哈。应该还有个快递;DeliveryExpress;需要设计下这个表 - /** * 快递运费模板 DO * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java index 3bec270de..a1a2196ca 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +// TODO @芋艿:后续再详细 review 一轮 /** * 自提门店店员 DO * @@ -16,6 +17,7 @@ import lombok.Data; @KeySequence("trade_delivery_pick_up_store_staff_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryPickUpStoreStaffDO extends BaseDO { + /** * 编号,自增 */ @@ -24,6 +26,8 @@ public class DeliveryPickUpStoreStaffDO extends BaseDO { /** * 自提门店编号 + * + * 关联 {@link DeliveryPickUpStoreDO#getId()} */ private Long storeId; @@ -40,4 +44,5 @@ public class DeliveryPickUpStoreStaffDO extends BaseDO { * 枚举 {@link CommonStatusEnum} */ private Integer status; -} \ No newline at end of file + +} From f129eab36fa941bc91401ac38e463a5055bd10e7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 16 May 2023 21:41:40 +0800 Subject: [PATCH 045/232] =?UTF-8?q?REVIEW=20=E7=89=A9=E6=B5=81=E9=85=8D?= =?UTF-8?q?=E9=80=81=E7=AE=A1=E7=90=86=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/dal/dataobject/delivery/DeliveryExpressDO.java | 7 +++++++ .../dal/dataobject/delivery/DeliveryPickUpStoreDO.java | 1 + .../dataobject/delivery/DeliveryPickUpStoreStaffDO.java | 1 + 3 files changed, 9 insertions(+) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java index 604ce225b..425ad9b06 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java @@ -50,4 +50,11 @@ public class DeliveryExpressDO extends BaseDO { */ private Integer status; + // TODO 芋艿:c 和结算相关的字段,后续在看 + // partnerId 是否需要月结账号 + // partnerKey 是否需要月结密码 + // net 是否需要取件网店 + // account 账号 + // password 网点名称 + // isShow 是否显示 } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java index 12c698665..f347c7912 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java @@ -64,6 +64,7 @@ public class DeliveryPickUpStoreDO extends BaseDO { */ private LocalTime closingTime; + // TODO @Jason:应该是 double? /** * 纬度 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java index a1a2196ca..4c03a8e5d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreStaffDO.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; // TODO @芋艿:后续再详细 review 一轮 +// TODO @芋艿:可能改成 DeliveryPickUpStoreUserDO /** * 自提门店店员 DO * From 3da2eb89b2a05ae6741495e0e23ae756cf0ff8a2 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 18 May 2023 23:37:56 +0800 Subject: [PATCH 046/232] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BF=AB=E9=80=92?= =?UTF-8?q?=E5=85=AC=E5=8F=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 13 ++- .../trade/enums/ErrorCodeConstants.java | 6 +- .../delivery/DeliveryExpressController.java | 92 ++++++++++++++++ .../delivery/vo/DeliveryExpressBaseVO.java | 36 +++++++ .../vo/DeliveryExpressCreateReqVO.java | 14 +++ .../delivery/vo/DeliveryExpressExcelVO.java | 37 +++++++ .../vo/DeliveryExpressExportReqVO.java | 28 +++++ .../delivery/vo/DeliveryExpressPageReqVO.java | 31 ++++++ .../delivery/vo/DeliveryExpressRespVO.java | 19 ++++ .../vo/DeliveryExpressUpdateReqVO.java | 18 ++++ .../delivery/DeliveryExpressConvert.java | 38 +++++++ .../delivery/DeliveryExpressDO.java | 2 +- .../mysql/delivery/DeliveryExpressMapper.java | 29 +++++ .../delivery/DeliveryExpressService.java | 74 +++++++++++++ .../delivery/DeliveryExpressServiceImpl.java | 102 ++++++++++++++++++ 15 files changed, 535 insertions(+), 4 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index cc95883a8..cb760665e 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -433,7 +433,7 @@ CREATE TABLE `trade_delivery_pick_up_store_staff` ( DROP TABLE IF EXISTS `trade_delivery_express`; CREATE TABLE `trade_delivery_express` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `code` varchar(64) NOT NULL COMMENT '快递公司 code', + `code` varchar(64) NOT NULL COMMENT '快递公司编号', `name` varchar(64) NOT NULL COMMENT '快递公司名称', `logo` varchar(256) COMMENT '快递公司logo', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', @@ -445,7 +445,7 @@ CREATE TABLE `trade_delivery_express` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='配送快递公司'; +) ENGINE=InnoDB COMMENT='快递公司'; SET FOREIGN_KEY_CHECKS = 1; @@ -478,6 +478,15 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2164, '配送管理', '', 1, 0, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-18 09:48:48', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2165, '快递发货', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2167, '快递公司', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); INSERT INTO `system_dict_data`(`sort`,`label`,`value`,`dict_type`,`status`,`color_type`,`css_class`,`remark`,`creator`,`create_time`,`updater`,`update_time`,`deleted`) VALUES (1,'打',2,'product_unit',0,'','','',1, NOW(),1, NOW(),0), diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index d6c314147..f6d06340b 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -42,7 +42,11 @@ public interface ErrorCodeConstants { ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】"); ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】"); - // ========== Cart 模块 1-011-001-000 ========== + // ========== Cart 模块 1-011-002-000 ========== ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); + // ========== 物流配送模块 1-011-003-000 ========== + ErrorCode DELIVERY_EXPRESS_NOT_EXISTS = new ErrorCode(1011003000, "快递公司不存在"); + ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java new file mode 100644 index 000000000..58076226f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -0,0 +1,92 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery; + +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +@Tag(name = "管理后台 - 快递公司") +@RestController +@RequestMapping("/trade/delivery/express") +@Validated +public class DeliveryExpressController { + + @Resource + private DeliveryExpressService deliveryExpressService; + + @PostMapping("/create") + @Operation(summary = "创建快递公司") + @PreAuthorize("@ss.hasPermission('trade:delivery:express:create')") + public CommonResult createDeliveryExpress(@Valid @RequestBody DeliveryExpressCreateReqVO createReqVO) { + return success(deliveryExpressService.createDeliveryExpress(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新快递公司") + @PreAuthorize("@ss.hasPermission('trade:delivery:express:update')") + public CommonResult updateDeliveryExpress(@Valid @RequestBody DeliveryExpressUpdateReqVO updateReqVO) { + deliveryExpressService.updateDeliveryExpress(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除快递公司") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('trade:delivery:express:delete')") + public CommonResult deleteDeliveryExpress(@RequestParam("id") Long id) { + deliveryExpressService.deleteDeliveryExpress(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得快递公司") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('trade:delivery:express:query')") + public CommonResult getDeliveryExpress(@RequestParam("id") Long id) { + DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(id); + return success(DeliveryExpressConvert.INSTANCE.convert(deliveryExpress)); + } + + @GetMapping("/page") + @Operation(summary = "获得快递公司分页") + @PreAuthorize("@ss.hasPermission('trade:delivery-express:query')") + public CommonResult> getDeliveryExpressPage(@Valid DeliveryExpressPageReqVO pageVO) { + PageResult pageResult = deliveryExpressService.getDeliveryExpressPage(pageVO); + return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出快递公司 Excel") + @PreAuthorize("@ss.hasPermission('trade:delivery:express:export')") + @OperateLog(type = EXPORT) + public void exportDeliveryExpressExcel(@Valid DeliveryExpressExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = deliveryExpressService.getDeliveryExpressList(exportReqVO); + // 导出 Excel + List dataList = DeliveryExpressConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "快递公司.xls", "数据", DeliveryExpressExcelVO.class, dataList); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java new file mode 100644 index 000000000..ea1a10461 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import javax.validation.constraints.*; + +/** +* 快递公司 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class DeliveryExpressBaseVO { + + @Schema(description = "快递公司编号", required = true) + @NotNull(message = "快递公司编号不能为空") + private String code; + + @Schema(description = "快递公司名称", required = true, example = "李四") + @NotNull(message = "快递公司名称不能为空") + private String name; + + @Schema(description = "快递公司logo") + private String logo; + + @Schema(description = "排序", required = true) + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "状态(0正常 1停用)", required = true, example = "1") + @NotNull(message = "状态(0正常 1停用)不能为空") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java new file mode 100644 index 000000000..2ef4e8070 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 快递公司创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressCreateReqVO extends DeliveryExpressBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java new file mode 100644 index 000000000..ba7e646d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 快递公司 Excel VO + * + * @author jason + */ +@Data +public class DeliveryExpressExcelVO { + + @ExcelProperty("编号") + private Long id; + + @ExcelProperty("快递公司编号") + private String code; + + @ExcelProperty("快递公司名称") + private String name; + + @ExcelProperty("快递公司logo") + private String logo; + + @ExcelProperty("排序") + private Integer sort; + + @ExcelProperty("状态(0正常 1停用)") + private Byte status; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java new file mode 100644 index 000000000..cb738a6db --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 快递公司 Excel 导出 Request VO") +@Data +public class DeliveryExpressExportReqVO { + + @Schema(description = "快递公司编号") + private String code; + + @Schema(description = "快递公司名称", example = "李四") + private String name; + + @Schema(description = "状态(0正常 1停用)", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java new file mode 100644 index 000000000..5425bf42a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 快递公司分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressPageReqVO extends PageParam { + + @Schema(description = "快递公司编号") + private String code; + + @Schema(description = "快递公司名称", example = "李四") + private String name; + + @Schema(description = "状态(0正常 1停用)", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java new file mode 100644 index 000000000..55d5578ad --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 快递公司 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressRespVO extends DeliveryExpressBaseVO { + + @Schema(description = "编号", required = true, example = "6592") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java new file mode 100644 index 000000000..633736e34 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 快递公司更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressUpdateReqVO extends DeliveryExpressBaseVO { + + @Schema(description = "编号", required = true, example = "6592") + @NotNull(message = "编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java new file mode 100644 index 000000000..768530ace --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.trade.convert.delivery; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExcelVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + + +/** + * 快递公司 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface DeliveryExpressConvert { + + DeliveryExpressConvert INSTANCE = Mappers.getMapper(DeliveryExpressConvert.class); + + DeliveryExpressDO convert(DeliveryExpressCreateReqVO bean); + + DeliveryExpressDO convert(DeliveryExpressUpdateReqVO bean); + + DeliveryExpressRespVO convert(DeliveryExpressDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java index 425ad9b06..265066d83 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** - * 配送快递公司 DO + * 快递公司 DO * * @author jason */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java index d2346f21f..24b0b50e6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java @@ -1,12 +1,41 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface DeliveryExpressMapper extends BaseMapperX { + default PageResult selectPage(DeliveryExpressPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(DeliveryExpressDO::getCode, reqVO.getCode()) + .likeIfPresent(DeliveryExpressDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryExpressDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(DeliveryExpressDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(DeliveryExpressDO::getSort)); + } + + default List selectList(DeliveryExpressExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(DeliveryExpressDO::getCode, reqVO.getCode()) + .likeIfPresent(DeliveryExpressDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryExpressDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(DeliveryExpressDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(DeliveryExpressDO::getSort)); + } + + default DeliveryExpressDO selectByCode(String code) { + return selectOne(new LambdaQueryWrapper() + .eq(DeliveryExpressDO::getCode, code)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java new file mode 100644 index 000000000..ce4814dbd --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import java.util.*; +import javax.validation.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; + +/** + * 快递公司 Service 接口 + * + * @author jason + */ +public interface DeliveryExpressService { + + /** + * 创建快递公司 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDeliveryExpress(@Valid DeliveryExpressCreateReqVO createReqVO); + + /** + * 更新快递公司 + * + * @param updateReqVO 更新信息 + */ + void updateDeliveryExpress(@Valid DeliveryExpressUpdateReqVO updateReqVO); + + /** + * 删除快递公司 + * + * @param id 编号 + */ + void deleteDeliveryExpress(Long id); + + /** + * 获得快递公司 + * + * @param id 编号 + * @return 快递公司 + */ + DeliveryExpressDO getDeliveryExpress(Long id); + + /** + * 获得快递公司列表 + * + * @param ids 编号 + * @return 快递公司列表 + */ + List getDeliveryExpressList(Collection ids); + + /** + * 获得快递公司分页 + * + * @param pageReqVO 分页查询 + * @return 快递公司分页 + */ + PageResult getDeliveryExpressPage(DeliveryExpressPageReqVO pageReqVO); + + /** + * 获得快递公司列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 快递公司列表 + */ + List getDeliveryExpressList(DeliveryExpressExportReqVO exportReqVO); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java new file mode 100644 index 000000000..dcbf08969 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; + + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; + +/** + * 快递公司 Service 实现类 + * + * @author jason + */ +@Service +@Validated +public class DeliveryExpressServiceImpl implements DeliveryExpressService { + + @Resource + private DeliveryExpressMapper deliveryExpressMapper; + + @Override + public Long createDeliveryExpress(DeliveryExpressCreateReqVO createReqVO) { + //校验编码是否唯一 + validateExpressCodeUnique(createReqVO.getCode(), null); + // 插入 + DeliveryExpressDO deliveryExpress = DeliveryExpressConvert.INSTANCE.convert(createReqVO); + deliveryExpressMapper.insert(deliveryExpress); + // 返回 + return deliveryExpress.getId(); + } + + @Override + public void updateDeliveryExpress(DeliveryExpressUpdateReqVO updateReqVO) { + // 校验存在 + validateDeliveryExpressExists(updateReqVO.getId()); + //校验编码是否唯一 + validateExpressCodeUnique(updateReqVO.getCode(), updateReqVO.getId()); + // 更新 + DeliveryExpressDO updateObj = DeliveryExpressConvert.INSTANCE.convert(updateReqVO); + deliveryExpressMapper.updateById(updateObj); + } + + @Override + public void deleteDeliveryExpress(Long id) { + // 校验存在 + validateDeliveryExpressExists(id); + // 删除 + deliveryExpressMapper.deleteById(id); + } + + private void validateExpressCodeUnique(String code, Long id) { + DeliveryExpressDO express = deliveryExpressMapper.selectByCode(code); + if (express == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的快递公司 + if (id == null) { + throw exception(EXPRESS_CODE_DUPLICATE); + } + if (!express.getId().equals(id)) { + throw exception(EXPRESS_CODE_DUPLICATE); + } + } + private void validateDeliveryExpressExists(Long id) { + if (deliveryExpressMapper.selectById(id) == null) { + throw exception(DELIVERY_EXPRESS_NOT_EXISTS); + } + } + + @Override + public DeliveryExpressDO getDeliveryExpress(Long id) { + return deliveryExpressMapper.selectById(id); + } + + @Override + public List getDeliveryExpressList(Collection ids) { + return deliveryExpressMapper.selectBatchIds(ids); + } + + @Override + public PageResult getDeliveryExpressPage(DeliveryExpressPageReqVO pageReqVO) { + return deliveryExpressMapper.selectPage(pageReqVO); + } + + @Override + public List getDeliveryExpressList(DeliveryExpressExportReqVO exportReqVO) { + return deliveryExpressMapper.selectList(exportReqVO); + } + +} From fbeaa061009c56c36461ab7e5913c01d1ea428bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=94=E5=AE=B6=E8=BE=89?= Date: Fri, 19 May 2023 10:47:23 +0800 Subject: [PATCH 047/232] =?UTF-8?q?bugfix:=20=E8=A7=A3=E5=86=B3=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E6=A8=A1=E5=9D=97=E9=94=99=E8=AF=AF=E7=A0=81=E5=8C=BA?= =?UTF-8?q?=E9=97=B4=E5=86=B2=E7=AA=81=E3=80=81=E9=83=A8=E5=88=86=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=A0=81=E9=87=8D=E5=A4=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/ServiceErrorCodeRange.java | 4 + .../module/bpm/enums/ErrorCodeConstants.java | 22 ++--- .../promotion/enums/ErrorCodeConstants.java | 82 +++++++++---------- .../trade/enums/ErrorCodeConstants.java | 12 +-- .../module/mp/enums/ErrorCodeConstants.java | 12 +-- .../module/pay/enums/ErrorCodeConstants.java | 45 ++++------ .../report/enums/ErrorCodeConstants.java | 2 +- .../system/enums/ErrorCodeConstants.java | 4 +- 8 files changed, 89 insertions(+), 94 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java index c3e504a7c..be22815eb 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/ServiceErrorCodeRange.java @@ -33,7 +33,11 @@ public class ServiceErrorCodeRange { // 模块 system 错误码区间 [1-002-000-000 ~ 1-003-000-000) // 模块 report 错误码区间 [1-003-000-000 ~ 1-004-000-000) // 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000) + // 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-000-000) // 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000) + // 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000) // 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000) + // 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000) + // 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000) } diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 9451f6d49..760985804 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -3,16 +3,16 @@ package cn.iocoder.yudao.module.bpm.enums; import cn.iocoder.yudao.framework.common.exception.ErrorCode; /** - * 工作流 错误码枚举类 + * Bpm 错误码枚举类 * - * 工作流系统,使用 1-009-000-000 段 + * bpm 系统,使用 1-009-000-000 段 */ public interface ErrorCodeConstants { - // ========== 通用流程处理 模块 1-009-000-000 ========== + // ========== 通用流程处理 模块 1009000000 ========== ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常"); - // ========== OA 流程模块 1-009-001-000 ========== + // ========== OA 流程模块 1009001000 ========== ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在"); ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置"); ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在"); @@ -21,7 +21,7 @@ public interface ErrorCodeConstants { ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置"); ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1"); - // ========== 流程模型 1-009-002-000 ========== + // ========== 流程模型 1009002000 ========== ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程"); ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在"); ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"); @@ -30,34 +30,34 @@ public interface ErrorCodeConstants { "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置"); ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化"); - // ========== 流程定义 1-009-003-000 ========== + // ========== 流程定义 1009003000 ========== ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图"); ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在"); ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003003, "流程定义处于挂起状态"); ErrorCode PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS = new ErrorCode(1009003004, "流程定义的模型不存在"); - // ========== 流程实例 1-009-004-000 ========== + // ========== 流程实例 1009004000 ========== ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在"); ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中"); ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的"); - // ========== 流程任务 1-009-005-000 ========== + // ========== 流程任务 1009005000 ========== ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009005000, "审批任务失败,原因:该任务不处于未审批"); ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009005001, "审批任务失败,原因:该任务的审批人不是你"); - // ========== 流程任务分配规则 1-009-006-000 ========== + // ========== 流程任务分配规则 1009006000 ========== ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则"); ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在"); ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改"); ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!"); ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在"); - // ========== 动态表单模块 1-009-010-000 ========== + // ========== 动态表单模块 1009010000 ========== ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在"); ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010001, "表单项({}) 和 ({}) 使用了相同的字段名({})"); - // ========== 用户组模块 1-009-011-000 ========== + // ========== 用户组模块 1009011000 ========== ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在"); ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用"); diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 47ce28b4b..308966c22 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -3,58 +3,58 @@ package cn.iocoder.yudao.module.promotion.enums; import cn.iocoder.yudao.framework.common.exception.ErrorCode; /** - * promotion 错误码枚举类 + * Promotion 错误码枚举类 * - * market 系统,使用 1-003-000-000 段 + * promotion 系统,使用 1-013-000-000 段 */ public interface ErrorCodeConstants { - // ========== 促销活动相关 1003001000 ============ - ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "限时折扣活动不存在"); - ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它限时折扣活动"); - ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "限时折扣活动已关闭,不能修改"); - ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "限时折扣活动未关闭,不能删除"); - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "限时折扣活动已关闭,不能重复关闭"); - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "限时折扣活动已结束,不能关闭"); + // ========== 促销活动相关 1013001000 ============ + ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1013001000, "限时折扣活动不存在"); + ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013001001, "存在商品参加了其它限时折扣活动"); + ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013001002, "限时折扣活动已关闭,不能修改"); + ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1013001003, "限时折扣活动未关闭,不能删除"); + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013001004, "限时折扣活动已关闭,不能重复关闭"); + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013001005, "限时折扣活动已结束,不能关闭"); - // ========== Banner 相关 1003002000 ============ - ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); + // ========== Banner 相关 1013002000 ============ + ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1013002000, "Banner 不存在"); - // ========== Coupon 相关 1003003000 ============ - ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); - ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "所结算的商品中未满足使用的金额"); + // ========== Coupon 相关 1013003000 ============ + ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1013003000, "优惠劵没有可使用的商品!"); + ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1013003001, "所结算的商品中未满足使用的金额"); - // ========== 优惠劵模板 1003004000 ========== - ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在"); - ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})"); + // ========== 优惠劵模板 1013004000 ========== + ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1013004000, "优惠劵模板不存在"); + ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1013004001, "发放数量不能小于已领取数量({})"); - // ========== 优惠劵模板 1003005000 ========== - ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠券不存在"); - ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用"); - ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态"); - ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1006003004, "优惠券不在使用时间范围内"); + // ========== 优惠劵模板 1013005000 ========== + ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1013005000, "优惠券不存在"); + ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1013005001, "回收优惠劵失败,优惠劵已被使用"); + ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1013005002, "优惠劵不处于待使用状态"); + ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1013005003, "优惠券不在使用时间范围内"); - // ========== 满减送活动 1003006000 ========== - ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在"); - ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它满减送活动"); - ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "满减送活动已关闭,不能修改"); - ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "满减送活动未关闭,不能删除"); - ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "满减送活动已关闭,不能重复关闭"); - ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "满减送活动已结束,不能关闭"); + // ========== 满减送活动 1013006000 ========== + ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1013006000, "满减送活动不存在"); + ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013006001, "存在商品参加了其它满减送活动"); + ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013006002, "满减送活动已关闭,不能修改"); + ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1013006003, "满减送活动未关闭,不能删除"); + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013006004, "满减送活动已关闭,不能重复关闭"); + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013006005, "满减送活动已结束,不能关闭"); - // ========== Price 相关 1003007000 ============ - ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0"); + // ========== Price 相关 1013007000 ============ + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1013007000, "支付价格计算异常,原因:价格小于等于 0"); - // ========== 秒杀活动 1003008000 ========== - ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); - ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008002, "存在商品参加了其它秒杀活动"); - ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003008003, "秒杀活动已关闭,不能修改"); - ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1003008004, "秒杀活动未关闭或未结束,不能删除"); - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003008005, "秒杀活动已关闭,不能重复关闭"); - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003008006, "秒杀活动已结束,不能关闭"); + // ========== 秒杀活动 1013008000 ========== + ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在"); + ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013008002, "存在商品参加了其它秒杀活动"); + ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改"); + ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013008006, "秒杀活动已结束,不能关闭"); - // ========== 秒杀时段 1003009000 ========== - ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003009000, "秒杀时段不存在"); - ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1003009001, "秒杀时段冲突"); + // ========== 秒杀时段 1013009000 ========== + ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); + ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1013009001, "秒杀时段冲突"); } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index f6d06340b..1d4aa8e78 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -3,15 +3,15 @@ package cn.iocoder.yudao.module.trade.enums; import cn.iocoder.yudao.framework.common.exception.ErrorCode; /** - * 交易 错误码枚举类 - * 交易系统,使用 1-011-000-000 段 + * Trade 错误码枚举类 + * trade 系统,使用 1-011-000-000 段 * * @author LeeYan9 * @since 2022-08-26 */ public interface ErrorCodeConstants { - // ========== Order 模块 1-011-000-000 ========== + // ========== Order 模块 1011000000 ========== ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); @@ -28,7 +28,7 @@ public interface ErrorCodeConstants { ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态"); ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态"); - // ========== After Sale 模块 1-011-000-000 ========== + // ========== After Sale 模块 1011000100 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1011000101, "申请退款金额错误"); ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1011000102, "订单已关闭,无法申请售后"); @@ -42,10 +42,10 @@ public interface ErrorCodeConstants { ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】"); ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】"); - // ========== Cart 模块 1-011-002-000 ========== + // ========== Cart 模块 1011002000 ========== ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); - // ========== 物流配送模块 1-011-003-000 ========== + // ========== 物流配送模块 1011003000 ========== ErrorCode DELIVERY_EXPRESS_NOT_EXISTS = new ErrorCode(1011003000, "快递公司不存在"); ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); diff --git a/yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java b/yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java index d612a3453..262306e34 100644 --- a/yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java +++ b/yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java @@ -12,7 +12,7 @@ public interface ErrorCodeConstants { // ========== 公众号账号 1006000000============ ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1006000000, "公众号账号不存在"); ErrorCode ACCOUNT_GENERATE_QR_CODE_FAIL = new ErrorCode(1006000001, "生成公众号二维码失败,原因:{}"); - ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}"); + ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000002, "清空公众号的 API 配额失败,原因:{}"); // ========== 公众号统计 1006001000============ ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1006001000, "获取粉丝增减数据失败,原因:{}"); @@ -23,9 +23,9 @@ public interface ErrorCodeConstants { // ========== 公众号标签 1006002000============ ErrorCode TAG_NOT_EXISTS = new ErrorCode(1006002000, "标签不存在"); ErrorCode TAG_CREATE_FAIL = new ErrorCode(1006002001, "创建标签失败,原因:{}"); - ErrorCode TAG_UPDATE_FAIL = new ErrorCode(1006002001, "更新标签失败,原因:{}"); - ErrorCode TAG_DELETE_FAIL = new ErrorCode(1006002001, "删除标签失败,原因:{}"); - ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}"); + ErrorCode TAG_UPDATE_FAIL = new ErrorCode(1006002002, "更新标签失败,原因:{}"); + ErrorCode TAG_DELETE_FAIL = new ErrorCode(1006002003, "删除标签失败,原因:{}"); + ErrorCode TAG_GET_FAIL = new ErrorCode(1006002004, "获得标签失败,原因:{}"); // ========== 公众号粉丝 1006003000============ ErrorCode USER_NOT_EXISTS = new ErrorCode(1006003000, "粉丝不存在"); @@ -43,13 +43,13 @@ public interface ErrorCodeConstants { // ========== 公众号发布能力 1006006000============ ErrorCode FREE_PUBLISH_LIST_FAIL = new ErrorCode(1006006000, "获得已成功发布列表失败,原因:{}"); ErrorCode FREE_PUBLISH_SUBMIT_FAIL = new ErrorCode(1006006001, "提交发布失败,原因:{}"); - ErrorCode FREE_PUBLISH_DELETE_FAIL = new ErrorCode(1006006001, "删除发布失败,原因:{}"); + ErrorCode FREE_PUBLISH_DELETE_FAIL = new ErrorCode(1006006002, "删除发布失败,原因:{}"); // ========== 公众号草稿 1006007000============ ErrorCode DRAFT_LIST_FAIL = new ErrorCode(1006007000, "获得草稿列表失败,原因:{}"); ErrorCode DRAFT_CREATE_FAIL = new ErrorCode(1006007001, "创建草稿失败,原因:{}"); ErrorCode DRAFT_UPDATE_FAIL = new ErrorCode(1006007002, "更新草稿失败,原因:{}"); - ErrorCode DRAFT_DELETE_FAIL = new ErrorCode(1006007002, "删除草稿失败,原因:{}"); + ErrorCode DRAFT_DELETE_FAIL = new ErrorCode(1006007003, "删除草稿失败,原因:{}"); // ========== 公众号菜单 1006008000============ ErrorCode MENU_SAVE_FAIL = new ErrorCode(1006008000, "创建菜单失败,原因:{}"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 9c939aae2..4d74cdf02 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -10,16 +10,12 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; */ public interface ErrorCodeConstants { - /** - * ========== APP 模块 1-007-000-000 ========== - */ + // ========== APP 模块 1007000000 ========== ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在"); ErrorCode PAY_APP_IS_DISABLE = new ErrorCode(1007000002, "App 已经被禁用"); ErrorCode PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE = new ErrorCode(1007000003, "支付应用存在交易中的订单,无法删除"); - /** - * ========== CHANNEL 模块 1-007-001-000 ========== - */ + // ========== CHANNEL 模块 1007001000 ========== ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用"); ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在"); @@ -30,44 +26,39 @@ public interface ErrorCodeConstants { ErrorCode CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL = new ErrorCode(1007001008,"微信渠道v3版本中apiclient_cert.pem不可为空"); ErrorCode PAY_CHANNEL_NOTIFY_VERIFY_FAILED = new ErrorCode(1007001009, "渠道通知校验失败"); - // ========== ORDER 模块 1-007-002-000 ========== - + // ========== ORDER 模块 1007002000 ========== ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); ErrorCode PAY_ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); ErrorCode PAY_ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); ErrorCode PAY_ORDER_ERROR_USER = new ErrorCode(1007002003, "支付订单用户不正确"); - /** - * ========== ORDER 模块(拓展单) 1-007-003-000 ========== - */ + // ========== ORDER 模块(拓展单) 1007003000 ========== ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007003002, "支付订单不处于已支付"); - // ========== 支付模块(退款) 1-007-006-000 ========== + // ========== 支付模块(退款) 1007006000 ========== ErrorCode PAY_REFUND_AMOUNT_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); ErrorCode PAY_REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空"); ErrorCode PAY_REFUND_SUCCEED = new ErrorCode(1007006003, "已经退款成功"); ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); - /** - * ========== 支付商户信息 1-007-004-000 ========== - */ + // ========== 支付商户信息 1007004000 ========== ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在"); ErrorCode PAY_MERCHANT_EXIST_APP_CANT_DELETE = new ErrorCode(1007004001, "支付商户存在支付应用,无法删除"); - // ========== 示例订单 1-007-900-000 ========== - ErrorCode PAY_DEMO_ORDER_NOT_FOUND = new ErrorCode(100790000, "示例订单不存在"); - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(100790001, "示例订单更新支付状态失败,订单不是【未支付】状态"); - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(100790002, "示例订单更新支付状态失败,支付单编号不匹配"); - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(100790003, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态"); - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(100790004, "示例订单更新支付状态失败,支付单金额不匹配"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(100790005, "发起退款失败,示例订单未支付"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(100790006, "发起退款失败,示例订单已退款"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(100790007, "发起退款失败,退款订单不存在"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS = new ErrorCode(100790008, "发起退款失败,退款订单未退款成功"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(100790008, "发起退款失败,退款单编号不匹配"); - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(100790004, "发起退款失败,退款单金额不匹配"); + // ========== 示例订单 1007900000 ========== + ErrorCode PAY_DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); + ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007900001, "示例订单更新支付状态失败,订单不是【未支付】状态"); + ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1007900002, "示例订单更新支付状态失败,支付单编号不匹配"); + ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007900003, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态"); + ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1007900004, "示例订单更新支付状态失败,支付单金额不匹配"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(1007900005, "发起退款失败,示例订单未支付"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(1007900006, "发起退款失败,示例订单已退款"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1007900007, "发起退款失败,退款订单不存在"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS = new ErrorCode(1007900008, "发起退款失败,退款订单未退款成功"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1007900009, "发起退款失败,退款单编号不匹配"); + ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1007900010, "发起退款失败,退款单金额不匹配"); } diff --git a/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java b/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java index d90bed398..92a1bbaa9 100644 --- a/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java +++ b/yudao-module-report/yudao-module-report-api/src/main/java/cn/iocoder/yudao/module/report/enums/ErrorCodeConstants.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; /** * Report 错误码枚举类 * - * system 系统,使用 1-003-000-000 段 + * report 系统,使用 1-003-000-000 段 */ public interface ErrorCodeConstants { diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 344a13d4c..d47e25a18 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -152,7 +152,7 @@ public interface ErrorCodeConstants { // ========== 邮件发送 1002025000 ========== ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失"); - ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025000, "邮箱不存在"); + ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025001, "邮箱不存在"); // ========== 站内信模版 1002026000 ========== ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1002026000, "站内信模版不存在"); @@ -161,6 +161,6 @@ public interface ErrorCodeConstants { // ========== 站内信模版 1002027000 ========== // ========== 站内信发送 1002028000 ========== - ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失"); + ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002028000, "模板参数({})缺失"); } From 83aa656bdab848a1792589d66a09152cd15c5439 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 19 May 2023 23:55:02 +0800 Subject: [PATCH 048/232] =?UTF-8?q?mall=EF=BC=9A=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E8=AF=84=E8=AE=BA=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/order/vo/TradeOrderItemBaseVO.java | 5 +-- .../app/order/AppTradeOrderController.java | 20 ++++++++- .../order/vo/AppTradeOrderDetailRespVO.java | 19 +++++---- .../order/vo/AppTradeOrderPageItemRespVO.java | 42 +++---------------- .../app/order/vo/AppTradeOrderPageReqVO.java | 4 +- .../vo/AppTradeOrderSettlementRespVO.java | 2 +- .../vo/item/AppTradeOrderItemRespVO.java | 39 +++++++++++++++++ .../convert/order/TradeOrderConvert.java | 5 ++- .../dal/dataobject/order/TradeOrderDO.java | 18 +++++--- .../dataobject/order/TradeOrderItemDO.java | 26 +++++------- .../dal/mysql/order/TradeOrderMapper.java | 1 + .../service/order/TradeOrderServiceTest.java | 10 ++--- 12 files changed, 111 insertions(+), 80 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java index b927e5e9e..351d5a787 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java @@ -40,11 +40,8 @@ public class TradeOrderItemBaseVO { // ========== 价格 + 支付基本信息 ========== - @Schema(description = "商品原价(总)", required = true, example = "100") - private Integer originalPrice; - @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer originalUnitPrice; + private Integer price; @Schema(description = "商品优惠(总)", required = true, example = "100") private Integer discountPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 945964b16..d1a2e4733 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -53,7 +54,7 @@ public class AppTradeOrderController { AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO(); AppTradeOrderSettlementRespVO.Price price = new AppTradeOrderSettlementRespVO.Price(); - price.setOriginalPrice(1000); + price.setTotalPrice(1000); price.setDeliveryPrice(200); price.setCouponPrice(100); price.setPointPrice(50); @@ -184,4 +185,21 @@ public class AppTradeOrderController { return success(orderCount); } + // ========== 订单项 ========== + + @GetMapping("/item/get") + @Operation(summary = "获得交易订单项") + @Parameter(name = "id", description = "交易订单项编号") + public CommonResult getOrderItem(@RequestParam("id") Long id) { + TradeOrderItemDO item = tradeOrderService.getOrderItem(getLoginUserId(), id); + return success(TradeOrderConvert.INSTANCE.convert03(item)); + } + + // TODO 芋艿:待实现 + @PostMapping("/item/create-comment") + @Operation(summary = "创建交易订单项的评价") + public CommonResult createOrderItemComment() { + return success(0L); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java index 54d012fdd..6055a8dbc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java @@ -123,29 +123,30 @@ public class AppTradeOrderDetailRespVO { @Schema(description = "商品 SPU 编号", required = true, example = "1") private Long spuId; - @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") private String spuName; @Schema(description = "商品 SKU 编号", required = true, example = "1") private Long skuId; + /** + * 属性数组 + */ + private List properties; + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") private String picUrl; @Schema(description = "购买数量", required = true, example = "1") private Integer count; - @Schema(description = "商品原价(总)", required = true, example = "100") - private Integer originalPrice; + @Schema(description = "是否评价", required = true, example = "true") + private Boolean commentStatus; + + // ========== 价格 + 支付基本信息 ========== @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer originalUnitPrice; - - /** - * 属性数组 - */ - private List properties; + private Integer price; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java index 75928c946..45a87082a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -22,6 +22,9 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "购买的商品数量", required = true, example = "10") private Integer productCount; + @Schema(description = "是否评价", required = true, example = "true") + private Boolean commentStatus; + // ========== 价格 + 支付基本信息 ========== @Schema(description = "应付金额,单位:分", required = true, example = "1000") @@ -30,41 +33,6 @@ public class AppTradeOrderPageItemRespVO { /** * 订单项数组 */ - private List items; - - @Schema(description = "用户 App - 交易订单的明细的订单项目") - @Data - public static class Item { - - @Schema(description = "编号", required = true, example = "1") - private Long id; - - @Schema(description = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - - @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") - private String spuName; - - @Schema(description = "商品 SKU 编号", required = true, example = "1") - private Long skuId; - - @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") - private String picUrl; - - @Schema(description = "购买数量", required = true, example = "1") - private Integer count; - - @Schema(description = "商品原价(总)", required = true, example = "100") - private Integer originalPrice; - - @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer originalUnitPrice; - - /** - * 属性数组 - */ - private List properties; - - } + private List items; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java index 180deadbf..c1e07c176 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -// TODO 芋艿:字段优化 @Schema(description = "交易订单分页 Request VO") @Data public class AppTradeOrderPageReqVO extends PageParam { @@ -15,4 +14,7 @@ public class AppTradeOrderPageReqVO extends PageParam { @InEnum(value = TradeOrderStatusEnum.class, message = "订单状态必须是 {value}") private Integer status; + @Schema(description = "是否评价", example = "true") + private Boolean commentStatus; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java index 3e3dc9d08..b76b3733c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java @@ -61,7 +61,7 @@ public class AppTradeOrderSettlementRespVO { public static class Price { @Schema(description = "商品原价(总),单位:分", required = true, example = "500") - private Integer originalPrice; + private Integer totalPrice; @Schema(description = "运费金额,单位:分", required = true, example = "50") private Integer deliveryPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java new file mode 100644 index 000000000..f68a9c747 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo.item; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 订单交易项 Response VO") +@Data +public class AppTradeOrderItemRespVO { + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + private Long skuId; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "购买数量", required = true, example = "1") + private Integer count; + + @Schema(description = "商品原价(单)", required = true, example = "100") + private Integer price; + + /** + * 属性数组 + */ + private List properties; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index db8ea6879..3f5b3e4ed 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductProp import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; @@ -191,7 +192,7 @@ public interface TradeOrderConvert { if (CollUtil.isEmpty(properties)) { continue; } - AppTradeOrderPageItemRespVO.Item item = orderVO.getItems().get(i); + AppTradeOrderItemRespVO item = orderVO.getItems().get(i); item.setProperties(new ArrayList<>(properties.size())); // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 properties.forEach(property -> { @@ -237,4 +238,6 @@ public interface TradeOrderConvert { } AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List items); + AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 9d031a905..f2ba51090 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -94,6 +94,13 @@ public class TradeOrderDO extends BaseDO { * 商家备注 */ private String remark; + /** + * 是否评价 + * + * true - 已评价 + * false - 未评价 + */ + private Boolean commentStatus; // ========== 价格 + 支付基本信息 ========== @@ -128,16 +135,17 @@ public class TradeOrderDO extends BaseDO { /** * 商品原价(总),单位:分 * - * 基于 {@link TradeOrderItemDO#getOriginalPrice()} 求和 + * totalPrice = {@link TradeOrderItemDO#getPrice()} * {@link TradeOrderItemDO#getCount()} 求和 * * 对应 taobao 的 trade.total_fee 字段 */ - private Integer originalPrice; + private Integer totalPrice; + // TODO 芋艿:是不是要删除这个字段? /** * 订单原价(总),单位:分 * - * 基于 {@link OrderItem#getPayPrice()} 求和 - * 和 {@link #originalPrice} 的差异:去除商品级优惠 + * 1. orderPrice = {@link OrderItem#getPayPrice()} 求和 + * 2. orderPrice = {@link #totalPrice} - 商品级优惠 */ private Integer orderPrice; /** @@ -219,7 +227,7 @@ public class TradeOrderDO extends BaseDO { // ========== 售后基本信息 ========== /** - * 收货状态 + * 售后状态 * * 枚举 {@link TradeOrderAfterSaleStatusEnum} */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index 0bc403f0e..42fc106f5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -84,29 +84,23 @@ public class TradeOrderItemDO extends BaseDO { * 购买数量 */ private Integer count; -// /** -// * 是否评论 TODO -// * -// * false - 未评论 -// * true - 已评论 -// */ -// private Boolean commented; + /** + * 是否评价 + * + * true - 已评价 + * false - 未评价 + */ + private Boolean commentStatus; // ========== 价格 + 支付基本信息 ========== - /** - * 商品原价(总),单位:分 - * - * = {@link #originalUnitPrice} * {@link #getCount()} - */ - private Integer originalPrice; /** * 商品原价(单),单位:分 * * 对应 ProductSkuDO 的 price 字段 * 对应 taobao 的 order.price 字段 */ - private Integer originalUnitPrice; + private Integer price; /** * 商品优惠(总),单位:分 * @@ -116,9 +110,9 @@ public class TradeOrderItemDO extends BaseDO { */ private Integer discountPrice; /** - * 子订单实付金额,不算主订单分摊金额,单位:分 + * 子订单实付金额(总),不算主订单分摊金额,单位:分 * - * = {@link #originalPrice} + * = {@link #price} * {@link #count} * - {@link #discountPrice} * * 对应 taobao 的 order.payment 字段 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index 7be224744..e6a13eabc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -40,6 +40,7 @@ public interface TradeOrderMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .eq(TradeOrderDO::getUserId, userId) .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeOrderDO::getCommentStatus, reqVO.getCommentStatus()) .orderByDesc(TradeOrderDO::getId)); // TODO 芋艿:未来不同的 status,不同的排序 } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 55418d52b..dc7f5bf70 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -169,7 +169,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertNull(tradeOrderDO.getRemark()); assertFalse(tradeOrderDO.getPayed()); assertNull(tradeOrderDO.getPayTime()); - assertEquals(tradeOrderDO.getOriginalPrice(), 230); + assertEquals(tradeOrderDO.getTotalPrice(), 230); assertEquals(tradeOrderDO.getOrderPrice(), 100); assertEquals(tradeOrderDO.getDiscountPrice(), 0); assertEquals(tradeOrderDO.getAdjustPrice(), 0); @@ -204,8 +204,8 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { //assertEquals(tradeOrderItemDO01.getSpuName(), sku01.getSpuName()); TODO 找不到spuName assertEquals(tradeOrderItemDO01.getPicUrl(), sku01.getPicUrl()); assertEquals(tradeOrderItemDO01.getCount(), 3); - assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); - assertEquals(tradeOrderItemDO01.getOriginalUnitPrice(), 50); +// assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); + assertEquals(tradeOrderItemDO01.getPrice(), 50); assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); assertEquals(tradeOrderItemDO01.getPayPrice(), 130); assertEquals(tradeOrderItemDO01.getOrderPartPrice(), 7); @@ -224,8 +224,8 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { //assertEquals(tradeOrderItemDO02.getSpuName(), sku02.getSpuName()); TODO 找不到spuName assertEquals(tradeOrderItemDO02.getPicUrl(), sku02.getPicUrl()); assertEquals(tradeOrderItemDO02.getCount(), 4); - assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); - assertEquals(tradeOrderItemDO02.getOriginalUnitPrice(), 20); +// assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); + assertEquals(tradeOrderItemDO02.getPrice(), 20); assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); assertEquals(tradeOrderItemDO02.getPayPrice(), 40); assertEquals(tradeOrderItemDO02.getOrderPartPrice(), 15); From be7c664e07868fb2de39061f6ff54bb0d571cc17 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 May 2023 10:11:38 +0800 Subject: [PATCH 049/232] =?UTF-8?q?mall=EF=BC=9A=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/order/AppTradeOrderController.java | 19 ++++++++++--------- .../dal/mysql/order/TradeOrderMapper.java | 6 ++++++ .../service/order/TradeOrderService.java | 10 ++++++++++ .../service/order/TradeOrderServiceImpl.java | 5 +++++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index d1a2e4733..714851c69 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -171,17 +172,17 @@ public class AppTradeOrderController { return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems, propertyValueDetails)); } - // TODO 芋艿:后续实现 @GetMapping("/get-count") @Operation(summary = "获得交易订单数量") - public CommonResult> getOrderCount() { - Map orderCount = new HashMap<>(); - orderCount.put("allCount", 10); - orderCount.put("unpaidCount", 5); - orderCount.put("undeliveredCount", 2); - orderCount.put("deliveredCount", 1); - orderCount.put("uncommentedCount", 3); - orderCount.put("allPrice", 300); + public CommonResult> getOrderCount() { + Map orderCount = new HashMap<>(); + // 全部 + orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null)); + // 待付款(未支付) + orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNPAID.getStatus(), null)); + orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null)); + orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null)); + orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false)); return success(orderCount); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index e6a13eabc..265450fbd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -44,4 +44,10 @@ public interface TradeOrderMapper extends BaseMapperX { .orderByDesc(TradeOrderDO::getId)); // TODO 芋艿:未来不同的 status,不同的排序 } + default Long selectCountByUserIdAndStatus(Long userId, Integer status, Boolean commentStatus) { + return selectCount(new LambdaQueryWrapperX() + .eq(TradeOrderDO::getUserId, userId) + .eqIfPresent(TradeOrderDO::getStatus, status) + .eqIfPresent(TradeOrderDO::getCommentStatus, commentStatus)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java index 086f65edd..b8a002791 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java @@ -91,6 +91,16 @@ public interface TradeOrderService { */ PageResult getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO); + /** + * 【会员】获得交易订单数量 + * + * @param userId 用户编号 + * @param status 订单状态。如果为空,则不进行筛选 + * @param commonStatus 评价状态。如果为空,则不进行筛选 + * @return 订单数量 + */ + Long getOrderCount(Long userId, Integer status, Boolean commonStatus); + // =================== Order Item =================== /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 9ae7def15..a66c990ce 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -451,6 +451,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { return tradeOrderMapper.selectPage(reqVO, userId); } + @Override + public Long getOrderCount(Long userId, Integer status, Boolean commentStatus) { + return tradeOrderMapper.selectCountByUserIdAndStatus(userId, status, commentStatus); + } + // =================== Order Item =================== @Override From e745bb667504424801f140b7f8e4ac2c4e57e806 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 May 2023 11:22:43 +0800 Subject: [PATCH 050/232] =?UTF-8?q?mall=EF=BC=9A=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=9A=E5=A2=9E=E5=8A=A0=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E6=8E=A5=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/trade/enums/order/TradeOrderTypeEnum.java | 7 +++++-- .../controller/app/order/AppTradeOrderController.java | 3 +++ .../app/order/vo/AppTradeOrderPageItemRespVO.java | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java index c8001b490..34e47a12e 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java @@ -17,8 +17,11 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { NORMAL(0, "普通订单"), SECKILL(1, "秒杀订单"), - TEAM(2, "拼团订单"), - BARGAIN(3, "砍价订单"); + // TODO 芋艿:如下三个字段,名字需要改下,等后面表设计完成后。 + KANJIA(2, "砍价订单"), + PINTUAN(3, "拼团订单"), + YUSHOU(4, "预售订单"), + ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 714851c69..defab3c50 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -180,8 +180,11 @@ public class AppTradeOrderController { orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null)); // 待付款(未支付) orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNPAID.getStatus(), null)); + // 待发货 orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null)); + // 待收货 orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null)); + // 待评价 orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false)); return success(orderCount); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java index 45a87082a..7e87280de 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.util.Date; import java.util.List; @Schema(description = "用户 App - 订单交易的分页项 Response VO") @@ -16,6 +17,9 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "订单流水号", required = true, example = "1146347329394184195") private String no; + @Schema(description = "订单类型", required = true, example = "0") + private Integer type; + @Schema(description = "订单状态", required = true, example = "1") private Integer status; @@ -25,6 +29,9 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "是否评价", required = true, example = "true") private Boolean commentStatus; + @Schema(description = "创建时间", required = true) + private Date createTime; + // ========== 价格 + 支付基本信息 ========== @Schema(description = "应付金额,单位:分", required = true, example = "1000") From e942b52a67471b6b79f525be52b1df371dcc8b90 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 21 May 2023 12:18:52 +0800 Subject: [PATCH 051/232] =?UTF-8?q?mall=EF=BC=9A=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E8=AF=A6=E6=83=85=EF=BC=9A=E8=B0=83=E6=95=B4=E5=94=AE=E5=90=8E?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/delivery/DeliveryTypeEnum.java | 5 +- .../TradeOrderItemAfterSaleStatusEnum.java | 7 +-- ...m.java => TradeOrderRefundStatusEnum.java} | 10 ++-- .../app/order/AppTradeOrderController.java | 7 ++- .../order/vo/AppTradeOrderDetailRespVO.java | 49 +++++-------------- .../order/vo/AppTradeOrderPageItemRespVO.java | 5 ++ .../vo/item/AppTradeOrderItemRespVO.java | 23 +++++++-- .../convert/order/TradeOrderConvert.java | 5 +- .../dal/dataobject/order/TradeOrderDO.java | 13 +++-- .../service/order/TradeOrderServiceImpl.java | 8 +-- .../service/order/TradeOrderServiceTest.java | 2 +- 11 files changed, 67 insertions(+), 67 deletions(-) rename yudao-module-mall/{yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product => yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade}/enums/delivery/DeliveryTypeEnum.java (82%) rename yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/{TradeOrderAfterSaleStatusEnum.java => TradeOrderRefundStatusEnum.java} (71%) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java similarity index 82% rename from yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java rename to yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java index da322ff24..210f5c307 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.product.enums.delivery; +package cn.iocoder.yudao.module.trade.enums.delivery; import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; @@ -15,9 +15,8 @@ import java.util.Arrays; @AllArgsConstructor public enum DeliveryTypeEnum implements IntArrayValuable { - // TODO 芋艿:英文单词,需要再想下; EXPRESS(1, "快递发货"), - USER(2, "用户自提"),; + PICK_UP(2, "用户自提"),; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray(); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java index c4fc8a373..50640717e 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java @@ -17,8 +17,8 @@ import java.util.Arrays; public enum TradeOrderItemAfterSaleStatusEnum implements IntArrayValuable { NONE(0, "未售后"), - APPLY(1, "售后中"), - SUCCESS(2, "已退款"); + APPLY(10, "售后中"), + SUCCESS(20, "售后成功"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderItemAfterSaleStatusEnum::getStatus).toArray(); @@ -31,9 +31,6 @@ public enum TradeOrderItemAfterSaleStatusEnum implements IntArrayValuable { */ private final String name; - // TODO 芋艿:EXPIRED 已失效不允许申请售后 - // TODO 芋艿:PART_AFTER_SALE 部分售后 - @Override public int[] array() { return ARRAYS; diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderRefundStatusEnum.java similarity index 71% rename from yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java rename to yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderRefundStatusEnum.java index 40402b6f8..d0e4190bb 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderRefundStatusEnum.java @@ -7,19 +7,19 @@ import lombok.RequiredArgsConstructor; import java.util.Arrays; /** - * 交易订单 - 售后状态 + * 交易订单 - 退款状态 * * @author Sin */ @RequiredArgsConstructor @Getter -public enum TradeOrderAfterSaleStatusEnum implements IntArrayValuable { +public enum TradeOrderRefundStatusEnum implements IntArrayValuable { NONE(0, "未退款"), - PART(1, "部分退款"), - ALL(2, "全部退款"); + PART(10, "部分退款"), + ALL(20, "全部退款"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderAfterSaleStatusEnum::getStatus).toArray(); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderRefundStatusEnum::getStatus).toArray(); /** * 状态值 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index defab3c50..d0c224bbd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -46,6 +47,9 @@ public class AppTradeOrderController { @Resource private ProductPropertyValueApi productPropertyValueApi; + @Resource + private TradeOrderProperties tradeOrderProperties; + @GetMapping("/settlement") @Operation(summary = "获得订单结算信息") @PreAuthenticated @@ -154,7 +158,8 @@ public class AppTradeOrderController { List propertyValueDetails = productPropertyValueApi .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); // 最终组合 - return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, propertyValueDetails)); + return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, + propertyValueDetails, tradeOrderProperties)); } @GetMapping("/page") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java index 6055a8dbc..fd54444db 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -38,6 +38,9 @@ public class AppTradeOrderDetailRespVO { @Schema(description = "订单取消时间") private LocalDateTime cancelTime; + @Schema(description = "是否评价", required = true, example = "true") + private Boolean commentStatus; + // ========== 价格 + 支付基本信息 ========== @Schema(description = "是否已支付", required = true, example = "true") @@ -49,6 +52,9 @@ public class AppTradeOrderDetailRespVO { @Schema(description = "付款时间") private LocalDateTime payTime; + @Schema(description = "付款超时时间", required = true) + private LocalDateTime payExpireTime; + @Schema(description = "支付渠道", required = true, example = "wx_lite_pay") private String payChannelCode; @@ -72,6 +78,9 @@ public class AppTradeOrderDetailRespVO { // ========== 收件 + 物流基本信息 ========== + @Schema(description = "配送方式", required = true, example = "1") + private Integer deliveryType; + @Schema(description = "发货物流单号", example = "1024") private String logisticsNo; @@ -112,42 +121,6 @@ public class AppTradeOrderDetailRespVO { /** * 订单项数组 */ - private List items; - - @Schema(description = "用户 App - 交易订单的分页项的订单项目") - @Data - public static class Item { - - @Schema(description = "编号", required = true, example = "1") - private Long id; - - @Schema(description = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") - private String spuName; - - @Schema(description = "商品 SKU 编号", required = true, example = "1") - private Long skuId; - - /** - * 属性数组 - */ - private List properties; - - @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") - private String picUrl; - - @Schema(description = "购买数量", required = true, example = "1") - private Integer count; - - @Schema(description = "是否评价", required = true, example = "true") - private Boolean commentStatus; - - // ========== 价格 + 支付基本信息 ========== - - @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer price; - - } + private List items; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java index 7e87280de..969dcbb6d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -37,6 +37,11 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "应付金额,单位:分", required = true, example = "1000") private Integer payPrice; + // ========== 收件 + 物流基本信息 ========== + + @Schema(description = "配送方式", required = true, example = "1") + private Integer deliveryType; + /** * 订单项数组 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java index f68a9c747..cc673a407 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java @@ -15,25 +15,38 @@ public class AppTradeOrderItemRespVO { @Schema(description = "商品 SPU 编号", required = true, example = "1") private Long spuId; - @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") private String spuName; @Schema(description = "商品 SKU 编号", required = true, example = "1") private Long skuId; + /** + * 属性数组 + */ + private List properties; + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") private String picUrl; @Schema(description = "购买数量", required = true, example = "1") private Integer count; + @Schema(description = "是否评价", required = true, example = "true") + private Boolean commentStatus; + + // ========== 价格 + 支付基本信息 ========== + @Schema(description = "商品原价(单)", required = true, example = "100") private Integer price; - /** - * 属性数组 - */ - private List properties; + // ========== 营销基本信息 ========== + // TODO 芋艿:在捉摸一下 + + // ========== 售后基本信息 ========== + + @Schema(description = "售后状态", required = true, example = "1") + private Integer afterSaleStatus; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 3f5b3e4ed..38860943c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -212,8 +212,9 @@ public interface TradeOrderConvert { AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean); default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List orderItems, - List propertyValueDetails) { + List propertyValueDetails, TradeOrderProperties tradeOrderProperties) { AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); + orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime())); // 处理商品属性 Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); for (int i = 0; i < orderItems.size(); i++) { @@ -221,7 +222,7 @@ public interface TradeOrderConvert { if (CollUtil.isEmpty(properties)) { continue; } - AppTradeOrderDetailRespVO.Item item = orderVO.getItems().get(i); + AppTradeOrderItemRespVO item = orderVO.getItems().get(i); item.setProperties(new ArrayList<>(properties.size())); // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 properties.forEach(property -> { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index f2ba51090..0faa67db3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -3,8 +3,9 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderDeliveryStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; @@ -179,6 +180,12 @@ public class TradeOrderDO extends BaseDO { private Integer payPrice; // ========== 收件 + 物流基本信息 ========== + /** + * 配送方式 + * + * 枚举 {@link DeliveryTypeEnum} + */ + private Integer deliveryType; /** * 配置模板的编号 * @@ -229,9 +236,9 @@ public class TradeOrderDO extends BaseDO { /** * 售后状态 * - * 枚举 {@link TradeOrderAfterSaleStatusEnum} + * 枚举 {@link TradeOrderRefundStatusEnum} */ - private Integer afterSaleStatus; + private Integer refundStatus; /** * 退款金额,单位:分 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index a66c990ce..45e5e490b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -178,12 +178,12 @@ public class TradeOrderServiceImpl implements TradeOrderService { tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; tradeOrderDO.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType()); - tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()); + tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum)); tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? tradeOrderDO.setAdjustPrice(0).setPayed(false); // 支付信息 tradeOrderDO.setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); // 物流信息 - tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 + tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 tradeOrderMapper.insert(tradeOrderDO); return tradeOrderDO; } @@ -491,7 +491,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { Integer orderRefundPrice = order.getRefundPrice() + refundPrice; if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice) + .setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice) .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now())); // TODO 芋艿:记录订单日志 @@ -499,7 +499,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { // TODO 芋艿:站内信? } else { // 如果部分售后,则更新退款金额 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); + .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); } // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index dc7f5bf70..0b4c3de2d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -185,7 +185,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); - assertEquals(tradeOrderDO.getAfterSaleStatus(), TradeOrderAfterSaleStatusEnum.NONE.getStatus()); + assertEquals(tradeOrderDO.getRefundStatus(), TradeOrderRefundStatusEnum.NONE.getStatus()); assertEquals(tradeOrderDO.getRefundPrice(), 0); assertEquals(tradeOrderDO.getCouponPrice(), 30); assertEquals(tradeOrderDO.getPointPrice(), 10); From 01a67289a96fafb076b0e84d97b11df77cca8c28 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 21 May 2023 23:35:07 +0800 Subject: [PATCH 052/232] =?UTF-8?q?mall:=20=E8=AE=A2=E5=8D=95=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E6=96=B0=E5=A2=9E=E8=BF=90=E8=B4=B9=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 16 +- .../trade/enums/ErrorCodeConstants.java | 3 +- .../delivery/DeliveryExpressController.java | 2 +- .../DeliveryExpressTemplateController.java | 100 +++++++++ .../vo/DeliveryExpressTemplateBaseVO.java | 27 +++ .../DeliveryExpressTemplateCreateReqVO.java | 23 ++ .../vo/DeliveryExpressTemplateExcelVO.java | 31 +++ .../DeliveryExpressTemplateExportReqVO.java | 26 +++ .../vo/DeliveryExpressTemplatePageReqVO.java | 28 +++ .../vo/DeliveryExpressTemplateRespVO.java | 28 +++ .../DeliveryExpressTemplateSimpleRespVO.java | 19 ++ .../DeliveryExpressTemplateUpdateReqVO.java | 27 +++ .../vo/ExpressTemplateChargeBaseVO.java | 35 +++ .../vo/ExpressTemplateChargeUpdateVO.java | 20 ++ .../vo/ExpressTemplateFreeBaseVO.java | 27 +++ .../vo/ExpressTemplateFreeUpdateVO.java | 19 ++ .../DeliveryExpressTemplateConvert.java | 83 +++++++ .../DeliveryExpressTemplateFreeDO.java | 2 +- .../DeliveryExpressTemplateChargeMapper.java | 19 ++ .../DeliveryExpressTemplateFreeMapper.java | 20 ++ .../DeliveryExpressTemplateMapper.java | 29 +++ .../DeliveryExpressTemplateService.java | 70 ++++++ .../DeliveryExpressTemplateServiceImpl.java | 212 ++++++++++++++++++ .../controller/admin/ip/AreaController.java | 9 +- 24 files changed, 867 insertions(+), 8 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index cb760665e..b7751befb 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -487,6 +487,12 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `s INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2178, '快递运费模板导出', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2177, '快递运费模板删除', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2176, '快递运费模板更新', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2175, '快递运费模板创建', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2174, '快递运费模板查询', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, '运费模版', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', '', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-05-20 06:48:29', b'0'); INSERT INTO `system_dict_data`(`sort`,`label`,`value`,`dict_type`,`status`,`color_type`,`css_class`,`remark`,`creator`,`create_time`,`updater`,`update_time`,`deleted`) VALUES (1,'打',2,'product_unit',0,'','','',1, NOW(),1, NOW(),0), @@ -520,4 +526,12 @@ INSERT INTO `system_dict_data`(`sort`,`label`,`value`,`dict_type`,`status`,`colo (1, '英寸', 30, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), (1, '英尺', 31, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), (1, '码', 32, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1,'个',1,'product_unit',0,'','','',1, NOW(),1, NOW(),0); \ No newline at end of file + (1,'个',1,'product_unit',0,'','','',1, NOW(),1, NOW(),0); +-- ---------------------------- +-- 数字字典,快递计费方式 +-- ---------------------------- +INSERT INTO `ruoyi-vue-pro`.`system_dict_type`(`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (169, '快递计费方式', 'trade_delivery_express_charge_mode', 0, '用于商城交易模块配送管理', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00'); + +INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1237, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0'); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index f6d06340b..1d7a2af01 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -48,5 +48,6 @@ public interface ErrorCodeConstants { // ========== 物流配送模块 1-011-003-000 ========== ErrorCode DELIVERY_EXPRESS_NOT_EXISTS = new ErrorCode(1011003000, "快递公司不存在"); ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); - + ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); + ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index 58076226f..98515935b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -71,7 +71,7 @@ public class DeliveryExpressController { @GetMapping("/page") @Operation(summary = "获得快递公司分页") - @PreAuthorize("@ss.hasPermission('trade:delivery-express:query')") + @PreAuthorize("@ss.hasPermission('trade:delivery:express:query')") public CommonResult> getDeliveryExpressPage(@Valid DeliveryExpressPageReqVO pageVO) { PageResult pageResult = deliveryExpressService.getDeliveryExpressPage(pageVO); return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java new file mode 100644 index 000000000..9ea4c4d1b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -0,0 +1,100 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery; + +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + + +@Tag(name = "管理后台 - 快递运费模板") +@RestController +@RequestMapping("/trade/delivery/express-template") +@Validated +public class DeliveryExpressTemplateController { + + @Resource + private DeliveryExpressTemplateService deliveryExpressTemplateService; + + @PostMapping("/create") + @Operation(summary = "创建快递运费模板") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:create')") + public CommonResult createDeliveryExpressTemplate(@Valid @RequestBody DeliveryExpressTemplateCreateReqVO createReqVO) { + return success(deliveryExpressTemplateService.createDeliveryExpressTemplate(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新快递运费模板") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:update')") + public CommonResult updateDeliveryExpressTemplate(@Valid @RequestBody DeliveryExpressTemplateUpdateReqVO updateReqVO) { + deliveryExpressTemplateService.updateDeliveryExpressTemplate(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除快递运费模板") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:delete')") + public CommonResult deleteDeliveryExpressTemplate(@RequestParam("id") Long id) { + deliveryExpressTemplateService.deleteDeliveryExpressTemplate(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得快递运费模板") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") + public CommonResult getDeliveryExpressTemplate(@RequestParam("id") Long id) { + return success(deliveryExpressTemplateService.getDeliveryExpressTemplate(id)); + } + + @GetMapping("/list") + @Operation(summary = "获得快递运费模板列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") + public CommonResult> getDeliveryExpressTemplateList(@RequestParam("ids") Collection ids) { + List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(ids); + return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得快递运费模板分页") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") + public CommonResult> getDeliveryExpressTemplatePage(@Valid DeliveryExpressTemplatePageReqVO pageVO) { + PageResult pageResult = deliveryExpressTemplateService.getDeliveryExpressTemplatePage(pageVO); + return success(DeliveryExpressTemplateConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出快递运费模板 Excel") + @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:export')") + @OperateLog(type = EXPORT) + public void exportDeliveryExpressTemplateExcel(@Valid DeliveryExpressTemplateExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(exportReqVO); + // 导出 Excel + List datas = DeliveryExpressTemplateConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "快递运费模板.xls", "数据", DeliveryExpressTemplateExcelVO.class, datas); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java new file mode 100644 index 000000000..cedb70888 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** +* 快递运费模板 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class DeliveryExpressTemplateBaseVO { + + @Schema(description = "模板名称", required = true, example = "王五") + @NotNull(message = "模板名称不能为空") + private String name; + + @Schema(description = "配送计费方式 1:按件 2:按重量 3:按体积", required = true) + @NotNull(message = "配送计费方式 1:按件 2:按重量 3:按体积不能为空") + private Integer chargeMode; + + @Schema(description = "排序", required = true) + @NotNull(message = "排序不能为空") + private Integer sort; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java new file mode 100644 index 000000000..e575f1a91 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; + +@Schema(description = "管理后台 - 快递运费模板创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplateCreateReqVO extends DeliveryExpressTemplateBaseVO { + + @Schema(description = "区域运费列表") + @Valid + private List templateCharge = Collections.emptyList(); + + @Schema(description = "包邮区域列表") + @Valid + private List templateFree = Collections.emptyList(); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java new file mode 100644 index 000000000..60ae499f0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 快递运费模板 Excel VO + * + * @author jason + */ +@Data +public class DeliveryExpressTemplateExcelVO { + + @ExcelProperty("编号,自增") + private Long id; + + @ExcelProperty("模板名称") + private String name; + + @ExcelProperty("配送计费方式 1:按件 2:按重量 3:按体积") + private Integer chargeMode; + + @ExcelProperty("排序") + private Integer sort; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java new file mode 100644 index 000000000..c02133165 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import java.time.LocalDateTime; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 快递运费模板 Excel 导出 Request VO,参数和 DeliveryExpressTemplatePageReqVO 是一致的") +@Data +public class DeliveryExpressTemplateExportReqVO { + + @Schema(description = "模板名称", example = "王五") + private String name; + + @Schema(description = "配送计费方式 1:按件 2:按重量 3:按体积") + private Integer chargeMode; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java new file mode 100644 index 000000000..c5fa5a6ca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 快递运费模板分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplatePageReqVO extends PageParam { + + @Schema(description = "模板名称", example = "王五") + private String name; + + @Schema(description = "配送计费方式 1:按件 2:按重量 3:按体积") + private Integer chargeMode; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java new file mode 100644 index 000000000..5e968f629 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +/** + * @author jason + */ +@Schema(description = "管理后台 - 快递运费模板 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplateRespVO extends DeliveryExpressTemplateBaseVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "371") + private Long id; + + @Schema(description = "运费模板运费设置", requiredMode = Schema.RequiredMode.REQUIRED) + private List templateCharge; + + @Schema(description = "运费模板包邮区域", requiredMode = Schema.RequiredMode.REQUIRED) + private List templateFree; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java new file mode 100644 index 000000000..4cfc530ab --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 快递运费模板 精简 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplateSimpleRespVO extends DeliveryExpressTemplateBaseVO { + + @Schema(description = "编号,自增", required = true, example = "371") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java new file mode 100644 index 000000000..80ebee8b6 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.Valid; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 快递运费模板更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplateUpdateReqVO extends DeliveryExpressTemplateBaseVO { + + @Schema(description = "编号", required = true, example = "371") + @NotNull(message = "编号不能为空") + private Long id; + + @Schema(description = "区域运费列表") + @Valid + private List templateCharge = Collections.emptyList(); + + @Schema(description = "包邮区域列表") + @Valid + private List templateFree = Collections.emptyList(); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java new file mode 100644 index 000000000..5da76845e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 快递运费模板运费设置 Base VO,提供给添加运费模板使用 + * + * @author jason + */ +@Data +public class ExpressTemplateChargeBaseVO { + + @Schema(description = "区域编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "区域编号不能为空") + private Integer areaId; + + @Schema(description = "首件数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + @NotNull(message = "首件数量不能为空") + private Double startCount; + + @Schema(description = "起步价", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") + @NotNull(message = "起步价不能为空") + private Integer startPrice; + + @Schema(description = "续件数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @NotNull(message = "续件数量不能为空") + private Double extraCount; + + @Schema(description = "额外价", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") + @NotNull(message = "额外价不能为空") + private Integer extraPrice; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java new file mode 100644 index 000000000..a0fb2315c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author jason + */ +@Data +public class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO { + + @Schema(description = "编号", example = "6592") + private Long id; + + @Schema(description = "配送模板编号", example = "1") + private Long templateId; + + @Schema(description = "配送计费方式", example = "1") + private Integer chargeMode; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java new file mode 100644 index 000000000..ff6dbbcaa --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 快递运费模板包邮 Base VO,提供给添加运费模板使用 + * + * @author jason + */ +@Data +public class ExpressTemplateFreeBaseVO { + + @Schema(description = "区域编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "区域编号不能为空") + private Integer areaId; + + @Schema(description = "包邮金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "5000") + @NotNull(message = "包邮金额不能为空") + private Integer freePrice; + + @Schema(description = "包邮件数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + @NotNull(message = "包邮件数不能为空") + private Integer freeCount; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java new file mode 100644 index 000000000..56485b579 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 快递运费模板包邮 更新 VO + * + * @author jason + */ +@Data +public class ExpressTemplateFreeUpdateVO extends ExpressTemplateFreeBaseVO { + + @Schema(description = "编号", example = "6592") + private Long id; + + @Schema(description = "配送模板编号", example = "1") + private Long templateId; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java new file mode 100644 index 000000000..dbbb7ba83 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.trade.convert.delivery; + +import java.util.*; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 快递运费模板 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface DeliveryExpressTemplateConvert { + + DeliveryExpressTemplateConvert INSTANCE = Mappers.getMapper(DeliveryExpressTemplateConvert.class); + + DeliveryExpressTemplateDO convert(DeliveryExpressTemplateCreateReqVO bean); + + DeliveryExpressTemplateDO convert(DeliveryExpressTemplateUpdateReqVO bean); + + DeliveryExpressTemplateSimpleRespVO convert(DeliveryExpressTemplateDO bean); + + DeliveryExpressTemplateRespVO convert2(DeliveryExpressTemplateDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + + DeliveryExpressTemplateChargeDO convertTemplateCharge(Long templateId, Integer chargeMode, ExpressTemplateChargeBaseVO vo); + + DeliveryExpressTemplateChargeDO convertTemplateCharge(ExpressTemplateChargeUpdateVO vo); + + DeliveryExpressTemplateFreeDO convertTemplateFree(Long templateId, ExpressTemplateFreeBaseVO vo); + + DeliveryExpressTemplateFreeDO convertTemplateFree(ExpressTemplateFreeUpdateVO vo); + + List convertTemplateChargeList(List list); + + List convertTemplateFreeList(List list); + + default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list){ + if(CollUtil.isEmpty(list)){ + return Collections.emptyList(); + } + List templateChargeList = new ArrayList<>( list.size() ); + for (ExpressTemplateChargeBaseVO item : list) { + templateChargeList.add(convertTemplateCharge(templateId, chargeMode, item)); + } + return templateChargeList; + } + + + + default List convertTemplateFreeList(Long templateId, List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + List templateFreeList = new ArrayList<>(list.size()); + for (ExpressTemplateFreeBaseVO item : list) { + templateFreeList.add(convertTemplateFree(templateId, item)); + } + return templateFreeList; + } + + default DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean, + List chargeList, + List freeList){ + DeliveryExpressTemplateRespVO respVO = convert2(bean); + respVO.setTemplateCharge(convertTemplateChargeList(chargeList)); + respVO.setTemplateFree(convertTemplateFreeList(freeList)); + return respVO; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java index ffc59a615..351a1dd24 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java @@ -17,7 +17,7 @@ import lombok.Data; public class DeliveryExpressTemplateFreeDO extends BaseDO { /** - * 编号,自增 + * 编号 */ @TableId private Long id; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java index c8f36d542..ed0314018 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -2,12 +2,31 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +import java.util.List; @Mapper public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX { + @Repository + class BatchInsertMapper extends ServiceImpl { + } + + default List selectListByTemplateId(Long templateId){ + return selectList(new LambdaQueryWrapper() + .eq(DeliveryExpressTemplateChargeDO::getTemplateId, templateId)); + } + + default int deleteByTemplateId(Long templateId){ + return delete(new LambdaQueryWrapper() + .eq(DeliveryExpressTemplateChargeDO::getTemplateId, templateId)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java index 2e8c47379..97a4d31d3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -1,12 +1,32 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +import java.util.List; @Mapper public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX { + @Repository + class BatchInsertMapper extends ServiceImpl { + } + + default List selectListByTemplateId(Long templateId) { + return selectList(new LambdaQueryWrapper() + .eq(DeliveryExpressTemplateFreeDO::getTemplateId, templateId)); + } + + default int deleteByTemplateId(Long templateId) { + return delete(new LambdaQueryWrapper() + .eq(DeliveryExpressTemplateFreeDO::getTemplateId, templateId)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java index fa356b51e..4f7460350 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java @@ -1,11 +1,40 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplateExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplatePageReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface DeliveryExpressTemplateMapper extends BaseMapperX { + + default PageResult selectPage(DeliveryExpressTemplatePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(DeliveryExpressTemplateDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryExpressTemplateDO::getChargeMode, reqVO.getChargeMode()) + .betweenIfPresent(DeliveryExpressTemplateDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(DeliveryExpressTemplateDO::getSort)); + } + + default List selectList(DeliveryExpressTemplateExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(DeliveryExpressTemplateDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryExpressTemplateDO::getChargeMode, reqVO.getChargeMode()) + .betweenIfPresent(DeliveryExpressTemplateDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(DeliveryExpressTemplateDO::getSort)); + } + + default DeliveryExpressTemplateDO selectByName(String name) { + return selectOne(new LambdaQueryWrapper() + .eq(DeliveryExpressTemplateDO::getName, name)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java new file mode 100644 index 000000000..30cb85b75 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; + +/** + * 快递运费模板 Service 接口 + * + * @author jason + */ +public interface DeliveryExpressTemplateService { + + /** + * 创建快递运费模板 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDeliveryExpressTemplate(@Valid DeliveryExpressTemplateCreateReqVO createReqVO); + + /** + * 更新快递运费模板 + * + * @param updateReqVO 更新信息 + */ + void updateDeliveryExpressTemplate(@Valid DeliveryExpressTemplateUpdateReqVO updateReqVO); + + /** + * 删除快递运费模板 + * + * @param id 编号 + */ + void deleteDeliveryExpressTemplate(Long id); + + /** + * 获得快递运费模板 + * + * @param id 编号 + * @return 快递运费模板详情 + */ + DeliveryExpressTemplateRespVO getDeliveryExpressTemplate(Long id); + + /** + * 获得快递运费模板列表 + * + * @param ids 编号 + * @return 快递运费模板列表 + */ + List getDeliveryExpressTemplateList(Collection ids); + + /** + * 获得快递运费模板分页 + * + * @param pageReqVO 分页查询 + * @return 快递运费模板分页 + */ + PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO); + + /** + * 获得快递运费模板列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 快递运费模板列表 + */ + List getDeliveryExpressTemplateList(DeliveryExpressTemplateExportReqVO exportReqVO); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java new file mode 100644 index 000000000..420e70687 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -0,0 +1,212 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; + +/** + * 快递运费模板 Service 实现类 + * + * @author jason + */ +@Service +@Validated +public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTemplateService { + + @Resource + private DeliveryExpressTemplateMapper expressTemplateMapper; + @Resource + private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; + @Resource + private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; + @Resource + private DeliveryExpressTemplateChargeMapper.BatchInsertMapper expressTemplateChargeBatchMapper; + @Resource + private DeliveryExpressTemplateFreeMapper.BatchInsertMapper expressTemplateFreeBatchMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createDeliveryExpressTemplate(DeliveryExpressTemplateCreateReqVO createReqVO) { + //校验模板名是否唯一 + validateTemplateNameUnique(createReqVO.getName(), null); + // 插入 + DeliveryExpressTemplateDO deliveryExpressTemplate = INSTANCE.convert(createReqVO); + expressTemplateMapper.insert(deliveryExpressTemplate); + //插入运费模板计费表 + if(CollUtil.isNotEmpty(createReqVO.getTemplateCharge())) { + expressTemplateChargeBatchMapper.saveBatch( + INSTANCE.convertTemplateChargeList(deliveryExpressTemplate.getId(), createReqVO.getChargeMode(), createReqVO.getTemplateCharge()) + ); + } + //插入运费模板包邮表 + if(CollUtil.isNotEmpty(createReqVO.getTemplateFree())) { + expressTemplateFreeBatchMapper.saveBatch( + INSTANCE.convertTemplateFreeList(deliveryExpressTemplate.getId(), createReqVO.getTemplateFree()) + ); + } + return deliveryExpressTemplate.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateDeliveryExpressTemplate(DeliveryExpressTemplateUpdateReqVO updateReqVO) { + // 校验存在 + validateDeliveryExpressTemplateExists(updateReqVO.getId()); + //校验模板名是否唯一 + validateTemplateNameUnique(updateReqVO.getName(), updateReqVO.getId()); + + //更新运费从表 + updateExpressTemplateCharge(updateReqVO); + //更新包邮从表 + updateExpressTemplateFree(updateReqVO); + //更新模板主表 + DeliveryExpressTemplateDO updateObj = INSTANCE.convert(updateReqVO); + expressTemplateMapper.updateById(updateObj); + } + + private void updateExpressTemplateFree(DeliveryExpressTemplateUpdateReqVO updateReqVO) { + List oldFreeList = expressTemplateFreeMapper.selectListByTemplateId(updateReqVO.getId()); + List newFreeList = updateReqVO.getTemplateFree(); + //新增包邮区域列表 + List addFreeList = new ArrayList<>(newFreeList.size()); + //更新包邮区域列表 + List updateFreeList = new ArrayList<>(newFreeList.size()); + for (ExpressTemplateFreeUpdateVO item : newFreeList) { + if (Objects.nonNull(item.getId())) { + updateFreeList.add(INSTANCE.convertTemplateFree(item)); + }else{ + item.setTemplateId(updateReqVO.getId()); + addFreeList.add(INSTANCE.convertTemplateFree(item)); + } + } + //删除的包邮区域id + Set deleteFreeIds = CollectionUtils.convertSet(oldFreeList, DeliveryExpressTemplateFreeDO::getId); + deleteFreeIds.removeAll(CollectionUtils.convertSet(updateFreeList, DeliveryExpressTemplateFreeDO::getId)); + //新增 + if (CollUtil.isNotEmpty(addFreeList)) { + expressTemplateFreeBatchMapper.saveBatch(addFreeList); + } + //修改 + if (CollUtil.isNotEmpty(updateFreeList)) { + expressTemplateFreeBatchMapper.saveOrUpdateBatch(updateFreeList); + } + //删除 + if (CollUtil.isNotEmpty(deleteFreeIds)) { + expressTemplateFreeMapper.deleteBatchIds(deleteFreeIds); + } + } + + private void updateExpressTemplateCharge(DeliveryExpressTemplateUpdateReqVO updateReqVO) { + List oldChargeList = expressTemplateChargeMapper.selectListByTemplateId(updateReqVO.getId()); + List newChargeList = updateReqVO.getTemplateCharge(); + //新增运费区域列表 + List addList = new ArrayList<>(newChargeList.size()); + //更新运费区域列表 + List updateList = new ArrayList<>(newChargeList.size()); + for (ExpressTemplateChargeUpdateVO item : newChargeList) { + if (Objects.nonNull(item.getId())) { + //计费模式以主表为准 + item.setChargeMode(updateReqVO.getChargeMode()); + updateList.add(INSTANCE.convertTemplateCharge(item)); + }else{ + item.setTemplateId(updateReqVO.getId()); + item.setChargeMode(updateReqVO.getChargeMode()); + addList.add(INSTANCE.convertTemplateCharge(item)); + } + } + //删除的运费区域id + Set deleteChargeIds = CollectionUtils.convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId); + deleteChargeIds.removeAll(CollectionUtils.convertSet(updateList, DeliveryExpressTemplateChargeDO::getId)); + //新增 + if (CollUtil.isNotEmpty(addList)) { + expressTemplateChargeBatchMapper.saveBatch(addList); + } + //修改 + if (CollUtil.isNotEmpty(updateList)) { + expressTemplateChargeBatchMapper.saveOrUpdateBatch(updateList); + } + //删除 + if (CollUtil.isNotEmpty(deleteChargeIds)) { + expressTemplateChargeMapper.deleteBatchIds(deleteChargeIds); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteDeliveryExpressTemplate(Long id) { + // 校验存在 + validateDeliveryExpressTemplateExists(id); + // 删除主表 + expressTemplateMapper.deleteById(id); + // 删除运费从表 + expressTemplateChargeMapper.deleteByTemplateId(id); + // 删除包邮从表 + expressTemplateFreeMapper.deleteByTemplateId(id); + } + + /** + * 校验运费模板名是否唯一 + * @param name 模板名称 + * @param id 运费模板编号, 可以为null + */ + private void validateTemplateNameUnique(String name, Long id) { + DeliveryExpressTemplateDO template = expressTemplateMapper.selectByName(name); + if (template == null) { + return; + } + // 如果 id 为空 + if (id == null) { + throw exception(EXPRESS_TEMPLATE_NAME_DUPLICATE); + } + if (!template.getId().equals(id)) { + throw exception(EXPRESS_TEMPLATE_NAME_DUPLICATE); + } + } + + private void validateDeliveryExpressTemplateExists(Long id) { + if (expressTemplateMapper.selectById(id) == null) { + throw exception(EXPRESS_TEMPLATE_NOT_EXISTS); + } + } + + @Override + public DeliveryExpressTemplateRespVO getDeliveryExpressTemplate(Long id) { + List chargeList = expressTemplateChargeMapper.selectListByTemplateId(id); + List freeList = expressTemplateFreeMapper.selectListByTemplateId(id); + DeliveryExpressTemplateDO template = expressTemplateMapper.selectById(id); + return INSTANCE.convert(template, chargeList,freeList); + } + + @Override + public List getDeliveryExpressTemplateList(Collection ids) { + return expressTemplateMapper.selectBatchIds(ids); + } + + @Override + public PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO) { + return expressTemplateMapper.selectPage(pageReqVO); + } + + @Override + public List getDeliveryExpressTemplateList(DeliveryExpressTemplateExportReqVO exportReqVO) { + return expressTemplateMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index 2d5c766fd..c7363c994 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.Arrays; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -28,10 +29,10 @@ public class AreaController { @GetMapping("/tree") @Operation(summary = "获得地区树") - public CommonResult> getAreaTree() { - Area area = AreaUtils.getArea(Area.ID_CHINA); - Assert.notNull(area, "获取不到中国"); - return success(AreaConvert.INSTANCE.convertList(area.getChildren())); + public CommonResult> getAreaTree(Integer id) { + Area area = AreaUtils.getArea(id); + Assert.notNull(area, String.format("获取不到 id : %d的区域", id)); + return success(AreaConvert.INSTANCE.convertList(Arrays.asList(area))); } @GetMapping("/get-by-ip") From 3672c217f84cb917d706f4f8ee371503cf39d636 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 22 May 2023 00:03:11 +0800 Subject: [PATCH 053/232] =?UTF-8?q?mall=EF=BC=9A=E5=94=AE=E5=90=8E?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=8E=A5=E5=8F=A3=E7=9A=84=20mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppTradeAfterSaleController.java | 50 +++++++++ .../vo/AppTradeAfterSalePageItemRespVO.java | 103 ++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSalePageItemRespVO.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java index c78a10e36..1982a9bdd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.controller.app.aftersale; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSalePageItemRespVO; +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -12,6 +15,8 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Arrays; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -26,6 +31,51 @@ public class AppTradeAfterSaleController { @Resource private TradeAfterSaleService afterSaleService; + // TODO 芋艿:待实现 + @GetMapping(value = "/page") + @Operation(summary = "获得售后分页") + public CommonResult> getAfterSalePage() { + AppTradeAfterSalePageItemRespVO vo = new AppTradeAfterSalePageItemRespVO(); + vo.setId(1L); + vo.setNo("1146347329394184195"); + vo.setStatus(61); + vo.setWay(10); + vo.setType(10); + vo.setApplyReason("不想要了"); + vo.setApplyDescription("这个商品我不喜欢,想退款"); + vo.setApplyPicUrls(Arrays.asList("pic_url_1", "pic_url_2", "pic_url_3")); + + // 设置订单相关信息 + vo.setOrderId(2001L); + vo.setOrderNo("23456789009876"); + vo.setOrderItemId(3001L); + vo.setSpuId(4001L); + vo.setSpuName("商品名"); + vo.setSkuId(5001L); + vo.setProperties(Arrays.asList( + new AppProductPropertyValueDetailRespVO().setPropertyId(6001L).setPropertyName("颜色").setValueId(7001L).setValueName("红色"), + new AppProductPropertyValueDetailRespVO().setPropertyId(6002L).setPropertyName("尺寸").setValueId(7002L).setValueName("XL"))); + vo.setPicUrl("https://cdn.pixabay.com/photo/2022/12/06/06/21/lavender-7638368_1280.jpg"); + vo.setCount(2); + + // 设置审批相关信息 + vo.setAuditReason("审核通过"); + + // 设置退款相关信息 + vo.setRefundPrice(1000); + vo.setRefundTime(LocalDateTime.now()); + + // 设置退货相关信息 + vo.setLogisticsId(7001L); + vo.setLogisticsNo("LAGN101010101001"); + vo.setDeliveryTime(LocalDateTime.now()); + vo.setReceiveTime(LocalDateTime.now()); + vo.setReceiveReason("收货正常"); + + return success(new PageResult<>(Arrays.asList(vo), 1L)); +// return success(afterSaleService.getAfterSalePage(getLoginUserId())); + } + @PostMapping(value = "/create") @Operation(summary = "申请售后") public CommonResult createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSalePageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSalePageItemRespVO.java new file mode 100644 index 000000000..31cb2e231 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSalePageItemRespVO.java @@ -0,0 +1,103 @@ +package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "用户 App - 交易售后的分页项 Request VO") +@Data +public class AppTradeAfterSalePageItemRespVO { + + @Schema(description = "售后编号", required = true, example = "1024") + private Long id; + + @Schema(description = "售后流水号", required = true, example = "1146347329394184195") + private String no; + + @Schema(description = "售后状态", required = true, example = "1") + private Integer status; + + @Schema(description = "售后方式", required = true, example = "1") + private Integer way; + + @Schema(description = "售后类型", required = true, example = "1") + private Integer type; + + @Schema(description = "申请原因", required = true, example = "1") + private String applyReason; + + @Schema(description = "补充描述", required = true, example = "1") + private String applyDescription; + + @Schema(description = "补充凭证图片", required = true, example = "1") + private List applyPicUrls; + + // ========== 交易订单相关 ========== + + @Schema(description = "交易订单编号", required = true, example = "1") + private Long orderId; + + @Schema(description = "交易订单流水号", required = true, example = "1") + private String orderNo; + + @Schema(description = "交易订单项编号", required = true, example = "1") + private Long orderItemId; + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "1") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + private Long skuId; + + /** + * 属性数组 + */ + private List properties; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/01.jpg") + private String picUrl; + + @Schema(description = "退货商品数量", required = true, example = "1") + private Integer count; + + // ========== 审批相关 ========== + + /** + * 审批备注 + * + * 注意,只有审批不通过才会填写 + */ + private String auditReason; + + // ========== 退款相关 ========== + + @Schema(description = "退款金额,单位:分", example = "100") + private Integer refundPrice; + + @Schema(description = "退款时间") + private LocalDateTime refundTime; + + // ========== 退货相关 ========== + + @Schema(description = "退货物流公司编号", example = "1") + private Long logisticsId; + + @Schema(description = "退货物流单号", example = "SF123456789") + private String logisticsNo; + + @Schema(description = "退货时间") + private LocalDateTime deliveryTime; + + @Schema(description = "收货时间") + private LocalDateTime receiveTime; + + @Schema(description = "收货备注") + private String receiveReason; + +} From 16956a6501d8fe6a73d22db7841123382aa910a1 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 22 May 2023 23:08:21 +0800 Subject: [PATCH 054/232] =?UTF-8?q?=E8=BF=90=E8=B4=B9=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=EF=BC=8C=E5=8C=BA=E5=9F=9F=E9=80=89=E6=8B=A9=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=87=92=E5=8A=A0=E8=BD=BD=E4=BC=98=E5=8C=96=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/ip/AreaController.java | 30 +++++++++++++++---- .../admin/ip/vo/LazyAreaNodeRespVO.java | 21 +++++++++++++ .../module/system/convert/ip/AreaConvert.java | 14 +++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index c7363c994..87e6e0bfd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -6,18 +6,18 @@ import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.IPUtils; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.LazyAreaNodeRespVO; import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -29,10 +29,28 @@ public class AreaController { @GetMapping("/tree") @Operation(summary = "获得地区树") - public CommonResult> getAreaTree(Integer id) { + public CommonResult> getAreaTree() { + Area area = AreaUtils.getArea(Area.ID_CHINA); + Assert.notNull(area, "获取不到中国"); + return success(AreaConvert.INSTANCE.convertList(area.getChildren())); + } + + @GetMapping("/getChildrenArea") + @Operation(summary = "获得地区的下级区域") + public CommonResult> getChildrenArea(Integer id) { Area area = AreaUtils.getArea(id); Assert.notNull(area, String.format("获取不到 id : %d的区域", id)); - return success(AreaConvert.INSTANCE.convertList(Arrays.asList(area))); + return success(AreaConvert.INSTANCE.convertList2(area.getChildren())); + } + + @PostMapping("/list") + @Operation(summary = "通过区域ids获得地区列表") + public CommonResult> list(@RequestBody Set areaIds) { + List areaList = new ArrayList<>(areaIds.size()); + for (Integer areaId : areaIds) { + areaList.add(AreaUtils.getArea(areaId)); + } + return success(AreaConvert.INSTANCE.convertList2(areaList)); } @GetMapping("/get-by-ip") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java new file mode 100644 index 000000000..fd184b307 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.system.controller.admin.ip.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author jason + */ +@Schema(description = "管理后台 - 懒加载地区节点 Response VO") +@Data +public class LazyAreaNodeRespVO { + + @Schema(description = "编号", required = true, example = "110000") + private Integer id; + + @Schema(description = "名字", required = true, example = "北京") + private String name; + + @Schema(description = "是否叶子节点", required = true, example = "false") + private Boolean leaf = Boolean.FALSE; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java index 0cedf8785..540272e12 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java @@ -1,11 +1,17 @@ package cn.iocoder.yudao.module.system.convert.ip; import cn.iocoder.yudao.framework.ip.core.Area; +import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.LazyAreaNodeRespVO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; +import org.springframework.context.annotation.Lazy; import java.util.List; +import java.util.Objects; @Mapper public interface AreaConvert { @@ -14,4 +20,12 @@ public interface AreaConvert { List convertList(List list); + List convertList2(List list); + + @Mapping(source = "type", target = "leaf") + LazyAreaNodeRespVO convert(Area area); + + default Boolean convertAreaType(Integer type){ + return Objects.equals(AreaTypeEnum.DISTRICT.getType(),type); + } } From cac5545762b6ac742bad056383087f6f6418a456 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 23 May 2023 11:01:40 +0800 Subject: [PATCH 055/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=E5=95=86?= =?UTF-8?q?=E5=93=81=E7=AE=A1=E7=90=86,=20=E5=AE=8C=E5=96=84=20mall.sql,?= =?UTF-8?q?=20=E5=AE=8C=E5=96=84=20product=20=E6=B5=8B=E8=AF=95=E7=9B=B8?= =?UTF-8?q?=E5=85=B3sql,=20=E5=AE=8C=E5=96=84=20ProductSpuServiceImplTest?= =?UTF-8?q?=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 383 ++++++++--------- .../product/enums/DictTypeConstants.java | 10 + .../product/enums/ErrorCodeConstants.java | 5 +- .../product/enums/ProductConstants.java | 34 ++ ...peEnum.java => ProductSpuPageTabEnum.java} | 13 +- .../admin/brand/ProductBrandController.java | 10 +- .../brand/vo/ProductBrandSimpleRespVO.java | 17 + .../admin/sku/vo/ProductSkuBaseVO.java | 57 ++- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 16 - .../admin/sku/vo/ProductSkuRespVO.java | 21 - .../admin/spu/ProductSpuController.java | 42 +- .../admin/spu/vo/ProductSpuBaseVO.java | 18 +- .../admin/spu/vo/ProductSpuCreateReqVO.java | 11 +- .../admin/spu/vo/ProductSpuDetailRespVO.java | 22 +- .../admin/spu/vo/ProductSpuExcelVO.java | 119 ++++++ .../admin/spu/vo/ProductSpuExportReqVO.java | 32 ++ .../admin/spu/vo/ProductSpuPageReqVO.java | 13 +- .../admin/spu/vo/ProductSpuPageRespVO.java | 32 -- .../admin/spu/vo/ProductSpuRespVO.java | 28 +- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 38 +- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 25 +- .../spu/vo/ProductSpuUpdateStatusReqVO.java | 9 +- .../convert/brand/ProductBrandConvert.java | 3 +- .../convert/spu/ProductSpuConvert.java | 102 +++-- .../category/ProductCategoryDO.java | 6 - .../property/ProductPropertyDO.java | 3 +- .../property/ProductPropertyValueDO.java | 3 +- .../dal/dataobject/sku/ProductSkuDO.java | 36 +- .../dal/dataobject/spu/ProductSpuDO.java | 2 +- .../dal/mysql/brand/ProductBrandMapper.java | 3 + .../dal/mysql/spu/ProductSpuMapper.java | 106 ++++- .../service/brand/ProductBrandService.java | 7 + .../brand/ProductBrandServiceImpl.java | 5 + .../category/ProductCategoryServiceImpl.java | 12 +- .../service/sku/ProductSkuServiceImpl.java | 1 - .../service/spu/ProductSpuService.java | 8 + .../service/spu/ProductSpuServiceImpl.java | 105 ++--- .../ProductCategoryServiceImplTest.java | 3 +- .../service/sku/ProductSkuServiceTest.java | 22 +- .../spu/ProductSpuServiceImplTest.java | 401 +++++++++++++----- .../src/test/resources/sql/clean.sql | 4 +- .../src/test/resources/sql/create_tables.sql | 184 +++++--- 42 files changed, 1318 insertions(+), 653 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java rename yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/{ProductSpuTabTypeEnum.java => ProductSpuPageTabEnum.java} (63%) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 77356cf65..56b7f65f6 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -22,23 +22,23 @@ SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- DROP TABLE IF EXISTS `market_activity`; CREATE TABLE `market_activity` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '活动编号', - `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '活动标题', - `activity_type` tinyint NOT NULL COMMENT '活动类型', - `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', - `start_time` datetime NOT NULL COMMENT '开始时间', - `end_time` datetime NOT NULL COMMENT '结束时间', - `invalid_time` datetime NULL DEFAULT NULL COMMENT '失效时间', - `delete_time` datetime NULL DEFAULT NULL COMMENT '删除时间', - `time_limited_discount` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', - `full_privilege` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '活动编号', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '活动标题', + `activity_type` tinyint NOT NULL COMMENT '活动类型', + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', + `start_time` datetime NOT NULL COMMENT '开始时间', + `end_time` datetime NOT NULL COMMENT '结束时间', + `invalid_time` datetime NULL DEFAULT NULL COMMENT '失效时间', + `delete_time` datetime NULL DEFAULT NULL COMMENT '删除时间', + `time_limited_discount` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', + `full_privilege` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '促销活动'; -- ---------------------------- @@ -52,20 +52,20 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `market_banner`; CREATE TABLE `market_banner` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Banner编号', - `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'Banner标题', - `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图片URL', - `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', - `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '跳转地址', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - `sort` tinyint NULL DEFAULT NULL COMMENT '排序', - `memo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Banner编号', + `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'Banner标题', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图片URL', + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态', + `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '跳转地址', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + `sort` tinyint NULL DEFAULT NULL COMMENT '排序', + `memo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Banner管理'; -- ---------------------------- @@ -79,22 +79,22 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `member_address`; CREATE TABLE `member_address` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '收件地址编号', - `user_id` bigint NOT NULL COMMENT '用户编号', - `name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件人名称', - `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '手机号', - `area_id` bigint NOT NULL COMMENT '地区编码', - `post_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '邮编', - `detail_address` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件详细地址', - `defaulted` bit(1) NOT NULL COMMENT '是否默认', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE, - INDEX `idx_userId`(`user_id` ASC) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '收件地址编号', + `user_id` bigint NOT NULL COMMENT '用户编号', + `name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件人名称', + `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '手机号', + `area_id` bigint NOT NULL COMMENT '地区编码', + `post_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '邮编', + `detail_address` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件详细地址', + `defaulted` bit(1) NOT NULL COMMENT '是否默认', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_userId`(`user_id` ASC) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址'; -- ---------------------------- @@ -109,19 +109,19 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_brand`; CREATE TABLE `product_brand` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号', - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌名称', - `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌图片', - `sort` int NULL DEFAULT 0 COMMENT '品牌排序', - `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '品牌描述', - `status` tinyint NOT NULL COMMENT '状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌名称', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌图片', + `sort` int NULL DEFAULT 0 COMMENT '品牌排序', + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '品牌描述', + `status` tinyint NOT NULL COMMENT '状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品品牌'; -- ---------------------------- @@ -136,20 +136,20 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_category`; CREATE TABLE `product_category` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', - `parent_id` bigint NOT NULL COMMENT '父分类编号', - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名称', - `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类图片', - `sort` int NULL DEFAULT 0 COMMENT '分类排序', - `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '分类描述', - `status` tinyint NOT NULL COMMENT '开启状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', + `parent_id` bigint NOT NULL COMMENT '父分类编号', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名称', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类图片', + `sort` int NULL DEFAULT 0 COMMENT '分类排序', + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '分类描述', + `status` tinyint NOT NULL COMMENT '开启状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品分类'; -- ---------------------------- @@ -164,18 +164,18 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_property`; CREATE TABLE `product_property` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格名称', - `status` tinyint DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`) USING BTREE, - KEY `idx_name` (`name`(32)) USING BTREE COMMENT '规格名称索引' + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格名称', + `status` tinyint DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_name` (`name`(32)) USING BTREE COMMENT '规格名称索引' ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='规格名称'; -- ---------------------------- @@ -189,18 +189,18 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_property_value`; CREATE TABLE `product_property_value` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `property_id` bigint DEFAULT NULL COMMENT '规格键id', - `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格值名字', - `status` tinyint DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `property_id` bigint DEFAULT NULL COMMENT '规格键id', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格值名字', + `status` tinyint DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='规格值'; -- ---------------------------- @@ -214,26 +214,26 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_sku`; CREATE TABLE `product_sku` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `spu_id` bigint NOT NULL COMMENT 'spu编号', - `properties` varchar(512) DEFAULT NULL COMMENT '属性数组,JSON 格式 [{propertId: , valueId: }, {propertId: , valueId: }]', - `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位:分', - `market_price` int DEFAULT NULL COMMENT '市场价,单位:分', - `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', - `bar_code` varchar(64) DEFAULT NULL COMMENT 'SKU 的条形码', - `pic_url` varchar(256) NOT NULL COMMENT '图片地址', - `stock` int DEFAULT NULL COMMENT '库存', - `weight` double DEFAULT NULL COMMENT '商品重量,单位:kg 千克', - `volume` double DEFAULT NULL COMMENT '商品体积,单位:m^3 平米', - `sub_commission_first_price` int DEFAULT NULL COMMENT '一级分销的佣金,单位:分', - `sub_commission_second_price` int DEFAULT NULL COMMENT '二级分销的佣金,单位:分', - `sales_count` int DEFAULT NULL COMMENT '商品销量', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) DEFAULT NULL COMMENT '创建人', - `updater` double(64,0) DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `spu_id` bigint NOT NULL COMMENT 'spu编号', + `properties` varchar(512) DEFAULT NULL COMMENT '属性数组,JSON 格式 [{propertId: , valueId: }, {propertId: , valueId: }]', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位:分', + `market_price` int DEFAULT NULL COMMENT '市场价,单位:分', + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', + `bar_code` varchar(64) DEFAULT NULL COMMENT 'SKU 的条形码', + `pic_url` varchar(256) NOT NULL COMMENT '图片地址', + `stock` int DEFAULT NULL COMMENT '库存', + `weight` double DEFAULT NULL COMMENT '商品重量,单位:kg 千克', + `volume` double DEFAULT NULL COMMENT '商品体积,单位:m^3 平米', + `sub_commission_first_price` int DEFAULT NULL COMMENT '一级分销的佣金,单位:分', + `sub_commission_second_price` int DEFAULT NULL COMMENT '二级分销的佣金,单位:分', + `sales_count` int DEFAULT NULL COMMENT '商品销量', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) DEFAULT NULL COMMENT '创建人', + `updater` double(64,0) DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='商品sku'; @@ -248,45 +248,45 @@ COMMIT; -- ---------------------------- DROP TABLE IF EXISTS `product_spu`; CREATE TABLE `product_spu` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品 SPU 编号,自增', - `name` varchar(128) NOT NULL COMMENT '商品名称', - `keyword` varchar(256) DEFAULT NULL COMMENT '关键字', - `introduction` varchar(256) COMMENT '商品简介', - `description` text COMMENT '商品详情', - `bar_code` varchar(64) DEFAULT NULL COMMENT '条形码', - `category_id` bigint NOT NULL COMMENT '商品分类编号', - `brand_id` int DEFAULT NULL COMMENT '商品品牌编号', - `pic_url` varchar(256) NOT NULL COMMENT '商品封面图', - `slider_pic_urls` varchar(2000) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张', - `video_url` varchar(256) DEFAULT NULL COMMENT '商品视频', - `unit` tinyint NOT NULL COMMENT '单位', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `status` tinyint NOT NULL COMMENT '商品状态: 0 上架(开启) 1 下架(禁用)-1 回收', - `spec_type` bit(1) DEFAULT NULL COMMENT '规格类型:0 单规格 1 多规格', - `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位使用:分', - `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分', - `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', - `stock` int NOT NULL DEFAULT '0' COMMENT '库存', - `delivery_template_id` bigint NOT NULL COMMENT '物流配置模板编号', - `recommend_hot` bit(1) DEFAULT NULL COMMENT '是否热卖推荐: 0 默认 1 热卖', - `recommend_benefit` bit(1) DEFAULT NULL COMMENT '是否优惠推荐: 0 默认 1 优选', - `recommend_best` bit(1) DEFAULT NULL COMMENT '是否精品推荐: 0 默认 1 精品', - `recommend_new` bit(1) DEFAULT NULL COMMENT '是否新品推荐: 0 默认 1 新品', - `recommend_good` bit(1) DEFAULT NULL COMMENT '是否优品推荐', - `give_integral` int NOT NULL COMMENT '赠送积分', - `give_coupon_template_ids` varchar(512) DEFAULT '' COMMENT '赠送的优惠劵编号的数组', - `sub_commission_type` bit(1) DEFAULT NULL COMMENT '分销类型', - `activity_orders` varchar(16) NOT NULL DEFAULT '' COMMENT '活动显示排序0=默认, 1=秒杀,2=砍价,3=拼团', - `sales_count` int DEFAULT '0' COMMENT '商品销量', - `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量', - `browse_count` int DEFAULT '0' COMMENT '商品点击量', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar(64) DEFAULT NULL COMMENT '创建人', - `updater` varchar(64) DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品 SPU 编号,自增', + `name` varchar(128) NOT NULL COMMENT '商品名称', + `keyword` varchar(256) DEFAULT NULL COMMENT '关键字', + `introduction` varchar(256) COMMENT '商品简介', + `description` text COMMENT '商品详情', + `bar_code` varchar(64) DEFAULT NULL COMMENT '条形码', + `category_id` bigint NOT NULL COMMENT '商品分类编号', + `brand_id` int DEFAULT NULL COMMENT '商品品牌编号', + `pic_url` varchar(256) NOT NULL COMMENT '商品封面图', + `slider_pic_urls` varchar(2000) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张', + `video_url` varchar(256) DEFAULT NULL COMMENT '商品视频', + `unit` tinyint NOT NULL COMMENT '单位', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', + `status` tinyint NOT NULL COMMENT '商品状态: 0 上架(开启) 1 下架(禁用)-1 回收', + `spec_type` bit(1) DEFAULT NULL COMMENT '规格类型:0 单规格 1 多规格', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位使用:分', + `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分', + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', + `stock` int NOT NULL DEFAULT '0' COMMENT '库存', + `delivery_template_id` bigint NOT NULL COMMENT '物流配置模板编号', + `recommend_hot` bit(1) DEFAULT NULL COMMENT '是否热卖推荐: 0 默认 1 热卖', + `recommend_benefit` bit(1) DEFAULT NULL COMMENT '是否优惠推荐: 0 默认 1 优选', + `recommend_best` bit(1) DEFAULT NULL COMMENT '是否精品推荐: 0 默认 1 精品', + `recommend_new` bit(1) DEFAULT NULL COMMENT '是否新品推荐: 0 默认 1 新品', + `recommend_good` bit(1) DEFAULT NULL COMMENT '是否优品推荐', + `give_integral` int NOT NULL COMMENT '赠送积分', + `give_coupon_template_ids` varchar(512) DEFAULT '' COMMENT '赠送的优惠劵编号的数组', + `sub_commission_type` bit(1) DEFAULT NULL COMMENT '分销类型', + `activity_orders` varchar(16) NOT NULL DEFAULT '' COMMENT '活动显示排序0=默认, 1=秒杀,2=砍价,3=拼团', + `sales_count` int DEFAULT '0' COMMENT '商品销量', + `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量', + `browse_count` int DEFAULT '0' COMMENT '商品点击量', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar(64) DEFAULT NULL COMMENT '创建人', + `updater` varchar(64) DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='商品spu'; -- ---------------------------- @@ -294,17 +294,17 @@ CREATE TABLE `product_spu` ( -- ---------------------------- DROP TABLE IF EXISTS `product_favorite`; CREATE TABLE `product_favorite` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `spu_id` bigint NOT NULL COMMENT '商品 SPU 编号', - `user_id` bigint NOT NULL COMMENT '用户id', - `type` int(10) NOT NULL DEFAULT 1 COMMENT '类型1:收藏 2:点赞', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `spu_id` bigint NOT NULL COMMENT '商品 SPU 编号', + `user_id` bigint NOT NULL COMMENT '用户id', + `type` int(10) NOT NULL DEFAULT 1 COMMENT '类型1:收藏 2:点赞', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='喜欢的商品表'; @@ -316,6 +316,7 @@ COMMIT; SET FOREIGN_KEY_CHECKS = 1; +BEGIN; INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 0, '/product', 'merchant', NULL, 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:26:19', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'dict', 'mall/product/category/index', 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:23:37', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); @@ -334,6 +335,7 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2016, '商品创建', 'product:spu:create', 3, 2, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2017, '商品更新', 'product:spu:update', 3, 3, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2018, '商品删除', 'product:spu:delete', 3, 4, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2018, '商品导出', 'product:spu:export', 3, 5, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2019, '规格管理', '', 2, 3, 2000, 'property', '', 'mall/product/property/index', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2020, '规格查询', 'product:property:query', 3, 1, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2021, '规格创建', 'product:property:create', 3, 2, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0'); @@ -345,37 +347,16 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); +BEGIN; -INSERT INTO `system_dict_data`(`sort`,`label`,`value`,`dict_type`,`status`,`color_type`,`css_class`,`remark`,`creator`,`create_time`,`updater`,`update_time`,`deleted`) VALUES - (1,'打',2,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'盒',3,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'袋',4,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'箱',5,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'套',6,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'包',7,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'双',8,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'卷',9,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'张',10,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'克',11,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'千克',12,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'毫克',13,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'微克',14,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'吨',15,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'升',16,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1,'毫升',17,'product_unit',0,'','','',1, NOW(),1, NOW(),0), - (1, '平方米', 18, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '平方千米', 19, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '平方英里', 20, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '平方码', 21, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '平方英尺', 22, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '立方米', 23, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '立方厘米', 24, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '立方英寸', 25, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '米', 26, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '千米', 27, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '厘米', 28, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '毫米', 29, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '英寸', 30, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '英尺', 31, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1, '码', 32, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), 0), - (1,'个',1,'product_unit',0,'','','',1, NOW(),1, NOW(),0); \ No newline at end of file +BEGIN; +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '个', 1, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '件', 2, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '盒', 3, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '袋', 4, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '箱', 5, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '套', 6, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '包', 7, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '双', 8, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '卷', 9, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +COMMIT; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java new file mode 100644 index 000000000..a41064970 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.module.product.enums; + +/** + * product 字典类型的枚举类 + * @author HUIHUI + */ +public interface DictTypeConstants { + String PRODUCT_UNIT = "product_unit"; // 商品单位 + String PRODUCT_SPU_STATUS = "product_spu_status"; // 商品 SPU 状态 +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 5c36a2328..9e7552b17 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -18,7 +18,7 @@ public interface ErrorCodeConstants { // ========== 商品品牌相关编号 1008002000 ========== ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); - ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在"); + ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌已禁用"); ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在"); // ========== 商品属性项 1008003000 ========== @@ -32,8 +32,9 @@ public interface ErrorCodeConstants { // ========== 商品 SPU 1008005000 ========== ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); - ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下"); + ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第二级的商品分类及以下"); ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态"); + ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1008005003, "商品 SPU 不处于回收站状态"); // ========== 商品 SKU 1008006000 ========== ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在"); diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java new file mode 100644 index 000000000..db0536993 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.enums; + +/** + * Product 常量 TODO 把使用到的常量收拢到一块定义替换魔法值 + * + * @author HUIHUI + */ + +public interface ProductConstants { + /** + * 父分类编号 - 根分类 + */ + Long PARENT_ID_NULL = 0L; + /** + * 限定分类层级 + */ + int CATEGORY_LEVEL = 2; + /** + * SPU 分页 tab 个数 + */ + int SPU_TAB_COUNTS = 5; + /** + * 警戒库存 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 + */ + int ALERT_STOCK = 10; + /** + * 默认商品销量 TODO 默认商品销量为零 + */ + Integer SALES_COUNT = 0; + /** + * 默认善品浏览量 TODO 默认浏览量为零 + */ + Integer BROWSE_COUNT = 0; +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java similarity index 63% rename from yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java rename to yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java index 86b5a9e8c..4c6e729f5 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuTabTypeEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java @@ -1,24 +1,27 @@ package cn.iocoder.yudao.module.product.enums.spu; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; + // TODO @puhui999:中英文之间要有空格; 商品 spu Tab 标签枚举;这个类可以改成 ProductSpuPageTabEnum 会更好一点哈;分页 Tab 的意思; /** - * 商品spu标签枚举类型 + * 商品 spu Tabs 标签枚举类型 * * @author HUIHUI */ @Getter @AllArgsConstructor -public enum ProductSpuTabTypeEnum { +public enum ProductSpuPageTabEnum implements IntArrayValuable { FOR_SALE(0,"出售中商品"), IN_WAREHOUSE(1,"仓库中商品"), SOLD_OUT(2,"已售空商品"), ALERT_STOCK(3,"警戒库存"), RECYCLE_BIN(4,"商品回收站"); - + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuPageTabEnum::getType).toArray(); /** * 状态 */ @@ -28,4 +31,8 @@ public enum ProductSpuTabTypeEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index 0e6f7f3bc..cf02edf1d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.brand; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; @@ -61,7 +62,14 @@ public class ProductBrandController { ProductBrandDO brand = brandService.getBrand(id); return success(ProductBrandConvert.INSTANCE.convert(brand)); } - + @GetMapping("/list-all-simple") + @Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项") + public CommonResult> getSimpleUserList() { + // 获取品牌列表,只要开启状态的 + List list = brandService.getBrandListByStatus(CommonStatusEnum.ENABLE.getStatus()); + // 排序后,返回给前端 + return success(ProductBrandConvert.INSTANCE.convertList1(list)); + } @GetMapping("/page") @Operation(summary = "获得品牌分页") @PreAuthorize("@ss.hasPermission('product:brand:query')") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java new file mode 100644 index 000000000..79a4a6d59 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Schema(description = "管理后台 - 品牌精简信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProductBrandSimpleRespVO { + @Schema(description = "品牌编号", required = true, example = "1024") + private Long id; + @Schema(description = "品牌名称", required = true, example = "芋道") + private String name; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index 4cc258082..be8f761a1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -41,20 +45,51 @@ public class ProductSkuBaseVO { @Schema(description = "预警预存", example = "1") private Integer warnStock; - @Schema(description = "商品重量", example = "1") // 单位:kg 千克 + @Schema(description = "商品重量,单位:kg 千克", example = "1") private Double weight; - @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 + @Schema(description = "商品体积,单位:m^3 平米", example = "1024") private Double volume; - // TODO @pitui999:注释可以去掉,VO 使用 @Schema 作为注释 - /** - * 一级分销的佣金,单位:分 - */ - @Schema(description = "一级分销的佣金", example = "1024") + + @Schema(description = "一级分销的佣金,单位:分", example = "1024") private Integer subCommissionFirstPrice; - /** - * 二级分销的佣金,单位:分 - */ - @Schema(description = "二级分销的佣金", example = "1024") + + @Schema(description = "二级分销的佣金,单位:分", example = "1024") private Integer subCommissionSecondPrice; + + /** + * 商品属性 + */ + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Property { + + /** + * 属性编号 + * 关联 {@link ProductPropertyDO#getId()} + */ + private Long propertyId; + /** + * 属性名字 + * 冗余 {@link ProductPropertyDO#getName()} + * + * 注意:每次属性名字发生变化时,需要更新该冗余 + */ + private String propertyName; + + /** + * 属性值编号 + * 关联 {@link ProductPropertyValueDO#getId()} + */ + private Long valueId; + /** + * 属性值名字 + * 冗余 {@link ProductPropertyValueDO#getName()} + * + * 注意:每次属性值名字发生变化时,需要更新该冗余 + */ + private String valueName; + + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index a1253ca26..2909a514f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -12,22 +12,6 @@ import java.util.List; @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { - @Schema(description = "商品属性") - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class Property { - - @Schema(description = "属性编号", required = true, example = "1") - @NotNull(message = "属性编号不能为空") - private Long propertyId; - - @Schema(description = "属性值编号", required = true, example = "1024") - @NotNull(message = "属性值编号不能为空") - private Long valueId; - - } - /** * 属性数组 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index 815761615..ce0614152 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -15,27 +15,6 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(description = "商品属性") - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class Property { - - @Schema(description = "属性编号", required = true, example = "1") - @NotNull(message = "属性编号不能为空") - private Long propertyId; - - // TODO @puhui999:propertyName 是不是也返回下 - - @Schema(description = "属性值编号", required = true, example = "1024") - @NotNull(message = "属性值编号不能为空") - private Long valueId; - - @Schema(description = "属性值", example = "1024") - private String valueName; - - } - /** * 属性数组 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 698681856..5b35c49fa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -16,12 +19,24 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; +/** + * 商品 SPU 相关接口 + * + * @author HUIHUI + */ @Tag(name = "管理后台 - 商品 SPU") @RestController @RequestMapping("/product/spu") @@ -30,10 +45,6 @@ public class ProductSpuController { @Resource private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; @PostMapping("/create") @Operation(summary = "创建商品 SPU") @@ -50,7 +61,7 @@ public class ProductSpuController { return success(true); } - @PutMapping("/updateStatus") + @PutMapping("/update-status") @Operation(summary = "更新商品 SPU Status") @PreAuthorize("@ss.hasPermission('product:spu:update')") public CommonResult updateStatus(@Valid @RequestBody ProductSpuUpdateStatusReqVO updateReqVO) { @@ -86,16 +97,27 @@ public class ProductSpuController { @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { + public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } - - // TODO @tuihui999:get-count;另外,url 使用 - 拆分 - @GetMapping("/tabsCount") - @Operation(summary = "获得商品 SPU tabsCount") + + // TODO @tuihui999:get-count;另外,url 使用 - 拆分 fix + @GetMapping("/get-count") + @Operation(summary = "获得商品 SPU 分页 tab count") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getTabsCount() { return success(productSpuService.getTabsCount()); } + @GetMapping("/export") + @Operation(summary = "导出用户") + @PreAuthorize("@ss.hasPermission('product:spu:export')") + @OperateLog(type = EXPORT) + public void exportUserList(@Validated ProductSpuExportReqVO reqVO, + HttpServletResponse response) throws IOException { + List spuList = productSpuService.getSpuList(reqVO); + // 导出 Excel + List datas = ProductSpuConvert.INSTANCE.convertList03(spuList); + ExcelUtils.write(response, "商品spu.xls", "数据", ProductSpuExcelVO.class, datas); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 5a0a64ef3..4b194ed76 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -10,7 +11,9 @@ import java.util.List; /** * 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ + * + * @author HUIHUI + */ @Data public class ProductSpuBaseVO { @@ -30,11 +33,12 @@ public class ProductSpuBaseVO { @NotEmpty(message = "商品详情不能为空") private String description; - @Schema(description = "商品分类编号", required = true, example = "芋道") - @NotNull(message = "商品分类编号不能为空") + @Schema(description = "商品分类编号", required = true, example = "1") + @NotNull(message = "商品分类不能为空") private Long categoryId; - @Schema(description = "商品品牌编号", required = true, example = "芋道") + @Schema(description = "商品品牌编号", required = true, example = "1") + @NotNull(message = "商品品牌不能为空") private Long brandId; @Schema(description = "商品封面图", required = true, example = "芋道") @@ -96,16 +100,16 @@ public class ProductSpuBaseVO { @Schema(description = "赠送的优惠劵编号的数组") // TODO 这块前端还未实现 private List giveCouponTemplateIds; - @Schema(description = "分销类型") + @Schema(description = "分销类型", example = "true") @NotNull(message = "商品分销类型不能为空") private Boolean subCommissionType; - @Schema(description = "活动展示顺序") // TODO 这块前端还未实现 + @Schema(description = "活动展示顺序", example = "[1、3、2、4、5]") // TODO 这块前端还未实现 private List activityOrders; // ========== 统计相关字段 ========= - @Schema(description = "虚拟销量", required = true, example = "芋道") + @Schema(description = "虚拟销量", example = "芋道") private Integer virtualSalesCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java index c75ed4d2e..b2fef56e2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java @@ -9,15 +9,20 @@ import lombok.ToString; import javax.validation.Valid; import java.util.List; +/** + * 商品 SPU 创建 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuCreateReqVO extends ProductSpuBaseVO { - /** - * SKU 数组 - */ + // ========== SKU 相关字段 ========= + + @Schema(description = "SKU 数组") @Valid private List skus; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index 51ea5d38a..7614467a1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -6,20 +6,36 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import java.time.LocalDateTime; import java.util.List; -@Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息 +/** + * 商品 SPU 详细 Response VO + * 包括关联的 SKU 等信息 + * + * @author HUIHUI + */ +@Schema(description = "管理后台 - 商品 SPU 详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuDetailRespVO extends ProductSpuBaseVO { - @Schema(description = "商品编号", example = "1") + @Schema(description = "spuId") private Long id; + @Schema(description = "商品销量") + private Integer salesCount; + + @Schema(description = "浏览量") + private Integer browseCount; + + @Schema(description = "商品状态") + private Integer status; + // ========== SKU 相关字段 ========= - @Schema(description = "SKU 数组", example = "1") + @Schema(description = "SKU 数组") private List skus; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java new file mode 100644 index 000000000..56ae45deb --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.product.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + + +import java.time.LocalDateTime; + +/** + * 商品 Spu Excel 导出 VO TODO 暂定 + * + * @author HUIHUI + */ +@Data +public class ProductSpuExcelVO { + @ExcelProperty("商品编号") + private Long id; + + @ExcelProperty("商品名称") + private String name; + + @ExcelProperty("关键字") + private String keyword; + + @ExcelProperty("商品简介") + private String introduction; + + @ExcelProperty("商品详情") + private String description; + + @ExcelProperty("条形码") + private String barCode; + + @ExcelProperty("商品分类编号") + private Long categoryId; + + @ExcelProperty("商品品牌编号") + private Long brandId; + + @ExcelProperty("商品封面图") + private String picUrl; + + @ExcelProperty("商品轮播图地址") + private String sliderPicUrls; + + @ExcelProperty("商品视频") + private String videoUrl; + + @ExcelProperty(value = "商品单位", converter = DictConvert.class) + @DictFormat(DictTypeConstants.PRODUCT_UNIT) + private Integer unit; + + @ExcelProperty("排序字段") + private Integer sort; + + @ExcelProperty(value = "商品状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.PRODUCT_SPU_STATUS) + private Integer status; + + @ExcelProperty("规格类型") + private Boolean specType; + + @ExcelProperty("商品价格") + private Integer price; + + @ExcelProperty("市场价") + private Integer marketPrice; + + @ExcelProperty("成本价") + private Integer costPrice; + + @ExcelProperty("库存") + private Integer stock; + + @ExcelProperty("物流配置模板编号") + private Long deliveryTemplateId; + + @ExcelProperty("是否热卖推荐") + private Boolean recommendHot; + + @ExcelProperty("是否优惠推荐") + private Boolean recommendBenefit; + + @ExcelProperty("是否精品推荐") + private Boolean recommendBest; + + @ExcelProperty("是否新品推荐") + private Boolean recommendNew; + + @ExcelProperty("是否优品推荐") + private Boolean recommendGood; + + @ExcelProperty("赠送积分") + private Integer giveIntegral; + + @ExcelProperty("赠送的优惠劵编号的数组") + private String giveCouponTemplateIds; + + @ExcelProperty("分销类型") + private Boolean subCommissionType; + + @ExcelProperty("活动显示排序") + private String activityOrders; + + @ExcelProperty("商品销量") + private Integer salesCount; + + @ExcelProperty("虚拟销量") + private Integer virtualSalesCount; + + @ExcelProperty("商品点击量") + private Integer browseCount; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java new file mode 100644 index 000000000..4fe387167 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProductSpuExportReqVO { + @Schema(description = "商品名称", example = "yutou") + private String name; + + @Schema(description = "前端请求的tab类型", example = "1") + @InEnum(ProductSpuPageTabEnum.class) + private Integer tabType; + + @Schema(description = "商品分类编号") + private Long categoryId; + + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 9c3b51e21..3f0ad57a8 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -1,16 +1,24 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +/** + * 商品 SPU 分页 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @@ -20,10 +28,13 @@ public class ProductSpuPageReqVO extends PageParam { @Schema(description = "商品名称", example = "yutou") private String name; - // TODO @puhui999:加下 @InEnum 校验 @Schema(description = "前端请求的tab类型", example = "1") + @InEnum(ProductSpuPageTabEnum.class) private Integer tabType; + @Schema(description = "商品分类编号") + private Long categoryId; + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java deleted file mode 100644 index 83933ebdb..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageRespVO.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @puhui999:可以直接继承 ProductSpuRespVO 么?一般情况下,多返回一些字段问题不大的;另外,是不是使用 ProductSpuRespVO 替代 -@Schema(description = "管理后台 - 商品 SPU 分页 response VO") -@Data -public class ProductSpuPageRespVO { - - @Schema(description = "spuId", example = "1") - private Long id; - @Schema(description = "商品封面图", example = "1") - private String picUrl; - @Schema(description = "商品名称", example = "1") - private String name; - @Schema(description = "商品价格", example = "1") - private Integer price; - @Schema(description = "商品销量", example = "1") - private Integer salesCount; - @Schema(description = "商品排序", example = "1") - private Integer stock; - @Schema(description = "商品封面图", example = "1") - private Integer sort; - @Schema(description = "商品创建时间", example = "1") - private LocalDateTime createTime; - @Schema(description = "商品状态", example = "1") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index d550cb0c2..4780b2509 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -7,16 +8,39 @@ import lombok.ToString; import java.time.LocalDateTime; +/** + * 商品 SPU Response VO + * TODO 移除ProductSpuPageRespVO相关应用跟换为ProductSpuRespVO已继承ProductSpuBaseVO 补全表格展示所需属性 + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuRespVO extends ProductSpuBaseVO { - @Schema(description = "主键", required = true, example = "1") + @Schema(description = "spuId") private Long id; - @Schema(description = "创建时间") + @Schema(description = "商品价格") + private Integer price; + + @Schema(description = "商品销量") + private Integer salesCount; + + @Schema(description = "市场价,单位使用:分") + private Integer marketPrice; + + @Schema(description = "成本价,单位使用:分") + private Integer costPrice; + + @Schema(description = "商品库存") + private Integer stock; + + @Schema(description = "商品创建时间") private LocalDateTime createTime; + @Schema(description = "商品状态") + private Integer status; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java index 9cc7bf169..65bb2cbaf 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -1,26 +1,48 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +/** + * 商品 SPU 精简 Response VO + * TODO 商品 SPU 精简 VO 暂时没有使用到,用到的时候再按需添加\修改属性 + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU 精简 Response VO") @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { +public class ProductSpuSimpleRespVO { - @Schema(description = "主键", required = true, example = "1") + @Schema(description = "主键") private Long id; - @Schema(description = "商品名称", required = true, example = "芋道") + @Schema(description = "商品名称") private String name; - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; + @Schema(description = "商品价格,单位使用:分") + private Integer price; - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; + @Schema(description = "商品市场价,单位使用:分") + private Integer marketPrice; + + @Schema(description = "商品成本价,单位使用:分") + private Integer costPrice; + + @Schema(description = "商品库存") + private Integer stock; + + // ========== 统计相关字段 ========= + + @Schema(description = "商品销量") + private Integer salesCount; + + @Schema(description = "商品虚拟销量") + private Integer virtualSalesCount; + + @Schema(description = "商品浏览量") + private Integer browseCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 6ea84fb9e..3788d2fa0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -8,8 +11,14 @@ import lombok.ToString; import javax.validation.Valid; import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; import java.util.List; +/** + * 商品 SPU 更新 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU 更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @@ -20,9 +29,19 @@ public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { @NotNull(message = "商品编号不能为空") private Long id; - /** - * SKU 数组 - */ + @Schema(description = "商品销量") + private Integer salesCount; + + @Schema(description = "浏览量") + private Integer browseCount; + + @Schema(description = "商品状态") + @InEnum(ProductSpuStatusEnum.class) + private Integer status; + + // ========== SKU 相关字段 ========= + + @Schema(description = "SKU 数组") @Valid private List skus; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java index 9838dd610..e5a52419e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -10,6 +12,11 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.List; +/** + * 商品 SPU Status 更新 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO") @Data public class ProductSpuUpdateStatusReqVO{ @@ -20,7 +27,7 @@ public class ProductSpuUpdateStatusReqVO{ @Schema(description = "商品状态", required = true, example = "1") @NotNull(message = "商品状态不能为空") + @InEnum(ProductSpuStatusEnum.class) private Integer status; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java index a318e9128..a3d017799 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.convert.brand; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandRespVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandSimpleRespVO; import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import org.mapstruct.Mapper; @@ -25,7 +26,7 @@ public interface ProductBrandConvert { ProductBrandDO convert(ProductBrandUpdateReqVO bean); ProductBrandRespVO convert(ProductBrandDO bean); - + List convertList1(List list); List convertList(List list); PageResult convertPage(PageResult page); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 79091974b..717152c95 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.product.convert.spu; +import java.time.LocalDateTime; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; @@ -10,6 +12,7 @@ import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProdu import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; @@ -19,6 +22,9 @@ import org.mapstruct.factory.Mappers; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; import static cn.hutool.core.util.ObjectUtil.defaultIfNull; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; @@ -34,46 +40,63 @@ public interface ProductSpuConvert { ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); ProductSpuDO convert(ProductSpuCreateReqVO bean); - // TODO 还是使用convert,重命名改动太多 + ProductSpuDO convert(ProductSpuUpdateReqVO bean); List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); List convertList2(List list); List convertList02(List list); - - // TODO @puhui999:是不是可以删除啦 - default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, - List propertyValues) { - ProductSpuDetailRespVO spuVO = convert03(spu); - spuVO.setSkus(convertList04(skus)); - // 处理商品属性 - Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); - for (int i = 0; i < skus.size(); i++) { - List properties = skus.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - ProductSkuRespVO sku = spuVO.getSkus().get(i); - sku.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); - if (propertyValue == null) { - return; - } - //sku.getProperties().add(convert04(propertyValue)); TODO 需要重写 - }); - } - return spuVO; + default List convertList03(List list){ + ArrayList spuExcelVOs = new ArrayList<>(); + list.forEach((spu)->{ + ProductSpuExcelVO spuExcelVO = new ProductSpuExcelVO(); + spuExcelVO.setId(spu.getId()); + spuExcelVO.setName(spu.getName()); + spuExcelVO.setKeyword(spu.getKeyword()); + spuExcelVO.setIntroduction(spu.getIntroduction()); + spuExcelVO.setDescription(spu.getDescription()); + spuExcelVO.setBarCode(spu.getBarCode()); + spuExcelVO.setCategoryId(spu.getCategoryId()); + spuExcelVO.setBrandId(spu.getBrandId()); + spuExcelVO.setPicUrl(spu.getPicUrl()); + spuExcelVO.setSliderPicUrls(StrUtil.toString(spu.getSliderPicUrls())); + spuExcelVO.setVideoUrl(spu.getVideoUrl()); + spuExcelVO.setUnit(spu.getUnit()); + spuExcelVO.setSort(spu.getSort()); + spuExcelVO.setStatus(spu.getStatus()); + spuExcelVO.setSpecType(spu.getSpecType()); + spuExcelVO.setPrice(spu.getPrice()/100); + spuExcelVO.setMarketPrice(spu.getMarketPrice()/100); + spuExcelVO.setCostPrice(spu.getCostPrice()/100); + spuExcelVO.setStock(spu.getStock()); + spuExcelVO.setDeliveryTemplateId(spu.getDeliveryTemplateId()); + spuExcelVO.setRecommendHot(spu.getRecommendHot()); + spuExcelVO.setRecommendBenefit(spu.getRecommendBenefit()); + spuExcelVO.setRecommendBest(spu.getRecommendBest()); + spuExcelVO.setRecommendNew(spu.getRecommendNew()); + spuExcelVO.setRecommendGood(spu.getRecommendGood()); + spuExcelVO.setGiveIntegral(spu.getGiveIntegral()); + spuExcelVO.setGiveCouponTemplateIds(StrUtil.toString(spu.getGiveCouponTemplateIds())); // TODO 暂定 + spuExcelVO.setSubCommissionType(spu.getSubCommissionType()); + spuExcelVO.setActivityOrders(StrUtil.toString(spu.getActivityOrders())); // TODO 暂定 + spuExcelVO.setSalesCount(spu.getSalesCount()); + spuExcelVO.setVirtualSalesCount(spu.getVirtualSalesCount()); + spuExcelVO.setBrowseCount(spu.getBrowseCount()); + spuExcelVO.setCreateTime(spu.getCreateTime()); + spuExcelVOs.add(spuExcelVO); + }); + return spuExcelVOs; } ProductSpuDetailRespVO convert03(ProductSpuDO spu); + List convertList04(List skus); + ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); // ========== 用户 App 相关 ========== @@ -84,6 +107,7 @@ public interface ProductSpuConvert { // 然后进行转换 return convertPageForGetSpuPage0(page); } + PageResult convertPageForGetSpuPage0(PageResult page); default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus, @@ -111,8 +135,32 @@ public interface ProductSpuConvert { } return spuVO; } + AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu); + List convertListForGetSpuDetail(List skus); + AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); + default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus, Function, List> func) { + ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu); + if (CollUtil.isNotEmpty(skus)) { + List skuVOs = ProductSkuConvert.INSTANCE.convertList(skus); + // fix:统一模型,即使是单规格,也查询下,如若Properties为空报错则为单属性不做处理 + try { + // 获取所有的属性值 id + Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()) + .map(ProductSkuDO.Property::getValueId) + .collect(Collectors.toSet()); + List valueDetailList = func.apply(valueIds); + Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); + // 设置属性值名称 + skuVOs.stream().flatMap(p -> p.getProperties().stream()).forEach(item -> item.setValueName(stringMap.get(item.getValueId()))); + } catch (Exception ignored) { + } + productSpuDetailRespVO.setSkus(skuVOs); + } + return productSpuDetailRespVO; + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index 3756ea818..b8444a31f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -19,12 +19,6 @@ import lombok.*; @NoArgsConstructor @AllArgsConstructor public class ProductCategoryDO extends BaseDO { - - /** - * 父分类编号 - 根分类 - */ - public static final Long PARENT_ID_NULL = 0L; - /** * 分类编号 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index 6da6af9fe..dfe666e1f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -19,7 +20,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? +public class ProductPropertyDO extends BaseDO { /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index be64373a5..80756bc5a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -20,7 +21,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductPropertyValueDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? +public class ProductPropertyValueDO extends BaseDO { /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 4e6c7f8a1..6c3a9a020 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.sku; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -27,7 +27,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductSkuDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了? +public class ProductSkuDO extends BaseDO { /** * 商品 SKU 编号,自增 @@ -105,33 +105,29 @@ public class ProductSkuDO extends TenantBaseDO { // TODO @puhui999:这里是 /** * 属性编号 - * * 关联 {@link ProductPropertyDO#getId()} */ private Long propertyId; - ///** - // * 属性名字 - // * - // * 冗余 {@link ProductPropertyDO#getName()} - // * - // * 注意:每次属性名字发生变化时,需要更新该冗余 - // */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀? - //private String propertyName; + /** + * 属性名字 + * 冗余 {@link ProductPropertyDO#getName()} + * + * 注意:每次属性名字发生变化时,需要更新该冗余 + */ + private String propertyName; /** * 属性值编号 - * * 关联 {@link ProductPropertyValueDO#getId()} */ private Long valueId; - ///** - // * 属性值名字 - // * - // * 冗余 {@link ProductPropertyValueDO#getName()} - // * - // * 注意:每次属性值名字发生变化时,需要更新该冗余 - // */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀? - //private String valueName; + /** + * 属性值名字 + * 冗余 {@link ProductPropertyValueDO#getName()} + * + * 注意:每次属性值名字发生变化时,需要更新该冗余 + */ + private String valueName; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index e2ed9f2a1..8c8dcbc9f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -29,7 +29,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class ProductSpuDO extends TenantBaseDO { +public class ProductSpuDO extends BaseDO { /** * 商品 SPU 编号,自增 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java index a62df7dc8..cc66780a4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java @@ -31,4 +31,7 @@ public interface ProductBrandMapper extends BaseMapperX { return selectOne(ProductBrandDO::getName, name); } + default List selectListByStatus(Integer status){ + return selectList(ProductBrandDO::getStatus,status); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index ae4389eb2..e7385b588 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -1,40 +1,56 @@ package cn.iocoder.yudao.module.product.dal.mysql.spu; import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.ProductConstants; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import org.apache.ibatis.annotations.Mapper; +import org.apache.poi.ss.formula.functions.T; +import java.util.List; import java.util.Objects; import java.util.Set; @Mapper public interface ProductSpuMapper extends BaseMapperX { + /** + * 获取 商品 SPU 分页列表数据 + * + * @param reqVO 分页请求参数 + * @return 商品 SPU 分页列表数据 + */ default PageResult selectPage(ProductSpuPageReqVO reqVO) { - // TODO @puhui999:多个 tab,写 if else 去补条件,可阅读性会好点哈 - return selectPage(reqVO, new LambdaQueryWrapperX() - // 商品名称 + Integer tabType = reqVO.getTabType(); + LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) + .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime()) - // 出售中商品 - .eq(ProductSpuTabTypeEnum.FOR_SALE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.ENABLE.getStatus()) - // 仓储中商品 - .eq(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.DISABLE.getStatus()) - // 已售空商品 - .eq(ProductSpuTabTypeEnum.SOLD_OUT.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,0) - // TODO @phuui999:警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 - .le(ProductSpuTabTypeEnum.ALERT_STOCK.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,10) - // 回收站 - .eq(ProductSpuTabTypeEnum.RECYCLE_BIN.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.RECYCLE.getStatus()) - .orderByDesc(ProductSpuDO::getSort)); + .orderByDesc(ProductSpuDO::getSort); + validateTabType(tabType, queryWrapper); + return selectPage(reqVO, queryWrapper); + } + + /** + * 获取库存小于value且状态不等于status的的个数 + */ + default Long selectCountByStockAndStatus() { + LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); + queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) + // 如果库存触发警戒库存且状态为回收站的话则不计入触发警戒库存的个数 + .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + return selectCount(queryWrapper); } /** @@ -42,10 +58,12 @@ public interface ProductSpuMapper extends BaseMapperX { */ default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Set categoryIds) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() - .likeIfPresent(ProductSpuDO::getName, pageReqVO.getKeyword()) // 关键字匹配,目前只匹配商品名 - .inIfPresent(ProductSpuDO::getCategoryId, categoryIds); // 分类 - query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()) // 上架状态 - .gt(ProductSpuDO::getStock, 0); // 有库存 + // 关键字匹配,目前只匹配商品名 + .likeIfPresent(ProductSpuDO::getName, pageReqVO.getKeyword()) + // 分类 + .inIfPresent(ProductSpuDO::getCategoryId, categoryIds); + // 上架状态 且有库存 + query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()).gt(ProductSpuDO::getStock, 0); // 推荐类型的过滤条件 if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { query.eq(ProductSpuDO::getRecommendHot, true); @@ -66,14 +84,60 @@ public interface ProductSpuMapper extends BaseMapperX { /** * 更新商品 SPU 库存 * - * @param id 商品 SPU 编号 + * @param id 商品 SPU 编号 * @param incrCount 增加的库存数量 */ default void updateStock(Long id, Integer incrCount) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() - .setSql(" total_stock = total_stock +" + incrCount) // 负数,所以使用 + 号 + // 负数,所以使用 + 号 + .setSql(" stock = stock +" + incrCount) .eq(ProductSpuDO::getId, id); update(null, updateWrapper); } + /** + * 获得 Spu 列表 + * + * @param reqVO 查询条件 + * @return Spu 列表 + */ + default List selectList(ProductSpuExportReqVO reqVO){ + Integer tabType = reqVO.getTabType(); + LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); + queryWrapper.eqIfPresent(ProductSpuDO::getName,reqVO.getName()); + queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId,reqVO.getCategoryId()); + queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime,reqVO.getCreateTime()); + validateTabType(tabType, queryWrapper); + return selectList(queryWrapper); + } + + /** + * 验证选项卡类型构建条件 + * + * @param tabType 标签类型 + * @param queryWrapper 查询条件 + */ + static void validateTabType(Integer tabType, LambdaQueryWrapperX queryWrapper) { + if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) { + // 出售中商品 + queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); + } + if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) { + // 仓储中商品 + queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); + } + if (ObjectUtil.equals(ProductSpuPageTabEnum.SOLD_OUT.getType(), tabType)) { + // 已售空商品 + queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0); + } + if (ObjectUtil.equals(ProductSpuPageTabEnum.ALERT_STOCK.getType(), tabType)) { + queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) + // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示 + .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + } + if (ObjectUtil.equals(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), tabType)) { + // 回收站 + queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); + } + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java index a90ec8a87..aa401ed07 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java @@ -76,4 +76,11 @@ public interface ProductBrandService { */ PageResult getBrandPage(ProductBrandPageReqVO pageReqVO); + /** + * 获取指定状态的品牌列表 + * + * @param status 状态 + * @return 返回品牌列表 + */ + List getBrandListByStatus(Integer status); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java index c7a3e5198..b97123f6a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java @@ -114,4 +114,9 @@ public class ProductBrandServiceImpl implements ProductBrandService { return brandMapper.selectPage(pageReqVO); } + @Override + public List getBrandListByStatus(Integer status) { + return brandMapper.selectListByStatus(status); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 02bde434d..ff1b6da01 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import cn.iocoder.yudao.module.product.enums.ProductConstants; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -68,7 +69,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { private void validateParentProductCategory(Long id) { // 如果是根分类,无需验证 - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) { return; } // 父分类不存在 @@ -77,7 +78,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { throw exception(CATEGORY_PARENT_NOT_EXISTS); } // 父分类不能是二级分类 - if (!Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { + if (!Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) { throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL); } } @@ -107,15 +108,16 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @Override public Integer getCategoryLevel(Long id) { - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) { return 0; } int level = 1; - for (int i = 0; i < 100; i++) { + // fix: 循环次数不确定改为while循环 + while (true){ ProductCategoryDO category = productCategoryMapper.selectById(id); // 如果没有父节点,break 结束 if (category == null - || Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { + || Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) { break; } // 继续递归父节点 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 61dc3a117..a03c94240 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -176,7 +176,6 @@ public class ProductSkuServiceImpl implements ProductSkuService { Long existsSkuId = existsSkuMap.remove(propertiesKey); if (existsSkuId != null) { sku.setId(existsSkuId); - // TODO 那spuId岂不是为null了 updateSkus.add(sku); return; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 4b0444018..a5dc3b821 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -74,6 +74,14 @@ public interface ProductSpuService { */ List getSpuList(); + /** + * 获得所有商品 SPU 列表 + * + * @param reqVO 导出条件 + * @return 商品 SPU 列表 + */ + List getSpuList(ProductSpuExportReqVO reqVO); + /** * 获得商品 SPU 分页,提供给挂你兰后台使用 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index fd1cac880..db317c1a6 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -10,11 +10,13 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import cn.iocoder.yudao.module.product.enums.ProductConstants; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; @@ -31,8 +33,7 @@ import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; /** * 商品 SPU Service 实现类 @@ -59,11 +60,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override @Transactional(rollbackFor = Exception.class) public Long createSpu(ProductSpuCreateReqVO createReqVO) { - // 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别; - //validateCategory(createReqVO.getCategoryId()); - // 校验品牌 TODO puhui999:暂不校验,前端没有做品牌选择;芋艿:可以加下哈 - //brandService.validateProductBrand(createReqVO.getBrandId()); - + // 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别;fix + validateCategory(createReqVO.getCategoryId()); + brandService.validateProductBrand(createReqVO.getBrandId()); List skuSaveReqList = createReqVO.getSkus(); // 校验 SKU productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); @@ -84,10 +83,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void updateSpu(ProductSpuUpdateReqVO updateReqVO) { // 校验 SPU 是否存在 validateSpuExists(updateReqVO.getId()); - // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点 - //validateCategory(updateReqVO.getCategoryId()); - // 校验品牌 TODO 暂不校验,前端没有做品牌选择 - //brandService.validateProductBrand(updateReqVO.getBrandId()); + // 校验分类 + validateCategory(updateReqVO.getCategoryId()); + // 校验品牌 + brandService.validateProductBrand(updateReqVO.getBrandId()); // 校验SKU List skuSaveReqList = updateReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); @@ -103,7 +102,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { * 基于 SKU 的信息,初始化 SPU 的信息 * 主要是计数相关的字段,例如说市场价、最大最小价、库存等等 * - * @param spu 商品 SPU + * @param spu 商品 SPU * @param skus 商品 SKU 数组 */ private void initSpuFromSkus(ProductSpuDO spu, List skus) { @@ -119,13 +118,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { spu.setCostPrice(vo.getCostPrice()); // sku单价最低的商品的条形码 spu.setBarCode(vo.getBarCode()); - // 默认状态为上架 - spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - // TODO 默认商品销量和浏览量为零 - spu.setSalesCount(0); - spu.setBrowseCount(0); // skus库存总数 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + // 若是 spu 已有状态则不处理 + if (spu.getStatus() == null) { + // 默认状态为上架 + spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + // 默认商品销量 + spu.setSalesCount(ProductConstants.SALES_COUNT); + // 默认商品浏览量 + spu.setBrowseCount(ProductConstants.BROWSE_COUNT); + } } /** @@ -136,7 +139,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { private void validateCategory(Long id) { categoryService.validateCategory(id); // 校验层级 - if (categoryService.getCategoryLevel(id) != 3) { + if (categoryService.getCategoryLevel(id) != ProductConstants.CATEGORY_LEVEL) { throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR); } } @@ -146,6 +149,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void deleteSpu(Long id) { // 校验存在 validateSpuExists(id); + // 校验商品状态不是回收站不能删除 + validateSpuStatus(id); // 删除 SPU productSpuMapper.deleteById(id); // 删除关联的 SKU @@ -158,6 +163,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { } } + /** + * 验证 SPU 状态是否为回收站 + * + * @param id id + */ + private void validateSpuStatus(Long id) { + ProductSpuDO spuDO = productSpuMapper.selectById(id); + // 判断 SPU 状态是否为回收站 + if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) { + throw exception(SPU_NOT_RECYCLE); + } + } + @Override public ProductSpuDO getSpu(Long id) { return productSpuMapper.selectById(id); @@ -173,6 +191,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { return productSpuMapper.selectList(); } + @Override + public List getSpuList(ProductSpuExportReqVO reqVO) { + return productSpuMapper.selectList(reqVO); + } + @Override public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { return productSpuMapper.selectPage(pageReqVO); @@ -190,7 +213,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); } - // TODO @puhui999:Service 尽量不做一些跟 VO 相关的拼接逻辑,目的是让 Service 更加简洁一点哈。 @Override public ProductSpuDetailRespVO getSpuDetail(Long id) { // 获得商品 SPU @@ -198,28 +220,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { if (spu == null) { throw exception(SPU_NOT_EXISTS); } - ProductSpuDetailRespVO productSpuDetailRespVO = ProductSpuConvert.INSTANCE.convert03(spu); // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); - if (CollUtil.isNotEmpty(skus)){ - // TODO @puhui999:skuVOs 更简洁一点。然后大小写要注释哈。RespVOs;因为 VO 是缩写,s 是复数 - List skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus); - // 非多规格,不需要处理 - // TODO @puhui999:统一模型,即使是单规格,也查询下,问题不大的 - if (ObjectUtil.equal(productSpuDetailRespVO.getSpecType(), true)) { - // 获取所有的属性值 id - Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()) - .map(ProductSkuDO.Property::getValueId) - .collect(Collectors.toSet()); - List valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds); - // TODO @puhui999:拼接的逻辑,最好查询好后,丢到 convert 里面统一处理;这样 Service or Controller 也可以更简洁;原则上,Controller 去组合;Service 写逻辑;Convert 转换 - Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); - // 设置属性值名称 - skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId()))); - } - productSpuDetailRespVO.setSkus(skuRespVoS); - } - return productSpuDetailRespVO; + return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus, productPropertyValueService::getPropertyValueDetailList); } @Override @@ -235,21 +238,21 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public Map getTabsCount() { - // TODO @puhui999:map =》counts;尽量避免出现 map 这种命名,无命名含义哈 - Map map = new HashMap<>(); + // TODO @puhui999:map =》;尽量避免出现 map 这种命名,无命名含义哈 fix + Map counts = new HashMap<>(ProductConstants.SPU_TAB_COUNTS); // 查询销售中的商品数量 - map.put(ProductSpuTabTypeEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); + counts.put(ProductSpuPageTabEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); // 查询仓库中的商品数量 - map.put(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); + counts.put(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); // 查询售空的商品数量 - map.put(ProductSpuTabTypeEnum.SOLD_OUT.getType(),productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); - // 查询触发警戒库存的商品数量 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 - // TODO @puhui999:要有空格;, productSpuMapper - // TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈 - map.put(ProductSpuTabTypeEnum.ALERT_STOCK.getType(),productSpuMapper.selectCount(new LambdaQueryWrapperX().le(ProductSpuDO::getStock, 10))); + counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); + // 查询触发警戒库存的商品数量 + // TODO @puhui999:要有空格;, productSpuMapper fix + // TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈 fix:调整为在 productSpuMapper 中书写逻辑 + counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCountByStockAndStatus()); // 查询回收站中的商品数量 - map.put(ProductSpuTabTypeEnum.RECYCLE_BIN.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); - return map; + counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + return counts; } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 2136e1102..3205c4d02 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -18,8 +18,9 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL; + import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ProductConstants.PARENT_ID_NULL; import static org.junit.jupiter.api.Assertions.*; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index f0bf30014..8c5a629af 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.service.sku; +import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.util.AssertUtils; @@ -49,23 +50,26 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { @MockBean private ProductPropertyValueService productPropertyValueService; + public Long generateId() { + return RandomUtil.randomLong(100000, 999999); + } + + public int generaInt(){return RandomUtil.randomInt(1,9999999);} + @Test public void testUpdateSkuList() { // mock 数据 ProductSkuDO sku01 = randomPojo(ProductSkuDO.class, o -> { // 测试更新 o.setSpuId(1L); - //o.setProperties(singletonList(new ProductSkuDO.Property( - // 10L, "颜色", 20L, "红色"))); TODO 新增字段已注释 o.setProperties(singletonList(new ProductSkuDO.Property( - 10L, 20L))); + 10L, "颜色", 20L, "红色"))); }); productSkuMapper.insert(sku01); ProductSkuDO sku02 = randomPojo(ProductSkuDO.class, o -> { // 测试删除 o.setSpuId(1L); - //o.setProperties(singletonList(new ProductSkuDO.Property( - // 10L, "颜色", 30L, "蓝色"))); TODO 新增字段已注释 o.setProperties(singletonList(new ProductSkuDO.Property( - 10L, 30L))); + 10L, "颜色", 30L, "蓝色"))); + }); productSkuMapper.insert(sku02); // 准备参数 @@ -73,10 +77,12 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { String spuName = "测试商品"; List skus = Arrays.asList( randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试更新 - o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 20L))); + o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property( + 10L, "颜色", 20L, "红色"))); }), randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试新增 - o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 40L))); + o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property( + 10L, "颜色", 20L, "红色"))); }) ); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index b6f150a11..641bac5c8 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -6,15 +6,16 @@ import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl; import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl; @@ -22,6 +23,7 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl; import com.google.common.collect.Lists; +import org.apache.poi.ss.formula.functions.T; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -30,14 +32,19 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static org.assertj.core.util.Lists.newArrayList; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; // TODO @芋艿:review 下单元测试 @@ -47,7 +54,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; * @author 芋道源码 */ @Import(ProductSpuServiceImpl.class) -@Disabled // TODO 芋艿:临时去掉 public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Resource @@ -75,10 +81,35 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { return RandomUtil.randomLong(100000, 999999); } + public int generaInt(){return RandomUtil.randomInt(1,9999999);} + @Test public void testCreateSpu_success() { // 准备参数 - ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class); + ProductSkuCreateOrUpdateReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuCreateOrUpdateReqVO.class,o->{ + // 限制范围为正整数 + o.setCostPrice(generaInt()); + o.setPrice(generaInt()); + o.setMarketPrice(generaInt()); + o.setStock(generaInt()); + o.setWarnStock(10); + o.setSubCommissionFirstPrice(generaInt()); + o.setSubCommissionSecondPrice(generaInt()); + // 限制分数为两位数 + o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); + o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); + }); + ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setSkus(newArrayList(skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO)); + }); + when(categoryService.getCategoryLevel(eq(createReqVO.getCategoryId()))).thenReturn(2); Long spu = productSpuService.createSpu(createReqVO); ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); assertPojoEquals(createReqVO, productSpuDO); @@ -87,12 +118,55 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test public void testUpdateSpu_success() { // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + }); productSpuMapper.insert(createReqVO); // 准备参数 + ProductSkuCreateOrUpdateReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuCreateOrUpdateReqVO.class,o->{ + // 限制范围为正整数 + o.setCostPrice(generaInt()); + o.setPrice(generaInt()); + o.setMarketPrice(generaInt()); + o.setStock(generaInt()); + o.setWarnStock(10); + o.setSubCommissionFirstPrice(generaInt()); + o.setSubCommissionSecondPrice(generaInt()); + // 限制分数为两位数 + o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); + o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); + }); + // 准备参数 ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { o.setId(createReqVO.getId()); // 设置更新的 ID + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + o.setStatus(0); + o.setSkus(newArrayList(skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO)); }); + when(categoryService.getCategoryLevel(eq(reqVO.getCategoryId()))).thenReturn(2); // 调用 productSpuService.updateSpu(reqVO); // 校验是否更新正确 @@ -110,7 +184,24 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test void deleteSpu() { // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + o.setStatus(-1); // 加入回收站才可删除 + }); productSpuMapper.insert(createReqVO); // 调用 @@ -122,7 +213,23 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test void getSpu() { // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + }); productSpuMapper.insert(createReqVO); ProductSpuDO spu = productSpuService.getSpu(createReqVO.getId()); @@ -132,19 +239,86 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test void getSpuList() { // 准备参数 - ArrayList createReqVO = Lists.newArrayList(randomPojo(ProductSpuDO.class), randomPojo(ProductSpuDO.class)); - productSpuMapper.insertBatch(createReqVO); + ArrayList createReqVOs = Lists.newArrayList(randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + }), randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + })); + productSpuMapper.insertBatch(createReqVOs); // 调用 - List spuList = productSpuService.getSpuList(createReqVO.stream().map(ProductSpuDO::getId).collect(Collectors.toList())); - Assertions.assertIterableEquals(createReqVO, spuList); + List spuList = productSpuService.getSpuList(createReqVOs.stream().map(ProductSpuDO::getId).collect(Collectors.toList())); + Assertions.assertIterableEquals(createReqVOs, spuList); } @Test void getSpuPage_alarmStock_empty() { + // 准备参数 + ArrayList createReqVOs = Lists.newArrayList(randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(11); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + }), randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(11); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + })); + productSpuMapper.insertBatch(createReqVOs); // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - //productSpuPageReqVO.setAlarmStock(true); + productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); @@ -155,76 +329,67 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @Test void getSpuPage_alarmStock() { - // mock 数据 - Long brandId = generateId(); - Long categoryId = generateId(); - String code = generateNo(); - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - //o.setTotalStock(500); - //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 - //o.setMaxPrice(50); - o.setMarketPrice(25); - o.setBrandId(brandId); - o.setCategoryId(categoryId); - //o.setClickCount(100); - //o.setCode(code); // TODO ProductSpuDO中已没有相关属性 - o.setDescription("测试商品"); - o.setSliderPicUrls(new ArrayList<>()); - o.setName("测试"); - o.setSalesCount(100); - //o.setSellPoint("超级加倍"); - //o.setShowStock(true); // TODO ProductSpuDO中已没有相关属性 - o.setVideoUrl(""); - }); - productSpuMapper.insert(createReqVO); - - //Set alarmStockSpuIds = SetUtils.asSet(createReqVO.getId()); TODO 查询接口已改变没有使用到这个变量 - - List productSpuDOS = Arrays.asList(randomPojo(ProductSkuDO.class, o -> { - o.setSpuId(createReqVO.getId()); - }), randomPojo(ProductSkuDO.class, o -> { - o.setSpuId(createReqVO.getId()); + ArrayList createReqVOs = Lists.newArrayList(randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(5); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + }), randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(9); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 })); - - Mockito.when(productSkuService.getSkuListByAlarmStock()).thenReturn(productSpuDOS); - + productSpuMapper.insertBatch(createReqVOs); // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - //productSpuPageReqVO.setAlarmStock(true); + productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO)); - Assertions.assertIterableEquals(result.getList(), spuPage.getList()); - assertEquals(spuPage.getTotal(), result.getTotal()); + assertEquals(createReqVOs.size(), spuPage.getTotal()); } @Test - void getSpuPage() { - // mock 数据 - Long brandId = generateId(); - Long categoryId = generateId(); - + void testGetSpuPage() { // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - //o.setTotalStock(1); - //o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性 - //o.setMaxPrice(1); - o.setMarketPrice(1); - o.setBrandId(brandId); - o.setSpecType(false); - o.setCategoryId(categoryId); - //o.setClickCount(1); // TODO ProductSpuDO中已没有相关属性 - //o.setCode(generateNo()); - o.setDescription("测试商品"); - o.setSliderPicUrls(new ArrayList<>()); - o.setName("测试"); - o.setSalesCount(1); - //o.setSellPoint("卖点"); - //o.setShowStock(true); // TODO ProductSpuDO中已没有相关属性 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class,o->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 }); // 准备参数 @@ -241,45 +406,21 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - // TODO 已暂时没有相关属性,等用到时再添加 - //productSpuPageReqVO.setAlarmStock(false); - //productSpuPageReqVO.setBrandId(brandId); - //productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - //productSpuPageReqVO.setCategoryId(categoryId); + // 查询条件 按需打开 + //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); + //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.RECYCLE_BIN.getType()); + //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.FOR_SALE.getType()); + //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.IN_WAREHOUSE.getType()); + //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.SOLD_OUT.getType()); + //productSpuPageReqVO.setName(createReqVO.getName()); + //productSpuPageReqVO.setCategoryId(createReqVO.getCategoryId()); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO)); - assertEquals(result, spuPage); + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO)); + assertEquals(result.getTotal(), spuPage.getTotal()); } - @Test - void testGetSpuPage() { -// 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> { - o.setCategoryId(2L); - }); - productSpuMapper.insert(createReqVO); - - // 调用 - AppProductSpuPageReqVO appSpuPageReqVO = new AppProductSpuPageReqVO(); - appSpuPageReqVO.setCategoryId(2L); - -// PageResult spuPage = productSpuService.getSpuPage(appSpuPageReqVO); -// -// PageResult result = productSpuMapper.selectPage( -// ProductSpuConvert.INSTANCE.convert(appSpuPageReqVO)); -// -// List collect = result.getList() -// .stream() -// .map(ProductSpuConvert.INSTANCE::convertAppResp) -// .collect(Collectors.toList()); -// -// Assertions.assertIterableEquals(collect, spuPage.getList()); -// assertEquals(spuPage.getTotal(), result.getTotal()); - } - - /** * 生成笛卡尔积 * @@ -316,14 +457,48 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 准备参数 Map stockIncrCounts = MapUtil.builder(1L, 10).put(2L, -20).build(); // mock 方法(数据) // TODO ProductSpuDO中已没有相关属性 - //productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(1L).setTotalStock(20))); - //productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(2L).setTotalStock(30))); + productSpuMapper.insert(randomPojo(ProductSpuDO.class, o ->{ + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + o.setId(1L).setStock(20); + })); + productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> { + o.setCategoryId(generateId()); + o.setBrandId(generateId()); + o.setDeliveryTemplateId(generateId()); + o.setUnit(RandomUtil.randomInt(1,20)); // 限制商品单位范围 + o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setVirtualSalesCount(generaInt()); // 限制范围为正整数 + o.setActivityOrders(newArrayList(1,3,2,4,5)); // 活动排序 + o.setPrice(generaInt()); // 限制范围为正整数 + o.setMarketPrice(generaInt()); // 限制范围为正整数 + o.setCostPrice(generaInt()); // 限制范围为正整数 + o.setStock(generaInt()); // 限制范围为正整数 + o.setGiveIntegral(generaInt()); // 限制范围为正整数 + o.setSalesCount(generaInt()); // 限制范围为正整数 + o.setBrowseCount(generaInt()); // 限制范围为正整数 + o.setId(2L).setStock(30); + })); // 调用 productSpuService.updateSpuStock(stockIncrCounts); // 断言 // TODO ProductSpuDO中已没有相关属性 - //assertEquals(productSpuService.getSpu(1L).getTotalStock(), 30); - //assertEquals(productSpuService.getSpu(2L).getTotalStock(), 10); + assertEquals(productSpuService.getSpu(1L).getStock(), 30); + assertEquals(productSpuService.getSpu(2L).getStock(), 10); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql index 4ecb5f34d..e9616cd0d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql @@ -1,5 +1,7 @@ DELETE FROM "product_sku"; DELETE FROM "product_spu"; -DELETE FROM "product_brand"; DELETE FROM "product_category"; +DELETE FROM "product_brand"; +DELETE FROM "product_property"; +DELETE FROM "product_property_value"; DELETE FROM "product_comment"; diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 512175a9d..983aee740 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -1,88 +1,131 @@ CREATE TABLE IF NOT EXISTS `product_sku` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `id` bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, `spu_id` bigint NOT NULL COMMENT 'spu编号', - `spu_name` varchar DEFAULT NULL COMMENT '商品 SPU 名字', - `properties` varchar DEFAULT NULL COMMENT '规格值数组-json格式, [{propertId: , valueId: }, {propertId: , valueId: }]', - `price` int NOT NULL DEFAULT '-1' COMMENT '销售价格,单位:分', - `market_price` int DEFAULT NULL COMMENT '市场价', + `properties` varchar(512) DEFAULT NULL COMMENT '属性数组,JSON 格式', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位:分', + `market_price` int DEFAULT NULL COMMENT '市场价,单位:分', `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', - `pic_url` varchar NOT NULL COMMENT '图片地址', + `bar_code` varchar(64) DEFAULT NULL COMMENT 'SKU 的条形码', + `pic_url` varchar(256) NOT NULL COMMENT '图片地址', `stock` int DEFAULT NULL COMMENT '库存', - `warn_stock` int DEFAULT NULL COMMENT '预警库存', - `volume` double DEFAULT NULL COMMENT '商品体积', - `weight` double DEFAULT NULL COMMENT '商品重量', - `bar_code` varchar DEFAULT NULL COMMENT '条形码', - `status` tinyint DEFAULT NULL COMMENT '状态: 0-正常 1-禁用', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`) + `weight` double DEFAULT NULL COMMENT '商品重量,单位:kg 千克', + `volume` double DEFAULT NULL COMMENT '商品体积,单位:m^3 平米', + `sub_commission_first_price` int DEFAULT NULL COMMENT '一级分销的佣金,单位:分', + `sub_commission_second_price` int DEFAULT NULL COMMENT '二级分销的佣金,单位:分', + `sales_count` int DEFAULT NULL COMMENT '商品销量', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + PRIMARY KEY("id") ) COMMENT '商品sku'; - CREATE TABLE IF NOT EXISTS `product_spu` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - `brand_id` bigint DEFAULT NULL COMMENT '商品品牌编号', - `category_id` bigint NOT NULL COMMENT '分类id', - `spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格', - `code` varchar(128) DEFAULT NULL COMMENT '商品编码', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品 SPU 编号,自增', `name` varchar(128) NOT NULL COMMENT '商品名称', - `sell_point` varchar(128) DEFAULT NULL COMMENT '卖点', - `description` text COMMENT '描述', - `pic_urls` varchar(1024) DEFAULT '' COMMENT '商品轮播图地址数组,以逗号分隔最多上传15张', - `video_url` varchar(128) DEFAULT NULL COMMENT '商品视频', - `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分', - `min_price` int DEFAULT NULL COMMENT '最小价格,单位使用:分', - `max_price` int DEFAULT NULL COMMENT '最大价格,单位使用:分', - `total_stock` int NOT NULL DEFAULT '0' COMMENT '总库存', - `show_stock` int DEFAULT '0' COMMENT '是否展示库存', + `keyword` varchar(256) NOT NULL COMMENT '关键字', + `introduction` varchar(256) NOT NULL COMMENT '商品简介', + `description` text NOT NULL COMMENT '商品详情', + `bar_code` varchar(64) NOT NULL COMMENT '条形码', + `category_id` bigint NOT NULL COMMENT '商品分类编号', + `brand_id` int DEFAULT NULL COMMENT '商品品牌编号', + `pic_url` varchar(256) NOT NULL COMMENT '商品封面图', + `slider_pic_urls` varchar(2000) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张', + `video_url` varchar(256) DEFAULT NULL COMMENT '商品视频', + `unit` tinyint NOT NULL COMMENT '单位', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', + `status` tinyint NOT NULL COMMENT '商品状态: 0 上架(开启) 1 下架(禁用)-1 回收', + `spec_type` bit(1) NOT NULL COMMENT '规格类型:0 单规格 1 多规格', + `price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位使用:分', + `market_price` int NOT NULL COMMENT '市场价,单位使用:分', + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', + `stock` int NOT NULL DEFAULT '0' COMMENT '库存', + `delivery_template_id` bigint NOT NULL COMMENT '物流配置模板编号', + `recommend_hot` bit(1) NOT NULL COMMENT '是否热卖推荐: 0 默认 1 热卖', + `recommend_benefit` bit(1) NOT NULL COMMENT '是否优惠推荐: 0 默认 1 优选', + `recommend_best` bit(1) NOT NULL COMMENT '是否精品推荐: 0 默认 1 精品', + `recommend_new` bit(1) NOT NULL COMMENT '是否新品推荐: 0 默认 1 新品', + `recommend_good` bit(1) NOT NULL COMMENT '是否优品推荐', + `give_integral` int NOT NULL COMMENT '赠送积分', + `give_coupon_template_ids` varchar(512) DEFAULT '' COMMENT '赠送的优惠劵编号的数组', + `sub_commission_type` bit(1) NOT NULL COMMENT '分销类型', + `activity_orders` varchar(16) NOT NULL DEFAULT '' COMMENT '活动显示排序0=默认, 1=秒杀,2=砍价,3=拼团', `sales_count` int DEFAULT '0' COMMENT '商品销量', `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量', - `click_count` int DEFAULT '0' COMMENT '商品点击量', - `status` bit(1) DEFAULT NULL COMMENT '上下架状态: 0 上架(开启) 1 下架(禁用)-1 回收', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', -PRIMARY KEY (`id`) + `browse_count` int DEFAULT '0' COMMENT '商品点击量', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + PRIMARY KEY("id") ) COMMENT '商品spu'; CREATE TABLE IF NOT EXISTS `product_category` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', - `parent_id` bigint DEFAULT NULL COMMENT '父分类编号', - `name` varchar(128) NOT NULL COMMENT '分类名称', - `pic_url` varchar DEFAULT NULL COMMENT '分类图片', - `big_pic_url` varchar DEFAULT NULL COMMENT 'PC端分类图', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `status` bit(1) DEFAULT NULL COMMENT '状态', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`) + `parent_id` bigint NOT NULL COMMENT '父分类编号', + `name` varchar(255) NOT NULL COMMENT '分类名称', + `pic_url` varchar(255) NOT NULL COMMENT '移动端分类图', + `big_pic_url` varchar(255) DEFAULT NULL COMMENT 'PC 端分类图', + `sort` int DEFAULT '0' COMMENT '分类排序', + `status` tinyint NOT NULL COMMENT '开启状态', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + PRIMARY KEY("id") ) COMMENT '商品分类'; CREATE TABLE IF NOT EXISTS `product_brand` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号', - `name` varchar(128) NOT NULL COMMENT '品牌名称', - `pic_url` varchar DEFAULT NULL COMMENT '品牌图片', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `description` varchar(256) NOT NULL DEFAULT '0' COMMENT '品牌描述', - `status` bit(1) DEFAULT NULL COMMENT '状态', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`) + `name` varchar(255) NOT NULL COMMENT '品牌名称', + `pic_url` varchar(255) NOT NULL COMMENT '品牌图片', + `sort` int DEFAULT '0' COMMENT '品牌排序', + `description` varchar(1024) DEFAULT NULL COMMENT '品牌描述', + `status` tinyint NOT NULL COMMENT '状态', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + PRIMARY KEY("id") ) COMMENT '商品品牌'; +CREATE TABLE IF NOT EXISTS `product_property` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) DEFAULT NULL COMMENT '规格名称', + `status` tinyint DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY("id") +) COMMENT '规格名称'; + +CREATE TABLE IF NOT EXISTS `product_property_value` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `property_id` bigint DEFAULT NULL COMMENT '规格键id', + `name` varchar(128) DEFAULT NULL COMMENT '规格值名字', + `status` tinyint DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY("id") +) COMMENT '规格值'; + CREATE TABLE IF NOT EXISTS `product_comment` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评价编号', `user_id` bigint NOT NULL COMMENT ' 评价ID 用户编号', @@ -108,10 +151,11 @@ CREATE TABLE IF NOT EXISTS `product_comment` ( `additional_content` varchar(2000) COMMENT '追加评价内容', `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张', `additional_time` datetime COMMENT '追加评价时间', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', PRIMARY KEY (`id`) ) COMMENT '商品评价'; \ No newline at end of file From a70c7ca855bb340d92199d6bdbae19fb30355307 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 23 May 2023 11:59:48 +0800 Subject: [PATCH 056/232] =?UTF-8?q?fix:=E5=AE=8C=E5=96=84=20mall.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 99 ++++++++++++------- .../dal/dataobject/spu/ProductSpuDO.java | 2 +- 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index a57f05878..83853b22b 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -101,7 +101,7 @@ CREATE TABLE `member_address` ( -- Records of member_address -- ---------------------------- BEGIN; -INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `post_code`, `detail_address`, `defaulted`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 1, 'yunai', '15601691300', 610632, '200000', '芋道源码 233 号 666 室', b'1', '1', '2022-08-01 22:46:35', '1', '2022-08-01 22:46:35', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `post_code`, `detail_address`, `defaulted`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 1, 'yunai', '15601691300', 610632, '200000', '芋道源码 233 号 666 室', b'1', '1', '2022-08-01 22:46:35', '1', '2022-08-01 22:46:35', b'0', 1); COMMIT; -- ---------------------------- @@ -128,7 +128,7 @@ CREATE TABLE `product_brand` ( -- Records of product_brand -- ---------------------------- BEGIN; -INSERT INTO `product_brand` (`id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '苹果', 'http://test.yudao.iocoder.cn/e3726713fa56db5717c78c011762fcc7a251db12735c3581470638b8e1fa17e2.jpeg', 0, '是上市', 0, '1', '2022-07-30 22:12:18', '1', '2022-07-30 22:13:55', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_brand` (`id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '苹果', 'http://test.yudao.iocoder.cn/e3726713fa56db5717c78c011762fcc7a251db12735c3581470638b8e1fa17e2.jpeg', 0, '是上市', 0, '1', '2022-07-30 22:12:18', '1', '2022-07-30 22:13:55', b'0', 1); COMMIT; -- ---------------------------- @@ -139,24 +139,43 @@ CREATE TABLE `product_category` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', `parent_id` bigint NOT NULL COMMENT '父分类编号', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名称', - `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类图片', - `sort` int NULL DEFAULT 0 COMMENT '分类排序', - `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '分类描述', + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '移动端分类图', + `big_pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'PC 端分类图', + `sort` int DEFAULT '0' COMMENT '分类排序', `status` tinyint NOT NULL COMMENT '开启状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品分类'; +) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品分类'; -- ---------------------------- -- Records of product_category -- ---------------------------- BEGIN; -INSERT INTO `product_category` (`id`, `parent_id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 0, '电脑办公', 'http://test.yudao.iocoder.cn/122d548e1b3cd5dec72fe8075c6977a70f9cc13541a684ab3685f1b5df42f6bd.jpeg', 1, '1234', 0, '1', '2022-07-30 16:36:35', '1', '2022-07-30 20:27:16', b'0', 1), (2, 1, '笔记本', 'http://test.yudao.iocoder.cn/72713ac7b947600a019a18786ed0e6562e8692e253dbd35110a0a85c2469bbec.jpg', 1, '

测试一下

', 0, '1', '2022-07-30 16:38:09', '1', '2022-07-30 16:38:09', b'0', 1), (3, 1, '游戏本', 'http://test.yudao.iocoder.cn/287c50dd9f5f575f57329a0c57b2095be6d1aeba83867b905fe549f54a296feb.jpg', 2, '

测试一下

', 0, '1', '2022-07-30 16:39:09', '1', '2022-07-30 20:26:59', b'0', 1), (4, 0, '手机', 'http://test.yudao.iocoder.cn/e1b63900c78dbb661b3e383960cee5cfea7e1dd2fb22cff2e317ff025faaf8b2.jpeg', 2, '

123

', 0, '1', '2022-07-30 16:40:00', '1', '2022-07-30 16:40:09', b'0', 1), (5, 4, '5G手机', 'http://test.yudao.iocoder.cn/3af6557ac7def6423f046f5b2e920b644793420b466959aaa996a2e19068bbde.jpeg', 1, '


', 0, '1', '2022-07-30 16:43:00', '1', '2022-07-30 16:43:00', b'0', 1), (6, 4, '游戏手机', 'http://test.yudao.iocoder.cn/964fe9ccd1710d64ede261dc36d231918a017641986c15293c367f9f66d94d05.jpeg', 2, NULL, 0, '1', '2022-07-30 16:43:44', '1', '2022-07-30 16:43:44', b'0', 1), (7, 5, '厉害的 5G 手机', 'http://test.yudao.iocoder.cn/b287122f277838e8de368769b96217918605743bc45f3a29bda3cc7359dc66e1.png', 0, '123', 0, '1', '2022-07-30 20:38:09', '1', '2022-07-30 20:38:09', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 0, '电脑办公', 'http://test.yudao.iocoder.cn/122d548e1b3cd5dec72fe8075c6977a70f9cc13541a684ab3685f1b5df42f6bd.jpeg', '', 300, 0, '1', '2022-07-30 16:36:35', '1', '2022-07-30 20:27:16', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 1, '笔记本', 'http://test.yudao.iocoder.cn/72713ac7b947600a019a18786ed0e6562e8692e253dbd35110a0a85c2469bbec.jpg', '', 310, 0, '1', '2022-07-30 16:38:09', '1', '2022-07-30 16:38:09', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 1, '游戏本', 'http://test.yudao.iocoder.cn/287c50dd9f5f575f57329a0c57b2095be6d1aeba83867b905fe549f54a296feb.jpg', '', 312, 0, '1', '2022-07-30 16:39:09', '1', '2022-07-30 20:26:59', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 0, '手机', 'http://test.yudao.iocoder.cn/e1b63900c78dbb661b3e383960cee5cfea7e1dd2fb22cff2e317ff025faaf8b2.jpeg', '', 313, 0, '1', '2022-07-30 16:40:00', '1', '2022-07-30 16:40:09', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 4, '5G手机', 'http://test.yudao.iocoder.cn/3af6557ac7def6423f046f5b2e920b644793420b466959aaa996a2e19068bbde.jpeg', '', 314, 0, '1', '2022-07-30 16:43:00', '1', '2022-07-30 16:43:00', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 4, '游戏手机', 'http://test.yudao.iocoder.cn/964fe9ccd1710d64ede261dc36d231918a017641986c15293c367f9f66d94d05.jpeg', '', 315, 0, '1', '2022-07-30 16:43:44', '1', '2022-07-30 16:43:44', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 5, '厉害的 5G 手机', 'http://test.yudao.iocoder.cn/b287122f277838e8de368769b96217918605743bc45f3a29bda3cc7359dc66e1.png', '', '123', 0, '1', '2022-07-30 20:38:09', '1', '2022-07-30 20:38:09', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (15, 0, '服装鞋包', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/a23f732db55e6adbc608f4b6cf2b0ab50db6d9147af0ee267a315805a596e175.jpg', '', 100, 0, '1', '2023-04-25 16:57:05', '1', '2023-04-25 17:08:26', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (16, 15, '时尚女装', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/aa8d5c44ac0390ab398bae0dc8883575e3cb57594f9ed00248febe8e3d7484d1.png', '', 200, 0, '1', '2023-04-25 17:09:00', '1', '2023-04-25 17:09:00', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 15, '精品男装', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/b0c166c0846fa2280b4a02431e2ac2e2363f2d2a6b608598f34b067a5ccf1245.png', '', 100, 0, '1', '2023-04-25 17:09:33', '1', '2023-04-25 17:09:33', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (18, 15, '箱包', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/8682928caa2a5a49b380ac93059adc435099873cdf646084f31cea79d5c27f40.png', '', 80, 0, '1', '2023-04-25 17:09:51', '1', '2023-04-25 17:09:51', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (19, 15, '西服', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/c202fa79f2fbe188cfdf40b107c7eca89c548a5c4b0047e26b7a6445c470615a.jpg', '', 0, 0, '1', '2023-04-25 17:10:15', '1', '2023-04-25 17:10:15', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (20, 15, '配饰', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/51bf43fcad0b947f5fa377356fb7034b47223fdbcec241d50e6e60a9be498730.jpg', '', 0, 0, '1', '2023-04-25 17:10:56', '1', '2023-04-25 17:10:56', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 15, '美妆工具', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/c3cd6735cf157c218bc32ece312fd90cb2130c437dc9ec61d4030681d6ba4efb.png', '', 0, 0, '1', '2023-04-25 17:11:15', '1', '2023-04-25 17:11:24', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (22, 0, '网络盒子', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/74656bb8bc988c0419e0dbc613eda24a03956b950452b3565527301a5782db3a.png', '', 50, 0, '1', '2023-04-25 17:12:13', '1', '2023-04-25 17:12:13', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (23, 22, '尿裤湿巾', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/20162f22d8f6b427f0d6f1678c9fbb7bf0c1b70768bdc86101bee8b5e13bec5a.jpeg', '', 0, 0, '1', '2023-04-25 17:12:42', '1', '2023-04-25 17:12:42', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (24, 15, '宠物主粮', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/383729ba05711c400f9e44db11a63603af0fdbc99e58cd7b40e9296ca4e0510e.jpg', '', 0, 0, '1', '2023-04-25 17:13:09', '1', '2023-04-25 17:13:09', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (25, 0, '家电电器', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/c8a34dc2688fd4d2c95b5f49888865db1c88fd3bde153e3f7f0bcd4ff9971c96.png', '', 50, 0, '1', '2023-04-25 17:13:43', '1', '2023-04-25 17:13:43', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (26, 25, '封口/封杯机', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/1c0c208cfcf871c146006d97f95ae4fcd14d8a2deb3eabe3696367af61cb5e69.png', '', 60, 0, '1', '2023-04-25 17:14:39', '1', '2023-04-25 17:14:39', b'0', 1); +INSERT INTO `ruoyi-vue-pro`.`product_category` (`id`, `parent_id`, `name`, `pic_url`, `big_pic_url`, `sort`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (27, 25, '空调', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/d578e1e60b2dc3efe70643d25a8b2150dabfecd658fdb2fafcdb786d525f66d1.png', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/34ed55f822ad25ab445e6b396dcd61a7d119882ef19f85f0e24742911d896959.jpeg', 60, 0, '1', '2023-04-25 17:15:12', '1', '2023-04-25 17:17:04', b'0', 1); COMMIT; -- ---------------------------- @@ -480,41 +499,45 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2164, '配送管理', '', 1, 0, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-18 09:48:48', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2165, '快递发货', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2167, '快递公司', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2178, '快递运费模板导出', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2177, '快递运费模板删除', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2176, '快递运费模板更新', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2175, '快递运费模板创建', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2174, '快递运费模板查询', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, '运费模版', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', '', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-05-20 06:48:29', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2164, '配送管理', '', 1, 0, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-18 09:48:48', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2165, '快递发货', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2167, '快递公司', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2178, '快递运费模板导出', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2177, '快递运费模板删除', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2176, '快递运费模板更新', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2175, '快递运费模板创建', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2174, '快递运费模板查询', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, '运费模版', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', '', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-05-20 06:48:29', b'0'); BEGIN; +-- ---------------------------- +-- 字典管理,添加商品单位字典 product_unit +-- ---------------------------- BEGIN; -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '个', 1, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '件', 2, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '盒', 3, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '袋', 4, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '箱', 5, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '套', 6, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '包', 7, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '双', 8, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '卷', 9, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (169, '商品单位', 'product_unit', 0, '', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '个', 1, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '件', 2, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '盒', 3, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '袋', 4, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '箱', 5, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '套', 6, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '包', 7, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '双', 8, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '卷', 9, 'product_unit', 0, '', '', '', 1, NOW(), 1, NOW(), b'0'); COMMIT; -- ---------------------------- -- 数字字典,快递计费方式 -- ---------------------------- BEGIN; -INSERT INTO `ruoyi-vue-pro`.`system_dict_type`(`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (169, '快递计费方式', 'trade_delivery_express_charge_mode', 0, '用于商城交易模块配送管理', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00'); -INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1237, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (169, '快递计费方式', 'trade_delivery_express_charge_mode', 0, '用于商城交易模块配送管理', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1237, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0'); COMMIT; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index f1d5a209c..29cfe3a27 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.spu; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; From c62da6a056331a8202c4d46d90a29a98ebc4f139 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 23 May 2023 23:27:15 +0800 Subject: [PATCH 057/232] =?UTF-8?q?mall=EF=BC=9Areview=20=E5=95=86?= =?UTF-8?q?=E5=93=81=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/DictTypeConstants.java | 3 ++ .../product/enums/ProductConstants.java | 8 ++++- .../enums/spu/ProductSpuPageTabEnum.java | 4 ++- .../admin/brand/ProductBrandController.java | 2 +- .../brand/vo/ProductBrandSimpleRespVO.java | 1 + .../admin/sku/vo/ProductSkuBaseVO.java | 11 +------ .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 6 ++-- .../admin/spu/ProductSpuController.java | 14 +++------ .../admin/spu/vo/ProductSpuBaseVO.java | 7 ++--- .../admin/spu/vo/ProductSpuDetailRespVO.java | 5 ++-- .../admin/spu/vo/ProductSpuExportReqVO.java | 3 ++ .../admin/spu/vo/ProductSpuRespVO.java | 3 +- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 4 +-- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 4 +-- .../convert/brand/ProductBrandConvert.java | 2 ++ .../convert/spu/ProductSpuConvert.java | 12 +++++--- .../dal/mysql/brand/ProductBrandMapper.java | 1 + .../dal/mysql/spu/ProductSpuMapper.java | 15 +++++----- .../category/ProductCategoryServiceImpl.java | 1 + .../service/spu/ProductSpuServiceImpl.java | 30 ++++++++----------- .../ProductCategoryServiceImplTest.java | 5 +--- .../service/sku/ProductSkuServiceTest.java | 2 +- .../spu/ProductSpuServiceImplTest.java | 20 ++++++------- 23 files changed, 83 insertions(+), 80 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java index a41064970..85725a18e 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java @@ -2,9 +2,12 @@ package cn.iocoder.yudao.module.product.enums; /** * product 字典类型的枚举类 + * * @author HUIHUI */ public interface DictTypeConstants { + String PRODUCT_UNIT = "product_unit"; // 商品单位 String PRODUCT_SPU_STATUS = "product_spu_status"; // 商品 SPU 状态 + } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java index db0536993..50d43bb97 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java @@ -5,8 +5,9 @@ package cn.iocoder.yudao.module.product.enums; * * @author HUIHUI */ - public interface ProductConstants { + + // TODO @puhui999:这个变量,可以放到 CategoryDO 的实体里 /** * 父分类编号 - 根分类 */ @@ -15,14 +16,18 @@ public interface ProductConstants { * 限定分类层级 */ int CATEGORY_LEVEL = 2; + + // TODO @puhui999:这个变量,必要项不大哈 /** * SPU 分页 tab 个数 */ int SPU_TAB_COUNTS = 5; + /** * 警戒库存 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 */ int ALERT_STOCK = 10; + /** * 默认商品销量 TODO 默认商品销量为零 */ @@ -31,4 +36,5 @@ public interface ProductConstants { * 默认善品浏览量 TODO 默认浏览量为零 */ Integer BROWSE_COUNT = 0; + } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java index 4c6e729f5..c79c55a97 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java @@ -6,7 +6,7 @@ import lombok.Getter; import java.util.Arrays; -// TODO @puhui999:中英文之间要有空格; 商品 spu Tab 标签枚举;这个类可以改成 ProductSpuPageTabEnum 会更好一点哈;分页 Tab 的意思; +// TODO @puhui999:这种非关键的枚举,要不直接写在 ProductSpuPageReqVO 里。类似 public static final Integer TAB_TYPE_FOR_SALE = 0; // 出售中商品 /** * 商品 spu Tabs 标签枚举类型 * @@ -21,6 +21,7 @@ public enum ProductSpuPageTabEnum implements IntArrayValuable { SOLD_OUT(2,"已售空商品"), ALERT_STOCK(3,"警戒库存"), RECYCLE_BIN(4,"商品回收站"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuPageTabEnum::getType).toArray(); /** * 状态 @@ -35,4 +36,5 @@ public enum ProductSpuPageTabEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index cf02edf1d..24af006c8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -61,7 +61,7 @@ public class ProductBrandController { public CommonResult getBrand(@RequestParam("id") Long id) { ProductBrandDO brand = brandService.getBrand(id); return success(ProductBrandConvert.INSTANCE.convert(brand)); - } + } // TODO @puhui999:方法和方法之间,要有空行。 @GetMapping("/list-all-simple") @Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项") public CommonResult> getSimpleUserList() { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java index 79a4a6d59..93501ce51 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +// TODO @puhui999:class 类的开始和结束,都要有一个空行哈。 @Schema(description = "管理后台 - 品牌精简信息 Response VO") @Data @NoArgsConstructor diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index be8f761a1..fb0554219 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; @@ -57,6 +55,7 @@ public class ProductSkuBaseVO { @Schema(description = "二级分销的佣金,单位:分", example = "1024") private Integer subCommissionSecondPrice; + // TODO @puhui999:这里要写 swagger 注解哈 /** * 商品属性 */ @@ -67,27 +66,19 @@ public class ProductSkuBaseVO { /** * 属性编号 - * 关联 {@link ProductPropertyDO#getId()} */ private Long propertyId; /** * 属性名字 - * 冗余 {@link ProductPropertyDO#getName()} - * - * 注意:每次属性名字发生变化时,需要更新该冗余 */ private String propertyName; /** * 属性值编号 - * 关联 {@link ProductPropertyValueDO#getId()} */ private Long valueId; /** * 属性值名字 - * 冗余 {@link ProductPropertyValueDO#getName()} - * - * 注意:每次属性值名字发生变化时,需要更新该冗余 */ private String valueName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 2909a514f..1287d8f8c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -1,9 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; -import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO") @@ -12,6 +13,7 @@ import java.util.List; @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { + // TODO @puhui999:是不是可以抽到父类里? /** * 属性数组 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 5b35c49fa..c03f08798 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -2,14 +2,11 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -22,14 +19,10 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; /** @@ -101,7 +94,7 @@ public class ProductSpuController { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } - // TODO @tuihui999:get-count;另外,url 使用 - 拆分 fix + // TODO @puhui999:方法名改成 getSpuCount,只是用于 tab 哈,这样更抽象一点。 @GetMapping("/get-count") @Operation(summary = "获得商品 SPU 分页 tab count") @PreAuthorize("@ss.hasPermission('product:spu:query')") @@ -110,7 +103,7 @@ public class ProductSpuController { } @GetMapping("/export") - @Operation(summary = "导出用户") + @Operation(summary = "导出商品") @PreAuthorize("@ss.hasPermission('product:spu:export')") @OperateLog(type = EXPORT) public void exportUserList(@Validated ProductSpuExportReqVO reqVO, @@ -118,6 +111,7 @@ public class ProductSpuController { List spuList = productSpuService.getSpuList(reqVO); // 导出 Excel List datas = ProductSpuConvert.INSTANCE.convertList03(spuList); - ExcelUtils.write(response, "商品spu.xls", "数据", ProductSpuExcelVO.class, datas); + ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuExcelVO.class, datas); } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 4b194ed76..1d4dccc5d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -97,14 +96,14 @@ public class ProductSpuBaseVO { @NotNull(message = "商品赠送积分不能为空") private Integer giveIntegral; - @Schema(description = "赠送的优惠劵编号的数组") // TODO 这块前端还未实现 + @Schema(description = "赠送的优惠劵编号的数组", example = "[1, 10]") // TODO 这块前端还未实现 private List giveCouponTemplateIds; - @Schema(description = "分销类型", example = "true") + @Schema(description = "分销类型", required = true, example = "true") @NotNull(message = "商品分销类型不能为空") private Boolean subCommissionType; - @Schema(description = "活动展示顺序", example = "[1、3、2、4、5]") // TODO 这块前端还未实现 + @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]") // TODO 这块前端还未实现 private List activityOrders; // ========== 统计相关字段 ========= diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index 7614467a1..dacd94b79 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -6,7 +6,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import java.time.LocalDateTime; import java.util.List; /** @@ -21,7 +20,9 @@ import java.util.List; @ToString(callSuper = true) public class ProductSpuDetailRespVO extends ProductSpuBaseVO { - @Schema(description = "spuId") + // TODO @puhui999:swagger 的 required 和 example 写下 + + @Schema(description = "商品 SPU 编号") private Long id; @Schema(description = "商品销量") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java index 4fe387167..01e752377 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java @@ -11,11 +11,13 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + @Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的") @Data @NoArgsConstructor @AllArgsConstructor public class ProductSpuExportReqVO { + @Schema(description = "商品名称", example = "yutou") private String name; @@ -29,4 +31,5 @@ public class ProductSpuExportReqVO { @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index 4780b2509..adcc94100 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -19,6 +18,8 @@ import java.time.LocalDateTime; @ToString(callSuper = true) public class ProductSpuRespVO extends ProductSpuBaseVO { + // TODO @puhui999:swagger 的 required 和 example 写下 + @Schema(description = "spuId") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java index 65bb2cbaf..4df865af0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -1,9 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.ToString; /** @@ -16,6 +14,8 @@ import lombok.ToString; @ToString(callSuper = true) public class ProductSpuSimpleRespVO { + // TODO @puhui999:swagger 的 required 和 example 写下 + @Schema(description = "主键") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 3788d2fa0..61230242f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -11,7 +10,6 @@ import lombok.ToString; import javax.validation.Valid; import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; import java.util.List; /** @@ -25,6 +23,8 @@ import java.util.List; @ToString(callSuper = true) public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { + // TODO @puhui999:swagger 的 required 和 example 写下 + @Schema(description = "商品编号", required = true, example = "1") @NotNull(message = "商品编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java index a3d017799..e6c72fb49 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java @@ -26,7 +26,9 @@ public interface ProductBrandConvert { ProductBrandDO convert(ProductBrandUpdateReqVO bean); ProductBrandRespVO convert(ProductBrandDO bean); + List convertList1(List list); + List convertList(List list); PageResult convertPage(PageResult page); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 717152c95..052ac287d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -1,5 +1,4 @@ package cn.iocoder.yudao.module.product.convert.spu; -import java.time.LocalDateTime; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; @@ -10,8 +9,8 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -52,6 +51,8 @@ public interface ProductSpuConvert { List convertList2(List list); List convertList02(List list); + + // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 default List convertList03(List list){ ArrayList spuExcelVOs = new ArrayList<>(); list.forEach((spu)->{ @@ -95,6 +96,7 @@ public interface ProductSpuConvert { } ProductSpuDetailRespVO convert03(ProductSpuDO spu); + // TODO @puhui999:下面两个没用到,是不是删除呀? List convertList04(List skus); ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); @@ -142,11 +144,13 @@ public interface ProductSpuConvert { AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); - default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus, Function, List> func) { + default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus, + Function, List> func) { ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu); + // TODO @puhui999:if return 哈,减少嵌套层数。 if (CollUtil.isNotEmpty(skus)) { List skuVOs = ProductSkuConvert.INSTANCE.convertList(skus); - // fix:统一模型,即使是单规格,也查询下,如若Properties为空报错则为单属性不做处理 + // fix:统一模型,即使是单规格,也查询下,如若 Properties 为空报错则为单属性不做处理 try { // 获取所有的属性值 id Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java index cc66780a4..e66a6ed2b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java @@ -31,6 +31,7 @@ public interface ProductBrandMapper extends BaseMapperX { return selectOne(ProductBrandDO::getName, name); } + // TODO @puhui999:) { 中间要有空格哈。 default List selectListByStatus(Integer status){ return selectList(ProductBrandDO::getStatus,status); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index e7385b588..14f6fae58 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -10,13 +10,10 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.enums.ProductConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import org.apache.ibatis.annotations.Mapper; -import org.apache.poi.ss.formula.functions.T; import java.util.List; import java.util.Objects; @@ -26,7 +23,7 @@ import java.util.Set; public interface ProductSpuMapper extends BaseMapperX { /** - * 获取 商品 SPU 分页列表数据 + * 获取商品 SPU 分页列表数据 * * @param reqVO 分页请求参数 * @return 商品 SPU 分页列表数据 @@ -43,11 +40,14 @@ public interface ProductSpuMapper extends BaseMapperX { } /** - * 获取库存小于value且状态不等于status的的个数 + * 获取库存小于 value ,且状态不等于 status 的的个数 + * + * @return 个数 */ default Long selectCountByStockAndStatus() { LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) + // TODO @puhui999:IN 另外两个状态,会不会好点哈。尽量不用 != // 如果库存触发警戒库存且状态为回收站的话则不计入触发警戒库存的个数 .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); return selectCount(queryWrapper); @@ -111,6 +111,7 @@ public interface ProductSpuMapper extends BaseMapperX { return selectList(queryWrapper); } + // TODO @puhui999:应该不太适合 validate 验证,应该是补充条件,例如说 appendTabQuery /** * 验证选项卡类型构建条件 * @@ -118,8 +119,8 @@ public interface ProductSpuMapper extends BaseMapperX { * @param queryWrapper 查询条件 */ static void validateTabType(Integer tabType, LambdaQueryWrapperX queryWrapper) { + // 出售中商品 TODO puhui999:这样好点 if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) { - // 出售中商品 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); } if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index ff1b6da01..534fd7131 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -111,6 +111,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) { return 0; } + // TODO @puhui999:for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈 int level = 1; // fix: 循环次数不确定改为while循环 while (true){ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 3b3e63541..12233d246 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,29 +1,24 @@ package cn.iocoder.yudao.module.product.service.spu; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.ProductConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -32,7 +27,6 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.*; -import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; @@ -63,11 +57,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override @Transactional(rollbackFor = Exception.class) public Long createSpu(ProductSpuCreateReqVO createReqVO) { - // 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别;fix + // 校验分类、品牌 validateCategory(createReqVO.getCategoryId()); brandService.validateProductBrand(createReqVO.getBrandId()); - List skuSaveReqList = createReqVO.getSkus(); // 校验 SKU + List skuSaveReqList = createReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); // 初始化 SPU 中 SKU 相关属性 @@ -86,13 +80,13 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void updateSpu(ProductSpuUpdateReqVO updateReqVO) { // 校验 SPU 是否存在 validateSpuExists(updateReqVO.getId()); - // 校验分类 + // 校验分类、品牌 validateCategory(updateReqVO.getCategoryId()); - // 校验品牌 brandService.validateProductBrand(updateReqVO.getBrandId()); // 校验SKU List skuSaveReqList = updateReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); + // TODO @puhui999:可以校验逻辑,和更新逻辑,中间有个空行,这样会发现,哟 这里到了关键逻辑啦,更有层次感 // 更新 SPU ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); initSpuFromSkus(updateObj, skuSaveReqList); @@ -111,17 +105,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { private void initSpuFromSkus(ProductSpuDO spu, List skus) { // 断言,避免告警 assert skus.size() > 0; - // 获取sku单价最低的商品 + // 获取 sku 单价最低的商品 + // TODO @puhui999:vo 改成 sku 会更好。vo dto 只是我们用来区分的,如果能区分的情况下,用更明确的名字会更好。 +// CollectionUtils.getMinValue(); TODO @puhui999:可以用这个方法,常见的 stream 操作,封装成方法,让逻辑更简洁 ProductSkuCreateOrUpdateReqVO vo = skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateReqVO::getPrice)).get(); - // sku单价最低的商品的价格 + // sku 单价最低的商品的价格 spu.setPrice(vo.getPrice()); - // sku单价最低的商品的市场价格 + // sku 单价最低的商品的市场价格 spu.setMarketPrice(vo.getMarketPrice()); // sku单价最低的商品的成本价格 spu.setCostPrice(vo.getCostPrice()); // sku单价最低的商品的条形码 spu.setBarCode(vo.getBarCode()); - // skus库存总数 + // skus 库存总数 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); // 若是 spu 已有状态则不处理 if (spu.getStatus() == null) { @@ -233,6 +229,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { } // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); + // TODO @puhui999:感觉还是查询好 productPropertyValueService,然后 propertyId 可以交给 convert 处理下即可。 return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus, productPropertyValueService::getPropertyValueDetailList); } @@ -249,7 +246,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public Map getTabsCount() { - // TODO @puhui999:map =》;尽量避免出现 map 这种命名,无命名含义哈 fix Map counts = new HashMap<>(ProductConstants.SPU_TAB_COUNTS); // 查询销售中的商品数量 counts.put(ProductSpuPageTabEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); @@ -258,8 +254,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 查询售空的商品数量 counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); // 查询触发警戒库存的商品数量 - // TODO @puhui999:要有空格;, productSpuMapper fix - // TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈 fix:调整为在 productSpuMapper 中书写逻辑 counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCountByStockAndStatus()); // 查询回收站中的商品数量 counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 3205c4d02..0ba5633cd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -40,10 +40,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @Test public void testCreateCategory_success() { // 准备参数 - ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class,o -> { - // 设置PC端图片可为空 TODO 数据库没有这个字段 - //o.setBigPicUrl(null); - }); + ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); // mock 父类 ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> { diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index 8c5a629af..9c4d6601d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.util.AssertUtils; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; @@ -50,6 +49,7 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { @MockBean private ProductPropertyValueService productPropertyValueService; + // TODO @puhui999:是不是可以删除这 2 方法 public Long generateId() { return RandomUtil.randomLong(100000, 999999); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 641bac5c8..06053b261 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -6,13 +6,12 @@ import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; @@ -23,21 +22,20 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl; import com.google.common.collect.Lists; -import org.apache.poi.ss.formula.functions.T; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; import java.math.RoundingMode; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -83,6 +81,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { public int generaInt(){return RandomUtil.randomInt(1,9999999);} + // TODO @芋艿:单测后续 review 哈 + @Test public void testCreateSpu_success() { // 准备参数 From 53e9be733f71019d97a91ef1cc87053e1031c575 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 24 May 2023 23:40:55 +0800 Subject: [PATCH 058/232] =?UTF-8?q?mall=EF=BC=9Areview=20+=20mall=EF=BC=9A?= =?UTF-8?q?=E5=BF=AB=E9=80=92=E5=85=AC=E5=8F=B8=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 40 +++++++++---------- .../delivery/DeliveryExpressController.java | 31 +++++++------- .../delivery/vo/DeliveryExpressBaseVO.java | 12 +++--- .../delivery/vo/DeliveryExpressExcelVO.java | 7 ++-- .../vo/DeliveryExpressExportReqVO.java | 2 +- .../delivery/vo/DeliveryExpressPageReqVO.java | 2 +- 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 83853b22b..ca9f584b2 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -330,9 +330,9 @@ CREATE TABLE `product_favorite` ( -- ---------------------------- DROP TABLE IF EXISTS `trade_delivery_express_template`; CREATE TABLE `trade_delivery_express_template` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(64) NOT NULL COMMENT '模板名称', - `charge_mode` tinyint NOT NULL DEFAULT 1 COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', + `charge_mode` tinyint NOT NULL COMMENT '配送计费方式', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', @@ -348,11 +348,11 @@ CREATE TABLE `trade_delivery_express_template` ( -- ---------------------------- DROP TABLE IF EXISTS `trade_delivery_express_template_free`; CREATE TABLE `trade_delivery_express_template_free` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', - `area_id` int NOT NULL COMMENT '包邮区域id', - `free_price` int NOT NULL COMMENT '包邮金额(单位分) 订单总金额>包邮金额才免运费', - `free_count` int NOT NULL DEFAULT 0 COMMENT '包邮件数,订单总件数>包邮件数才免运费', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `template_id` bigint NOT NULL COMMENT '快递运费模板编号', + `area_id` int NOT NULL COMMENT '包邮区域 id', + `free_price` int NOT NULL COMMENT '包邮金额,单位:分', + `free_count` int NOT NULL DEFAULT 0 COMMENT '包邮件数,', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -368,13 +368,13 @@ CREATE TABLE `trade_delivery_express_template_free` ( DROP TABLE IF EXISTS `trade_delivery_express_template_charge`; CREATE TABLE `trade_delivery_express_template_charge` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `template_id` bigint NOT NULL COMMENT '配送模板编号, 对应delivery_template表id', - `area_id` int NOT NULL COMMENT '配送区域id 1:适用于全国', - `charge_mode` tinyint NOT NULL COMMENT '配送计费方式 1:按件 2:按重量 3:按体积', - `start_count` double NOT NULL COMMENT '首件数量(件数,重量,或体积)', - `start_price` int NOT NULL COMMENT '起步价(单位分)', - `extra_count` double NOT NULL COMMENT '续件数量(件,重量,或体积)', - `extra_price` int NOT NULL COMMENT '额外价(单位分)', + `template_id` bigint NOT NULL COMMENT '快递运费模板编号', + `area_id` int NOT NULL COMMENT '配送区域 id', + `charge_mode` tinyint NOT NULL COMMENT '配送计费方式', + `start_count` double NOT NULL COMMENT '首件数量', + `start_price` int NOT NULL COMMENT '起步价,单位:分', + `extra_count` double NOT NULL COMMENT '续件数量', + `extra_price` int NOT NULL COMMENT '额外价,单位:分', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -417,7 +417,7 @@ DROP TABLE IF EXISTS `trade_delivery_pick_up_store_staff`; CREATE TABLE `trade_delivery_pick_up_store_staff` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', store_id bigint NOT NULL COMMENT '自提门店编号', - `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -451,12 +451,12 @@ CREATE TABLE `trade_delivery_pick_up_store_staff` ( -- ---------------------------- DROP TABLE IF EXISTS `trade_delivery_express`; CREATE TABLE `trade_delivery_express` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `code` varchar(64) NOT NULL COMMENT '快递公司编号', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `code` varchar(64) NOT NULL COMMENT '快递公司编码', `name` varchar(64) NOT NULL COMMENT '快递公司名称', - `logo` varchar(256) COMMENT '快递公司logo', + `logo` varchar(256) COMMENT '快递公司 logo', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', - `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -540,4 +540,4 @@ INSERT INTO `ruoyi-vue-pro`.`system_dict_type` (`id`, `name`, `type`, `status`, INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1237, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0'); -COMMIT; \ No newline at end of file +COMMIT; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index 98515935b..fde0b5d79 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -1,31 +1,28 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; -import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; -import javax.validation.constraints.*; -import javax.validation.*; -import javax.servlet.http.*; -import java.util.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.io.IOException; +import java.util.List; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; - -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @Tag(name = "管理后台 - 快递公司") @RestController diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java index ea1a10461..538027c81 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java @@ -1,11 +1,9 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import javax.validation.constraints.*; +import lombok.Data; + +import javax.validation.constraints.NotNull; /** * 快递公司 Base VO,提供给添加、修改、详细的子 VO 使用 @@ -14,8 +12,8 @@ import javax.validation.constraints.*; @Data public class DeliveryExpressBaseVO { - @Schema(description = "快递公司编号", required = true) - @NotNull(message = "快递公司编号不能为空") + @Schema(description = "快递公司编码", required = true) + @NotNull(message = "快递公司编码不能为空") private String code; @Schema(description = "快递公司名称", required = true, example = "李四") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java index ba7e646d5..45d92aa43 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java @@ -16,19 +16,20 @@ public class DeliveryExpressExcelVO { @ExcelProperty("编号") private Long id; - @ExcelProperty("快递公司编号") + @ExcelProperty("快递公司编码") private String code; @ExcelProperty("快递公司名称") private String name; - @ExcelProperty("快递公司logo") + @ExcelProperty("快递公司 logo") private String logo; @ExcelProperty("排序") private Integer sort; - @ExcelProperty("状态(0正常 1停用)") + @ExcelProperty("状态") + // TODO @jason:可以使用 @DictFormat(DictTypeConstants.COMMON_STATUS) private Byte status; @ExcelProperty("创建时间") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java index cb738a6db..6e44cc45f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java @@ -12,7 +12,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class DeliveryExpressExportReqVO { - @Schema(description = "快递公司编号") + @Schema(description = "快递公司编码") private String code; @Schema(description = "快递公司名称", example = "李四") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java index 5425bf42a..50826ea36 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java @@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class DeliveryExpressPageReqVO extends PageParam { - @Schema(description = "快递公司编号") + @Schema(description = "快递公司编码") private String code; @Schema(description = "快递公司名称", example = "李四") From b065a2a741853df5ce087e35e12890da6bbda1f1 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 25 May 2023 09:23:38 +0800 Subject: [PATCH 059/232] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=95=86?= =?UTF-8?q?=E5=93=81=20review=20=E6=8F=90=E5=88=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/spu/ProductUnitEnum.java | 67 ------------- .../admin/brand/ProductBrandController.java | 4 +- .../admin/brand/vo/ProductBrandBaseVO.java | 2 +- .../admin/brand/vo/ProductBrandListReqVO.java | 2 +- .../admin/brand/vo/ProductBrandPageReqVO.java | 2 +- .../brand/vo/ProductBrandSimpleRespVO.java | 5 +- .../vo/ProductCategoryCreateReqVO.java | 4 +- .../vo/ProductCategoryUpdateReqVO.java | 3 +- .../admin/sku/vo/ProductSkuBaseVO.java | 50 +++++----- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 6 -- .../admin/sku/vo/ProductSkuRespVO.java | 5 - .../admin/spu/ProductSpuController.java | 3 +- .../admin/spu/vo/ProductSpuBaseVO.java | 14 +-- .../admin/spu/vo/ProductSpuDetailRespVO.java | 10 +- .../admin/spu/vo/ProductSpuExcelVO.java | 2 + .../admin/spu/vo/ProductSpuExportReqVO.java | 4 +- .../admin/spu/vo/ProductSpuPageReqVO.java | 8 +- .../admin/spu/vo/ProductSpuRespVO.java | 18 ++-- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 20 ++-- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 8 +- .../app/spu/AppProductSpuController.java | 3 +- .../convert/sku/ProductSkuConvert.java | 2 - .../convert/spu/ProductSpuConvert.java | 96 +++++++------------ .../dal/dataobject/sku/ProductSkuDO.java | 2 +- .../dal/mysql/brand/ProductBrandMapper.java | 5 +- .../dal/mysql/sku/ProductSkuMapper.java | 14 ++- .../dal/mysql/spu/ProductSpuMapper.java | 36 +++---- .../service/sku/ProductSkuService.java | 6 +- .../service/sku/ProductSkuServiceImpl.java | 8 +- .../service/spu/ProductSpuServiceImpl.java | 29 ++---- 30 files changed, 155 insertions(+), 283 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java deleted file mode 100644 index 8753824dc..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java +++ /dev/null @@ -1,67 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.spu; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -// TODO @puhui999:是不是放到数据字典里? -/** - * 产品单位枚举 - * - * @author HUIHUI - */ -@Getter -@AllArgsConstructor -public enum ProductUnitEnum implements IntArrayValuable { - - PIECE(1, "个"), - DOZEN(2, "打"), - BOX(3, "盒"), - BAG(4, "袋"), - CASE(5, "箱"), - SET(6, "套"), - PACK(7, "包"), - PAIR(8, "双"), - ROLL(9, "卷"), - SHEET(10, "张"), - WEIGHT(11, "克"), - KILOGRAM(12, "千克"), - MILLIGRAM(13, "毫克"), - MICROGRAM(14, "微克"), - TON(15, "吨"), - LITER(16, "升"), - MILLILITER(17, "毫升"), - SQUARE_METER(19, "平方米"), - SQUARE_KILOMETER(20, "平方千米"), - SQUARE_MILE(21, "平方英里"), - SQUARE_YARD(22, "平方码"), - SQUARE_FOOT(23, "平方英尺"), - CUBIC_METER(24, "立方米"), - CUBIC_CENTIMETER(25, "立方厘米"), - CUBIC_INCH(26, "立方英寸"), - METER(27, "米"), - CENTIMETER(29, "厘米"), - MILLIMETER(30, "毫米"), - INCH(31, "英寸"), - FOOT(32, "英尺"), - YARD(33, "码"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductUnitEnum::getStatus).toArray(); - - /** - * 状态 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index 24af006c8..9cc398169 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -61,7 +61,8 @@ public class ProductBrandController { public CommonResult getBrand(@RequestParam("id") Long id) { ProductBrandDO brand = brandService.getBrand(id); return success(ProductBrandConvert.INSTANCE.convert(brand)); - } // TODO @puhui999:方法和方法之间,要有空行。 + } + @GetMapping("/list-all-simple") @Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项") public CommonResult> getSimpleUserList() { @@ -70,6 +71,7 @@ public class ProductBrandController { // 排序后,返回给前端 return success(ProductBrandConvert.INSTANCE.convertList1(list)); } + @GetMapping("/page") @Operation(summary = "获得品牌分页") @PreAuthorize("@ss.hasPermission('product:brand:query')") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java index e8561fe07..4336c3cc8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java @@ -12,7 +12,7 @@ import javax.validation.constraints.NotNull; @Data public class ProductBrandBaseVO { - @Schema(description = "品牌名称", required = true, example = "芋道") + @Schema(description = "品牌名称", required = true, example = "苹果") @NotNull(message = "品牌名称不能为空") private String name; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java index 63305810c..ed93ff090 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java @@ -7,7 +7,7 @@ import lombok.Data; @Data public class ProductBrandListReqVO { - @Schema(description = "品牌名称", example = "芋道") + @Schema(description = "品牌名称", example = "苹果") private String name; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java index 81d470b1b..3a6efc93f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java @@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class ProductBrandPageReqVO extends PageParam { - @Schema(description = "品牌名称", example = "芋道") + @Schema(description = "品牌名称", example = "苹果") private String name; @Schema(description = "状态", example = "0") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java index 93501ce51..14e74b946 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java @@ -11,8 +11,11 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class ProductBrandSimpleRespVO { + @Schema(description = "品牌编号", required = true, example = "1024") private Long id; - @Schema(description = "品牌名称", required = true, example = "芋道") + + @Schema(description = "品牌名称", required = true, example = "苹果") private String name; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java index 616286674..cd02ddbd0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -12,6 +12,8 @@ import javax.validation.constraints.NotBlank; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { - @Schema(description = "分类描述") + + @Schema(description = "分类描述", example = "描述") private String description; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java index 68cad0d30..2dee40d22 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -17,7 +17,8 @@ public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { @Schema(description = "分类编号", required = true, example = "2") @NotNull(message = "分类编号不能为空") private Long id; - @Schema(description = "分类描述") + + @Schema(description = "分类描述", example = "描述") private String description; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index fb0554219..518428ca6 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.List; /** * 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用 @@ -15,72 +16,67 @@ import javax.validation.constraints.NotNull; @Data public class ProductSkuBaseVO { - @Schema(description = "商品 SKU 名字", required = true, example = "芋道") + @Schema(description = "商品 SKU 名字", required = true, example = "清凉小短袖") @NotEmpty(message = "商品 SKU 名字不能为空") private String name; - @Schema(description = "销售价格,单位:分", required = true, example = "1024") + @Schema(description = "销售价格,单位:分", required = true, example = "1999") @NotNull(message = "销售价格,单位:分不能为空") private Integer price; - @Schema(description = "市场价", example = "1024") + @Schema(description = "市场价", example = "2999") private Integer marketPrice; - @Schema(description = "成本价", example = "1024") + @Schema(description = "成本价", example = "19") private Integer costPrice; - @Schema(description = "条形码", example = "haha") + @Schema(description = "条形码", example = "15156165456") private String barCode; @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "图片地址不能为空") private String picUrl; - @Schema(description = "库存", required = true, example = "1") + @Schema(description = "库存", required = true, example = "200") @NotNull(message = "库存不能为空") private Integer stock; - @Schema(description = "预警预存", example = "1") + @Schema(description = "预警预存", example = "10") private Integer warnStock; - @Schema(description = "商品重量,单位:kg 千克", example = "1") + @Schema(description = "商品重量,单位:kg 千克", example = "1.2") private Double weight; - @Schema(description = "商品体积,单位:m^3 平米", example = "1024") + @Schema(description = "商品体积,单位:m^3 平米", example = "2.5") private Double volume; - @Schema(description = "一级分销的佣金,单位:分", example = "1024") + @Schema(description = "一级分销的佣金,单位:分", example = "199") private Integer subCommissionFirstPrice; - @Schema(description = "二级分销的佣金,单位:分", example = "1024") + @Schema(description = "二级分销的佣金,单位:分", example = "19") private Integer subCommissionSecondPrice; - // TODO @puhui999:这里要写 swagger 注解哈 - /** - * 商品属性 - */ + @Schema(description = "属性数组") + private List properties; + + @Schema(description = "商品属性") @Data @NoArgsConstructor @AllArgsConstructor public static class Property { - /** - * 属性编号 - */ + @Schema(description = "属性编号", example = "10") private Long propertyId; - /** - * 属性名字 - */ + + @Schema(description = "属性名字", example = "颜色") private String propertyName; - /** - * 属性值编号 - */ + @Schema(description = "属性值编号", example = "10") private Long valueId; - /** - * 属性值名字 - */ + + @Schema(description = "属性值名字", example = "红色") private String valueName; } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 1287d8f8c..e750013d5 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -13,10 +13,4 @@ import java.util.List; @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { - // TODO @puhui999:是不是可以抽到父类里? - /** - * 属性数组 - */ - private List properties; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index ce0614152..27c66a295 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -15,9 +15,4 @@ public class ProductSkuRespVO extends ProductSkuBaseVO { @Schema(description = "主键", required = true, example = "1024") private Long id; - /** - * 属性数组 - */ - private List properties; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index c03f08798..184a44f7e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -94,11 +94,10 @@ public class ProductSpuController { return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); } - // TODO @puhui999:方法名改成 getSpuCount,只是用于 tab 哈,这样更抽象一点。 @GetMapping("/get-count") @Operation(summary = "获得商品 SPU 分页 tab count") @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getTabsCount() { + public CommonResult> getSpuCount() { return success(productSpuService.getTabsCount()); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 1d4dccc5d..409a74518 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -16,19 +16,19 @@ import java.util.List; @Data public class ProductSpuBaseVO { - @Schema(description = "商品名称", required = true, example = "芋道") + @Schema(description = "商品名称", required = true, example = "清凉小短袖") @NotEmpty(message = "商品名称不能为空") private String name; - @Schema(description = "关键字", required = true, example = "芋道") + @Schema(description = "关键字", required = true, example = "清凉丝滑不出汗") @NotEmpty(message = "商品关键字不能为空") private String keyword; - @Schema(description = "商品简介", required = true, example = "芋道") + @Schema(description = "商品简介", required = true, example = "清凉小短袖简介") @NotEmpty(message = "商品简介不能为空") private String introduction; - @Schema(description = "商品详情", required = true, example = "芋道") + @Schema(description = "商品详情", required = true, example = "清凉小短袖详情") @NotEmpty(message = "商品详情不能为空") private String description; @@ -40,14 +40,14 @@ public class ProductSpuBaseVO { @NotNull(message = "商品品牌不能为空") private Long brandId; - @Schema(description = "商品封面图", required = true, example = "芋道") + @Schema(description = "商品封面图", required = true, example = "https://www.iocoder.cn/xx.png") @NotEmpty(message = "商品封面图不能为空") private String picUrl; - @Schema(description = "商品轮播图", required = true) + @Schema(description = "商品轮播图", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") private List sliderPicUrls; - @Schema(description = "商品视频") + @Schema(description = "商品视频", example = "https://www.iocoder.cn/xx.mp4") private String videoUrl; @Schema(description = "单位", required = true, example = "1") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index dacd94b79..0c63e43b1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -20,18 +20,16 @@ import java.util.List; @ToString(callSuper = true) public class ProductSpuDetailRespVO extends ProductSpuBaseVO { - // TODO @puhui999:swagger 的 required 和 example 写下 - - @Schema(description = "商品 SPU 编号") + @Schema(description = "商品 SPU 编号", required = true, example = "1212") private Long id; - @Schema(description = "商品销量") + @Schema(description = "商品销量", required = true, example = "10000") private Integer salesCount; - @Schema(description = "浏览量") + @Schema(description = "浏览量", required = true, example = "20000") private Integer browseCount; - @Schema(description = "商品状态") + @Schema(description = "商品状态", required = true, example = "1") private Integer status; // ========== SKU 相关字段 ========= diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java index 56ae45deb..62da2747b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java @@ -16,6 +16,7 @@ import java.time.LocalDateTime; */ @Data public class ProductSpuExcelVO { + @ExcelProperty("商品编号") private Long id; @@ -116,4 +117,5 @@ public class ProductSpuExcelVO { @ExcelProperty("创建时间") private LocalDateTime createTime; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java index 01e752377..11260c1b2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java @@ -18,14 +18,14 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @AllArgsConstructor public class ProductSpuExportReqVO { - @Schema(description = "商品名称", example = "yutou") + @Schema(description = "商品名称", example = "清凉小短袖") private String name; @Schema(description = "前端请求的tab类型", example = "1") @InEnum(ProductSpuPageTabEnum.class) private Integer tabType; - @Schema(description = "商品分类编号") + @Schema(description = "商品分类编号", example = "100") private Long categoryId; @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 3f0ad57a8..9dca61d69 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -25,17 +25,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class ProductSpuPageReqVO extends PageParam { - @Schema(description = "商品名称", example = "yutou") + @Schema(description = "商品名称", example = "清凉小短袖") private String name; - @Schema(description = "前端请求的tab类型", example = "1") + @Schema(description = "前端请求的tab类型", required = true, example = "1") @InEnum(ProductSpuPageTabEnum.class) private Integer tabType; - @Schema(description = "商品分类编号") + @Schema(description = "商品分类编号", example = "1") private Long categoryId; - @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index adcc94100..39b35ae68 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -18,30 +18,28 @@ import java.time.LocalDateTime; @ToString(callSuper = true) public class ProductSpuRespVO extends ProductSpuBaseVO { - // TODO @puhui999:swagger 的 required 和 example 写下 - - @Schema(description = "spuId") + @Schema(description = "spuId", required = true, example = "111") private Long id; - @Schema(description = "商品价格") + @Schema(description = "商品价格", required = true, example = "1999") private Integer price; - @Schema(description = "商品销量") + @Schema(description = "商品销量", required = true, example = "2000") private Integer salesCount; - @Schema(description = "市场价,单位使用:分") + @Schema(description = "市场价,单位使用:分", required = true, example = "199") private Integer marketPrice; - @Schema(description = "成本价,单位使用:分") + @Schema(description = "成本价,单位使用:分", required = true, example = "19") private Integer costPrice; - @Schema(description = "商品库存") + @Schema(description = "商品库存", required = true, example = "10000") private Integer stock; - @Schema(description = "商品创建时间") + @Schema(description = "商品创建时间", required = true, example = "2023-05-24 00:00:00") private LocalDateTime createTime; - @Schema(description = "商品状态") + @Schema(description = "商品状态", required = true, example = "1") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java index 4df865af0..4ab766129 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -14,35 +14,33 @@ import lombok.ToString; @ToString(callSuper = true) public class ProductSpuSimpleRespVO { - // TODO @puhui999:swagger 的 required 和 example 写下 - - @Schema(description = "主键") + @Schema(description = "主键", required = true, example = "213") private Long id; - @Schema(description = "商品名称") + @Schema(description = "商品名称", required = true, example = "清凉小短袖") private String name; - @Schema(description = "商品价格,单位使用:分") + @Schema(description = "商品价格,单位使用:分", required = true, example = "1999") private Integer price; - @Schema(description = "商品市场价,单位使用:分") + @Schema(description = "商品市场价,单位使用:分", required = true, example = "199") private Integer marketPrice; - @Schema(description = "商品成本价,单位使用:分") + @Schema(description = "商品成本价,单位使用:分", required = true, example = "19") private Integer costPrice; - @Schema(description = "商品库存") + @Schema(description = "商品库存", required = true, example = "2000") private Integer stock; // ========== 统计相关字段 ========= - @Schema(description = "商品销量") + @Schema(description = "商品销量", required = true, example = "200") private Integer salesCount; - @Schema(description = "商品虚拟销量") + @Schema(description = "商品虚拟销量", required = true, example = "20000") private Integer virtualSalesCount; - @Schema(description = "商品浏览量") + @Schema(description = "商品浏览量", required = true, example = "2000") private Integer browseCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 61230242f..f4bd3cdae 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -23,19 +23,17 @@ import java.util.List; @ToString(callSuper = true) public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { - // TODO @puhui999:swagger 的 required 和 example 写下 - @Schema(description = "商品编号", required = true, example = "1") @NotNull(message = "商品编号不能为空") private Long id; - @Schema(description = "商品销量") + @Schema(description = "商品销量", required = true, example = "1999") private Integer salesCount; - @Schema(description = "浏览量") + @Schema(description = "浏览量", required = true, example = "1999") private Integer browseCount; - @Schema(description = "商品状态") + @Schema(description = "商品状态", required = true, example = "1") @InEnum(ProductSpuStatusEnum.class) private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index fe1a8ee87..2a0f4cd68 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -67,8 +67,7 @@ public class AppProductSpuController { } // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), - CommonStatusEnum.ENABLE.getStatus()); + List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId()); // 查询商品属性 List propertyValues = productPropertyValueService .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index dd69646af..96cd7e41b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -43,8 +43,6 @@ public interface ProductSkuConvert { ProductSkuRespDTO convert02(ProductSkuDO bean); - List convertList03(List list); - List convertList04(List list); List convertList05(List skus); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 052ac287d..62c47bfb6 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -16,6 +16,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; import java.util.ArrayList; @@ -52,55 +54,38 @@ public interface ProductSpuConvert { List convertList02(List list); - // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 - default List convertList03(List list){ - ArrayList spuExcelVOs = new ArrayList<>(); - list.forEach((spu)->{ - ProductSpuExcelVO spuExcelVO = new ProductSpuExcelVO(); - spuExcelVO.setId(spu.getId()); - spuExcelVO.setName(spu.getName()); - spuExcelVO.setKeyword(spu.getKeyword()); - spuExcelVO.setIntroduction(spu.getIntroduction()); - spuExcelVO.setDescription(spu.getDescription()); - spuExcelVO.setBarCode(spu.getBarCode()); - spuExcelVO.setCategoryId(spu.getCategoryId()); - spuExcelVO.setBrandId(spu.getBrandId()); - spuExcelVO.setPicUrl(spu.getPicUrl()); - spuExcelVO.setSliderPicUrls(StrUtil.toString(spu.getSliderPicUrls())); - spuExcelVO.setVideoUrl(spu.getVideoUrl()); - spuExcelVO.setUnit(spu.getUnit()); - spuExcelVO.setSort(spu.getSort()); - spuExcelVO.setStatus(spu.getStatus()); - spuExcelVO.setSpecType(spu.getSpecType()); - spuExcelVO.setPrice(spu.getPrice()/100); - spuExcelVO.setMarketPrice(spu.getMarketPrice()/100); - spuExcelVO.setCostPrice(spu.getCostPrice()/100); - spuExcelVO.setStock(spu.getStock()); - spuExcelVO.setDeliveryTemplateId(spu.getDeliveryTemplateId()); - spuExcelVO.setRecommendHot(spu.getRecommendHot()); - spuExcelVO.setRecommendBenefit(spu.getRecommendBenefit()); - spuExcelVO.setRecommendBest(spu.getRecommendBest()); - spuExcelVO.setRecommendNew(spu.getRecommendNew()); - spuExcelVO.setRecommendGood(spu.getRecommendGood()); - spuExcelVO.setGiveIntegral(spu.getGiveIntegral()); - spuExcelVO.setGiveCouponTemplateIds(StrUtil.toString(spu.getGiveCouponTemplateIds())); // TODO 暂定 - spuExcelVO.setSubCommissionType(spu.getSubCommissionType()); - spuExcelVO.setActivityOrders(StrUtil.toString(spu.getActivityOrders())); // TODO 暂定 - spuExcelVO.setSalesCount(spu.getSalesCount()); - spuExcelVO.setVirtualSalesCount(spu.getVirtualSalesCount()); - spuExcelVO.setBrowseCount(spu.getBrowseCount()); - spuExcelVO.setCreateTime(spu.getCreateTime()); + /** + * 列表转字符串 + * + * @param list 列表 + * @return 字符串 + */ + @Named("convertListToString") + default String convertListToString(List list) { + return StrUtil.toString(list); + } + + // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 fix:哈哈 这样确实丝滑哈 + + @Mapping(source = "sliderPicUrls", target = "sliderPicUrls", qualifiedByName = "convertListToString") + @Mapping(source = "giveCouponTemplateIds", target = "giveCouponTemplateIds", qualifiedByName = "convertListToString") + @Mapping(source = "activityOrders", target = "activityOrders", qualifiedByName = "convertListToString") + @Mapping(target = "price", expression = "java(spu.getPrice() / 100)") + @Mapping(target = "marketPrice", expression = "java(spu.getMarketPrice() / 100)") + @Mapping(target = "costPrice", expression = "java(spu.getCostPrice() / 100)") + ProductSpuExcelVO convert(ProductSpuDO spu); + + default List convertList03(List list) { + List spuExcelVOs = new ArrayList<>(); + list.forEach(spu -> { + ProductSpuExcelVO spuExcelVO = convert(spu); spuExcelVOs.add(spuExcelVO); }); return spuExcelVOs; } + ProductSpuDetailRespVO convert03(ProductSpuDO spu); - // TODO @puhui999:下面两个没用到,是不是删除呀? - List convertList04(List skus); - - ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); - // ========== 用户 App 相关 ========== default PageResult convertPageForGetSpuPage(PageResult page) { @@ -144,26 +129,15 @@ public interface ProductSpuConvert { AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); - default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus, - Function, List> func) { + default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus) { ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu); - // TODO @puhui999:if return 哈,减少嵌套层数。 - if (CollUtil.isNotEmpty(skus)) { - List skuVOs = ProductSkuConvert.INSTANCE.convertList(skus); - // fix:统一模型,即使是单规格,也查询下,如若 Properties 为空报错则为单属性不做处理 - try { - // 获取所有的属性值 id - Set valueIds = skus.stream().flatMap(p -> p.getProperties().stream()) - .map(ProductSkuDO.Property::getValueId) - .collect(Collectors.toSet()); - List valueDetailList = func.apply(valueIds); - Map stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName)); - // 设置属性值名称 - skuVOs.stream().flatMap(p -> p.getProperties().stream()).forEach(item -> item.setValueName(stringMap.get(item.getValueId()))); - } catch (Exception ignored) { - } - productSpuDetailRespVO.setSkus(skuVOs); + // skus 为空直接返回 + if (CollUtil.isEmpty(skus)) { + return productSpuDetailRespVO; } + List skuVOs = ProductSkuConvert.INSTANCE.convertList(skus); + // fix: 因为现在已改为 sku 属性列表 属性 已包含 属性名字 属性值名字 所以不需要再额外处理,属性更新时更新 sku 中的属性相关冗余即可 + productSpuDetailRespVO.setSkus(skuVOs); return productSpuDetailRespVO; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 6c3a9a020..fa576683b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -19,7 +19,7 @@ import java.util.List; * * @author 芋道源码 */ -@TableName(value = "product_sku",autoResultMap = true) +@TableName(value = "product_sku", autoResultMap = true) @KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java index e66a6ed2b..b2c4bd5fb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java @@ -31,8 +31,7 @@ public interface ProductBrandMapper extends BaseMapperX { return selectOne(ProductBrandDO::getName, name); } - // TODO @puhui999:) { 中间要有空格哈。 - default List selectListByStatus(Integer status){ - return selectList(ProductBrandDO::getStatus,status); + default List selectListByStatus(Integer status) { + return selectList(ProductBrandDO::getStatus, status); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 96378faf7..75963e3e1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -23,11 +23,9 @@ public interface ProductSkuMapper extends BaseMapperX { return selectList(ProductSkuDO::getSpuId, spuId); } - default List selectListBySpuIdAndStatus(Long spuId, - Integer status) { + default List selectListBySpuIdAndStatus(Long spuId) { return selectList(new LambdaQueryWrapperX() - .eq(ProductSkuDO::getSpuId, spuId)// eqIfPresent(ProductSkuDO::getStatus, status) TODO ProductSkuDO已经没有status属性 - ); + .eq(ProductSkuDO::getSpuId, spuId)); } default List selectListBySpuId(Collection spuIds) { @@ -41,7 +39,7 @@ public interface ProductSkuMapper extends BaseMapperX { /** * 更新 SKU 库存(增加) * - * @param id 编号 + * @param id 编号 * @param incrCount 增加库存(正数) */ default void updateStockIncr(Long id, Integer incrCount) { @@ -55,7 +53,7 @@ public interface ProductSkuMapper extends BaseMapperX { /** * 更新 SKU 库存(减少) * - * @param id 编号 + * @param id 编号 * @param incrCount 减少库存(负数) * @return 更新条数 */ @@ -68,8 +66,8 @@ public interface ProductSkuMapper extends BaseMapperX { return update(null, updateWrapper); } - default List selectListByAlarmStock(){ - return selectList(new QueryWrapper().apply("stock <= warn_stock")); + default List selectListByAlarmStock() { + return selectList(new QueryWrapper().apply("stock <= warn_stock")); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 14f6fae58..abf357c24 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -35,21 +35,21 @@ public interface ProductSpuMapper extends BaseMapperX { .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(ProductSpuDO::getSort); - validateTabType(tabType, queryWrapper); + appendTabQuery(tabType, queryWrapper); return selectPage(reqVO, queryWrapper); } /** - * 获取库存小于 value ,且状态不等于 status 的的个数 + * 查询触发警戒库存的 SPU 数量 * - * @return 个数 + * @return 触发警戒库存的 SPU 数量 */ - default Long selectCountByStockAndStatus() { + default Long selectCount() { LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); + // 库存小于等于警戒库存 queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) - // TODO @puhui999:IN 另外两个状态,会不会好点哈。尽量不用 != // 如果库存触发警戒库存且状态为回收站的话则不计入触发警戒库存的个数 - .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); return selectCount(queryWrapper); } @@ -101,43 +101,43 @@ public interface ProductSpuMapper extends BaseMapperX { * @param reqVO 查询条件 * @return Spu 列表 */ - default List selectList(ProductSpuExportReqVO reqVO){ + default List selectList(ProductSpuExportReqVO reqVO) { Integer tabType = reqVO.getTabType(); LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); - queryWrapper.eqIfPresent(ProductSpuDO::getName,reqVO.getName()); - queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId,reqVO.getCategoryId()); - queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime,reqVO.getCreateTime()); - validateTabType(tabType, queryWrapper); + queryWrapper.eqIfPresent(ProductSpuDO::getName, reqVO.getName()); + queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()); + queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime()); + appendTabQuery(tabType, queryWrapper); return selectList(queryWrapper); } - // TODO @puhui999:应该不太适合 validate 验证,应该是补充条件,例如说 appendTabQuery /** * 验证选项卡类型构建条件 * * @param tabType 标签类型 * @param queryWrapper 查询条件 */ - static void validateTabType(Integer tabType, LambdaQueryWrapperX queryWrapper) { - // 出售中商品 TODO puhui999:这样好点 + static void appendTabQuery(Integer tabType, LambdaQueryWrapperX queryWrapper) { + // 出售中商品 if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) { queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); } + // 仓储中商品 if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) { - // 仓储中商品 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); } + // 已售空商品 if (ObjectUtil.equals(ProductSpuPageTabEnum.SOLD_OUT.getType(), tabType)) { - // 已售空商品 queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0); } + // 警戒库存 if (ObjectUtil.equals(ProductSpuPageTabEnum.ALERT_STOCK.getType(), tabType)) { queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示 - .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } + // 回收站 if (ObjectUtil.equals(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), tabType)) { - // 回收站 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 0b34cc2d8..8438db684 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -88,14 +88,10 @@ public interface ProductSkuService { /** * 基于 SPU 编号和状态,获得商品 SKU 集合 * - * TODO @puhui999:SKU中已经不存在status属性;芋艿:那就去掉 status 哈 - * * @param spuId SPU 编号 - * @param status 状态 * @return 商品 SKU 集合 */ - List getSkuListBySpuIdAndStatus(Long spuId, - @Nullable Integer status); + List getSkuListBySpuIdAndStatus(Long spuId); /** * 获得 spu 对应的 SKU 集合 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index a03c94240..1bb129876 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -3,14 +3,12 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; -import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; @@ -85,7 +83,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { } // 0、校验skus是否为空 - if (CollUtil.isEmpty(skus)){ + if (CollUtil.isEmpty(skus)) { throw exception(SKU_NOT_EXISTS); } @@ -140,8 +138,8 @@ public class ProductSkuServiceImpl implements ProductSkuService { } @Override - public List getSkuListBySpuIdAndStatus(Long spuId, Integer status) { - return productSkuMapper.selectListBySpuIdAndStatus(spuId, status); + public List getSkuListBySpuIdAndStatus(Long spuId) { + return productSkuMapper.selectListBySpuIdAndStatus(spuId); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 12233d246..859450510 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -51,8 +50,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { private ProductBrandService brandService; @Resource private ProductCategoryService categoryService; - @Resource - private ProductPropertyValueService productPropertyValueService; @Override @Transactional(rollbackFor = Exception.class) @@ -63,10 +60,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 校验 SKU List skuSaveReqList = createReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); + ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); // 初始化 SPU 中 SKU 相关属性 initSpuFromSkus(spu, skuSaveReqList); - // 插入 SPU productSpuMapper.insert(spu); // 插入 SKU @@ -86,7 +83,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 校验SKU List skuSaveReqList = updateReqVO.getSkus(); productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); - // TODO @puhui999:可以校验逻辑,和更新逻辑,中间有个空行,这样会发现,哟 这里到了关键逻辑啦,更有层次感 + // 更新 SPU ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); initSpuFromSkus(updateObj, skuSaveReqList); @@ -103,20 +100,14 @@ public class ProductSpuServiceImpl implements ProductSpuService { * @param skus 商品 SKU 数组 */ private void initSpuFromSkus(ProductSpuDO spu, List skus) { - // 断言,避免告警 - assert skus.size() > 0; - // 获取 sku 单价最低的商品 - // TODO @puhui999:vo 改成 sku 会更好。vo dto 只是我们用来区分的,如果能区分的情况下,用更明确的名字会更好。 -// CollectionUtils.getMinValue(); TODO @puhui999:可以用这个方法,常见的 stream 操作,封装成方法,让逻辑更简洁 - ProductSkuCreateOrUpdateReqVO vo = skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateReqVO::getPrice)).get(); // sku 单价最低的商品的价格 - spu.setPrice(vo.getPrice()); + spu.setPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); // sku 单价最低的商品的市场价格 - spu.setMarketPrice(vo.getMarketPrice()); + spu.setMarketPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); // sku单价最低的商品的成本价格 - spu.setCostPrice(vo.getCostPrice()); + spu.setCostPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice)); // sku单价最低的商品的条形码 - spu.setBarCode(vo.getBarCode()); + spu.setBarCode(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); // skus 库存总数 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); // 若是 spu 已有状态则不处理 @@ -150,6 +141,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { validateSpuExists(id); // 校验商品状态不是回收站不能删除 validateSpuStatus(id); + // 删除 SPU productSpuMapper.deleteById(id); // 删除关联的 SKU @@ -229,8 +221,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { } // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); - // TODO @puhui999:感觉还是查询好 productPropertyValueService,然后 propertyId 可以交给 convert 处理下即可。 - return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus, productPropertyValueService::getPropertyValueDetailList); + return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus); } @Override @@ -238,10 +229,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO) { // 校验存在 validateSpuExists(updateReqVO.getId()); + // 更新状态 ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus()); productSpuMapper.updateById(productSpuDO); - } @Override @@ -254,7 +245,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 查询售空的商品数量 counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); // 查询触发警戒库存的商品数量 - counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCountByStockAndStatus()); + counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCount()); // 查询回收站中的商品数量 counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); return counts; From 0083d1240423338605ab8ec3ea03633d0f3d543c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 25 May 2023 22:51:38 +0800 Subject: [PATCH 060/232] =?UTF-8?q?mall=EF=BC=9Areview=20+=20mall=EF=BC=9A?= =?UTF-8?q?=E5=BF=AB=E9=80=92=E8=B4=B9=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../delivery/DeliveryExpressController.java | 1 + .../DeliveryExpressTemplateConvert.java | 57 +++++++++++-------- .../DeliveryExpressTemplateMapper.java | 4 +- .../DeliveryExpressTemplateServiceImpl.java | 13 +++-- .../controller/admin/ip/AreaController.java | 7 ++- .../admin/ip/vo/LazyAreaNodeRespVO.java | 3 + 6 files changed, 53 insertions(+), 32 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index fde0b5d79..b245ec860 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -74,6 +74,7 @@ public class DeliveryExpressController { return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); } + // TODO @jason:运费模版,可以去掉哈,没啥用; @GetMapping("/export-excel") @Operation(summary = "导出快递公司 Excel") @PreAuthorize("@ss.hasPermission('trade:delivery:express:export')") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index dbbb7ba83..d4d23cb0a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -1,10 +1,7 @@ package cn.iocoder.yudao.module.trade.convert.delivery; -import java.util.*; - import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; - import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; @@ -12,6 +9,10 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * 快递运费模板 Convert * @@ -22,6 +23,8 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateConvert INSTANCE = Mappers.getMapper(DeliveryExpressTemplateConvert.class); + // ========== Template ========== + DeliveryExpressTemplateDO convert(DeliveryExpressTemplateCreateReqVO bean); DeliveryExpressTemplateDO convert(DeliveryExpressTemplateUpdateReqVO bean); @@ -36,10 +39,35 @@ public interface DeliveryExpressTemplateConvert { List convertList02(List list); + default DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean, + List chargeList, + List freeList){ + DeliveryExpressTemplateRespVO respVO = convert2(bean); + respVO.setTemplateCharge(convertTemplateChargeList(chargeList)); + respVO.setTemplateFree(convertTemplateFreeList(freeList)); + return respVO; + } + + // ========== Template Charge ========== + DeliveryExpressTemplateChargeDO convertTemplateCharge(Long templateId, Integer chargeMode, ExpressTemplateChargeBaseVO vo); DeliveryExpressTemplateChargeDO convertTemplateCharge(ExpressTemplateChargeUpdateVO vo); + default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { + // TODO @jason:可以使用 CollectionUtils.convertList,本质上就是 stream convert list + if(CollUtil.isEmpty(list)){ + return Collections.emptyList(); + } + List templateChargeList = new ArrayList<>(list.size()); + for (ExpressTemplateChargeBaseVO item : list) { + templateChargeList.add(convertTemplateCharge(templateId, chargeMode, item)); + } + return templateChargeList; + } + + // ========== Template Free ========== + DeliveryExpressTemplateFreeDO convertTemplateFree(Long templateId, ExpressTemplateFreeBaseVO vo); DeliveryExpressTemplateFreeDO convertTemplateFree(ExpressTemplateFreeUpdateVO vo); @@ -48,20 +76,9 @@ public interface DeliveryExpressTemplateConvert { List convertTemplateFreeList(List list); - default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list){ - if(CollUtil.isEmpty(list)){ - return Collections.emptyList(); - } - List templateChargeList = new ArrayList<>( list.size() ); - for (ExpressTemplateChargeBaseVO item : list) { - templateChargeList.add(convertTemplateCharge(templateId, chargeMode, item)); - } - return templateChargeList; - } - - - + // TODO @jason:, List,中间一个空格哈。代码的空格和空行要注意,嘿嘿~ default List convertTemplateFreeList(Long templateId, List list) { + // TODO @jason:可以使用 CollectionUtils.convertList,本质上就是 stream convert list if (CollUtil.isEmpty(list)) { return Collections.emptyList(); } @@ -72,12 +89,4 @@ public interface DeliveryExpressTemplateConvert { return templateFreeList; } - default DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean, - List chargeList, - List freeList){ - DeliveryExpressTemplateRespVO respVO = convert2(bean); - respVO.setTemplateCharge(convertTemplateChargeList(chargeList)); - respVO.setTemplateFree(convertTemplateFreeList(freeList)); - return respVO; - } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java index 4f7460350..85b52851e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java @@ -3,11 +3,9 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; - import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplateExportReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplatePageReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -33,8 +31,10 @@ public interface DeliveryExpressTemplateMapper extends BaseMapperX() .eq(DeliveryExpressTemplateDO::getName, name)); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 420e70687..76182eed7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -36,6 +36,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; @Resource private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; + // TODO @jason:应该不用 BatchInsertMapper 拉,直接走 expressTemplateChargeMapper.insertBatch @Resource private DeliveryExpressTemplateChargeMapper.BatchInsertMapper expressTemplateChargeBatchMapper; @Resource @@ -44,12 +45,15 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla @Override @Transactional(rollbackFor = Exception.class) public Long createDeliveryExpressTemplate(DeliveryExpressTemplateCreateReqVO createReqVO) { + // TODO @jason:中英文之间,要有空格哈。例如说, // 校验模板名是否唯一 //校验模板名是否唯一 validateTemplateNameUnique(createReqVO.getName(), null); + // 插入 DeliveryExpressTemplateDO deliveryExpressTemplate = INSTANCE.convert(createReqVO); expressTemplateMapper.insert(deliveryExpressTemplate); //插入运费模板计费表 + // TODO @jason:if (,中间要有空格 if(CollUtil.isNotEmpty(createReqVO.getTemplateCharge())) { expressTemplateChargeBatchMapper.saveBatch( INSTANCE.convertTemplateChargeList(deliveryExpressTemplate.getId(), createReqVO.getChargeMode(), createReqVO.getTemplateCharge()) @@ -121,7 +125,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla //更新运费区域列表 List updateList = new ArrayList<>(newChargeList.size()); for (ExpressTemplateChargeUpdateVO item : newChargeList) { - if (Objects.nonNull(item.getId())) { + if (Objects.nonNull(item.getId())) { // TODO @jason:null 的判断,还是用 item.getId() != null 好一点。一般数组用方法,主要考虑 null + length = 0; //计费模式以主表为准 item.setChargeMode(updateReqVO.getChargeMode()); updateList.add(INSTANCE.convertTemplateCharge(item)); @@ -131,7 +135,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla addList.add(INSTANCE.convertTemplateCharge(item)); } } - //删除的运费区域id + //删除的运费区域id TODO @jason:这块放到删除部分的那块逻辑会好点(149 - 152 行),主要变量要贴相应的逻辑近一点哈。 Set deleteChargeIds = CollectionUtils.convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId); deleteChargeIds.removeAll(CollectionUtils.convertSet(updateList, DeliveryExpressTemplateChargeDO::getId)); //新增 @@ -153,6 +157,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public void deleteDeliveryExpressTemplate(Long id) { // 校验存在 validateDeliveryExpressTemplateExists(id); + // 删除主表 expressTemplateMapper.deleteById(id); // 删除运费从表 @@ -162,9 +167,9 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } /** - * 校验运费模板名是否唯一 + * 校验运费模板名是否唯一 // TODO @jason:方法注释,和参数,要空一行。 * @param name 模板名称 - * @param id 运费模板编号, 可以为null + * @param id 运费模板编号, 可以为null // TODO @jason:中英文之间,要空一行;其它地方也看看哈 */ private void validateTemplateNameUnique(String name, Long id) { DeliveryExpressTemplateDO template = expressTemplateMapper.selectByName(name); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index 87e6e0bfd..0988cbe90 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -15,7 +15,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Set; @@ -35,6 +34,8 @@ public class AreaController { return success(AreaConvert.INSTANCE.convertList(area.getChildren())); } + // TODO @jason:1)url 使用中划线分隔哈,然后可以改成 children;2)id 需要添加 @RequestParam,因为可能会混淆编译; + // 3) swagger 注解要写下哈; @GetMapping("/getChildrenArea") @Operation(summary = "获得地区的下级区域") public CommonResult> getChildrenArea(Integer id) { @@ -43,8 +44,10 @@ public class AreaController { return success(AreaConvert.INSTANCE.convertList2(area.getChildren())); } + // TODO @jason:1)读请求,使用 get 哈。2)然后参数不应该使用 @RequestBody;3)areaIds 改成 ids 更合适; + // 4)方法改成 getAreaChildrenList 获得子节点们;5)url 可以已改成 children-list @PostMapping("/list") - @Operation(summary = "通过区域ids获得地区列表") + @Operation(summary = "通过区域 ids 获得地区列表") public CommonResult> list(@RequestBody Set areaIds) { List areaList = new ArrayList<>(areaIds.size()); for (Integer areaId : areaIds) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java index fd184b307..e95defb1c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.ip.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +// TODO @jason:1)VO 不添加注释作者哈。2)是不是改成 AreaNodeSimpleRespVO,它其实是返回一个简洁的地区,懒加载只是它的使用场景; /** * @author jason */ @@ -16,6 +17,8 @@ public class LazyAreaNodeRespVO { @Schema(description = "名字", required = true, example = "北京") private String name; + // TODO @jason:1)不设置默认值,交给业务逻辑那写入;2)这个字段必须返回哇? @Schema(description = "是否叶子节点", required = true, example = "false") private Boolean leaf = Boolean.FALSE; + } From 02fa6fc5c6187bc1c731e11f574675d7aac410fc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 26 May 2023 23:58:26 +0800 Subject: [PATCH 061/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=BB=B7=E6=A0=BC=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=98=93=E6=87=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/price/dto/PriceCalculateRespDTO.java | 12 ++--- .../promotion/convert/price/PriceConvert.java | 6 +-- .../service/price/PriceServiceImpl.java | 7 ++- .../service/price/PriceServiceTest.java | 29 +++++----- .../admin/order/vo/TradeOrderBaseVO.java | 3 -- .../order/vo/AppTradeOrderDetailRespVO.java | 5 +- .../dal/dataobject/order/TradeOrderDO.java | 27 +++------- .../dataobject/order/TradeOrderItemDO.java | 53 ++++++++++--------- .../aftersale/TradeAfterSaleServiceImpl.java | 2 +- .../service/order/TradeOrderServiceTest.java | 7 +-- 10 files changed, 58 insertions(+), 93 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java index cda6d99d6..a067aa0b5 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -38,6 +38,7 @@ public class PriceCalculateRespDTO { */ private List promotions; + // TODO @芋艿:需要改造下,主要是价格字段 /** * 订单 */ @@ -51,14 +52,7 @@ public class PriceCalculateRespDTO { * * 对应 taobao 的 trade.total_fee 字段 */ - private Integer originalPrice; - /** - * 订单原价(总),单位:分 - * - * 基于 {@link OrderItem#getPayPrice()} 求和 - * 和 {@link #originalPrice} 的差异:去除商品级优惠 - */ - private Integer orderPrice; + private Integer totalPrice; /** * 订单优惠(总),单位:分 * @@ -207,7 +201,7 @@ public class PriceCalculateRespDTO { /** * 计算时的原价(总),单位:分 */ - private Integer originalPrice; + private Integer totalPrice; /** * 计算时的优惠(总),单位:分 */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java index 8e4b24666..e8649cb61 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java @@ -22,7 +22,7 @@ public interface PriceConvert { // 创建 PriceCalculateRespDTO 对象 PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 创建它的 Order 属性 - PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setOriginalPrice(0).setDiscountPrice(0) + PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setTotalPrice(0).setDiscountPrice(0) .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); @@ -38,8 +38,8 @@ public interface PriceConvert { orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); priceCalculate.getOrder().getItems().add(orderItem); // 补充价格信息到 Order 中 - order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()) - .setOrderPrice(order.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); + order.setTotalPrice(order.getTotalPrice() + orderItem.getOriginalPrice()) + .setPayPrice(order.getTotalPrice()); }); return priceCalculate; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java index 03abb061f..7aab0bee5 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java @@ -406,7 +406,7 @@ public class PriceServiceImpl implements PriceService { // 创建营销明细 PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) + .setTotalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); priceCalculate.getPromotions().add(promotion); } @@ -437,7 +437,7 @@ public class PriceServiceImpl implements PriceService { // 创建营销明细 PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) + .setTotalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); priceCalculate.getPromotions().add(promotion); @@ -453,7 +453,7 @@ public class PriceServiceImpl implements PriceService { Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(originalPrice).setDiscountPrice(0) + .setTotalPrice(originalPrice).setDiscountPrice(0) .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); priceCalculate.getPromotions().add(promotion); } @@ -476,7 +476,6 @@ public class PriceServiceImpl implements PriceService { // 设置 Order 相关相关字段 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); order.setPayPrice(order.getPayPrice() - diffPayPrice); - order.setOrderPrice(order.getOrderPrice() - diffPayPrice); } /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 0c7b2d6ec..9e40ff67b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -70,8 +70,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 200); - assertEquals(order.getOrderPrice(), 180); + assertEquals(order.getTotalPrice(), 200); assertEquals(order.getDiscountPrice(), 0); assertEquals(order.getPointPrice(), 0); assertEquals(order.getDeliveryPrice(), 0); @@ -95,7 +94,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion.getName(), "会员折扣"); assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion.getOriginalPrice(), 200); + assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getDiscountPrice(), 20); assertTrue(promotion.getMeet()); assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); @@ -133,8 +132,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getOrderPrice(), 210); + assertEquals(order.getTotalPrice(), 350); assertEquals(order.getDiscountPrice(), 0); assertEquals(order.getPointPrice(), 0); assertEquals(order.getDeliveryPrice(), 0); @@ -167,7 +165,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 200); + assertEquals(promotion01.getTotalPrice(), 200); assertEquals(promotion01.getDiscountPrice(), 80); assertTrue(promotion01.getMeet()); assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); @@ -181,7 +179,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 150); + assertEquals(promotion02.getTotalPrice(), 150); assertEquals(promotion02.getDiscountPrice(), 60); assertTrue(promotion02.getMeet()); assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); @@ -225,8 +223,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getOrderPrice(), 470); + assertEquals(order.getTotalPrice(), 470); assertEquals(order.getDiscountPrice(), 130); assertEquals(order.getPointPrice(), 0); assertEquals(order.getDeliveryPrice(), 0); @@ -268,7 +265,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMeet()); assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); @@ -287,7 +284,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 120); + assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getDiscountPrice(), 60); assertTrue(promotion02.getMeet()); assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); @@ -323,8 +320,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getOrderPrice(), 350); + assertEquals(order.getTotalPrice(), 350); assertEquals(order.getDiscountPrice(), 0); assertEquals(order.getPointPrice(), 0); assertEquals(order.getDeliveryPrice(), 0); @@ -357,7 +353,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 0); assertFalse(promotion01.getMeet()); assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 @@ -396,8 +392,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getOrderPrice(), 470); + assertEquals(order.getTotalPrice(), 470); assertEquals(order.getDiscountPrice(), 0); assertEquals(order.getPointPrice(), 0); assertEquals(order.getDeliveryPrice(), 0); @@ -440,7 +435,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getName(), "程序员节"); assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMeet()); assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java index a1428c436..3453a3c2e 100755 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java @@ -73,9 +73,6 @@ public class TradeOrderBaseVO { @Schema(description = "商品原价(总)", required = true, example = "1000") private Integer originalPrice; - @Schema(description = "订单原价(总)", required = true, example = "1000") - private Integer orderPrice; - @Schema(description = "订单优惠(总)", required = true, example = "100") private Integer discountPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java index fd54444db..647ea2638 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java @@ -59,10 +59,7 @@ public class AppTradeOrderDetailRespVO { private String payChannelCode; @Schema(description = "商品原价(总)", required = true, example = "1000") - private Integer originalPrice; - - @Schema(description = "订单原价(总)", required = true, example = "1000") - private Integer orderPrice; + private Integer totalPrice; @Schema(description = "订单优惠(总)", required = true, example = "100") private Integer discountPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 0faa67db3..f4d27a3ae 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -2,13 +2,8 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderDeliveryStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.*; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -134,25 +129,15 @@ public class TradeOrderDO extends BaseDO { private String payChannelCode; /** - * 商品原价(总),单位:分 + * 商品原价,单位:分 * * totalPrice = {@link TradeOrderItemDO#getPrice()} * {@link TradeOrderItemDO#getCount()} 求和 * * 对应 taobao 的 trade.total_fee 字段 */ private Integer totalPrice; - // TODO 芋艿:是不是要删除这个字段? /** - * 订单原价(总),单位:分 - * - * 1. orderPrice = {@link OrderItem#getPayPrice()} 求和 - * 2. orderPrice = {@link #totalPrice} - 商品级优惠 - */ - private Integer orderPrice; - /** - * 订单优惠(总),单位:分 - * - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 + * 优惠金额,单位:分 * * 对应 taobao 的 order.discount_fee 字段 */ @@ -162,7 +147,7 @@ public class TradeOrderDO extends BaseDO { */ private Integer deliveryPrice; /** - * 订单调价(总),单位:分 + * 订单调价,单位:分 * * 正数,加价;负数,减价 */ @@ -170,11 +155,11 @@ public class TradeOrderDO extends BaseDO { /** * 应付金额(总),单位:分 * - * = {@link OrderItem#getPayPrice()} 求和 + * = {@link #totalPrice} * - {@link #couponPrice} * - {@link #pointPrice} - * + {@link #deliveryPrice} * - {@link #discountPrice} + * + {@link #deliveryPrice} * + {@link #adjustPrice} */ private Integer payPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index 42fc106f5..323389c94 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -102,44 +102,47 @@ public class TradeOrderItemDO extends BaseDO { */ private Integer price; /** - * 商品优惠(总),单位:分 - * - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 + * 优惠金额(总),单位:分 * * 对应 taobao 的 order.discount_fee 字段 */ private Integer discountPrice; /** - * 子订单实付金额(总),不算主订单分摊金额,单位:分 + * 运费金额(总),单位:分 + */ + private Integer deliveryPrice; + /** + * 订单调价(总),单位:分 + * + * 正数,加价;负数,减价 + */ + private Integer adjustPrice; + /** + * 应付金额(总),单位:分 * * = {@link #price} * {@link #count} + * - {@link #couponPrice} + * - {@link #pointPrice} * - {@link #discountPrice} - * - * 对应 taobao 的 order.payment 字段 + * + {@link #deliveryPrice} + * + {@link #adjustPrice} */ private Integer payPrice; - /** - * 子订单分摊金额(总),单位:分 - * 需要分摊 {@link TradeOrderDO#getDiscountPrice()}、{@link TradeOrderDO#getCouponPrice()}、{@link TradeOrderDO#getPointPrice()} - * - * 对应 taobao 的 order.part_mjz_discount 字段 - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 - */ - private Integer orderPartPrice; - /** - * 分摊后子订单实付金额(总),单位:分 - * - * = {@link #payPrice} - * - {@link #orderPartPrice} - * - * 对应 taobao 的 divide_order_fee 字段 - */ - private Integer orderDividePrice; - // ========== 营销基本信息 ========== - // TODO 芋艿:在捉摸一下 + /** + * 优惠劵减免金额,单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; // ========== 售后基本信息 ========== /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java index 2da892d61..374af0a16 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java @@ -97,7 +97,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { } // 申请的退款金额,不能超过商品的价格 - if (createReqVO.getRefundPrice() > orderItem.getOrderDividePrice()) { + if (createReqVO.getRefundPrice() > orderItem.getPayPrice()) { throw exception(AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 0b4c3de2d..064ec336e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -124,7 +124,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { .setSpuId(21L).setSkuId(2L).setCount(4).setOriginalPrice(80).setOriginalUnitPrice(20) .setDiscountPrice(40).setPayPrice(40).setOrderPartPrice(15).setOrderDividePrice(25); PriceCalculateRespDTO.Order priceOrder = new PriceCalculateRespDTO.Order() - .setOriginalPrice(230).setOrderPrice(100).setDiscountPrice(0).setCouponPrice(30) + .setTotalPrice(230).setDiscountPrice(0).setCouponPrice(30) .setPointPrice(10).setDeliveryPrice(20).setPayPrice(80).setCouponId(101L).setCouponPrice(30) .setItems(Arrays.asList(priceOrderItem01, priceOrderItem02)); when(priceApi.calculatePrice(argThat(priceCalculateReqDTO -> { @@ -170,7 +170,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertFalse(tradeOrderDO.getPayed()); assertNull(tradeOrderDO.getPayTime()); assertEquals(tradeOrderDO.getTotalPrice(), 230); - assertEquals(tradeOrderDO.getOrderPrice(), 100); assertEquals(tradeOrderDO.getDiscountPrice(), 0); assertEquals(tradeOrderDO.getAdjustPrice(), 0); assertEquals(tradeOrderDO.getPayPrice(), 80); @@ -208,8 +207,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertEquals(tradeOrderItemDO01.getPrice(), 50); assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); assertEquals(tradeOrderItemDO01.getPayPrice(), 130); - assertEquals(tradeOrderItemDO01.getOrderPartPrice(), 7); - assertEquals(tradeOrderItemDO01.getOrderDividePrice(), 35); assertEquals(tradeOrderItemDO01.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); // 断言 TradeOrderItemDO 订单(第 2 个) TradeOrderItemDO tradeOrderItemDO02 = tradeOrderItemDOs.get(1); @@ -228,8 +225,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertEquals(tradeOrderItemDO02.getPrice(), 20); assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); assertEquals(tradeOrderItemDO02.getPayPrice(), 40); - assertEquals(tradeOrderItemDO02.getOrderPartPrice(), 15); - assertEquals(tradeOrderItemDO02.getOrderDividePrice(), 25); assertEquals(tradeOrderItemDO02.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); // 校验调用 verify(productSkuApi).updateSkuStock(argThat(updateStockReqDTO -> { From 55dbff7570caf069efe2495b6c048e90c12d51b0 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 27 May 2023 11:20:43 +0800 Subject: [PATCH 062/232] =?UTF-8?q?=E8=BF=90=E8=B4=B9=E6=A8=A1=E6=9D=BF=20?= =?UTF-8?q?review=20=E4=BF=AE=E6=94=B9.=20=E8=BF=90=E8=B4=B9=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=8F=AF=E4=BB=A5=E9=80=89=E6=8B=A9=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 6 +- .../common/util/string/StrUtils.java | 6 ++ .../mybatis/core/mapper/BaseMapperX.java | 10 ++ .../core/type/IntegerListTypeHandler.java | 56 ++++++++++ .../delivery/DeliveryExpressController.java | 2 +- .../DeliveryExpressTemplateController.java | 13 --- .../delivery/vo/DeliveryExpressExcelVO.java | 11 +- .../vo/DeliveryExpressTemplateExcelVO.java | 31 ------ .../DeliveryExpressTemplateExportReqVO.java | 26 ----- .../vo/ExpressTemplateChargeBaseVO.java | 10 +- .../vo/ExpressTemplateChargeUpdateVO.java | 4 +- .../vo/ExpressTemplateFreeBaseVO.java | 10 +- .../vo/ExpressTemplateFreeUpdateVO.java | 2 - .../delivery/DeliveryExpressConvert.java | 2 +- .../DeliveryExpressTemplateConvert.java | 28 +---- .../DeliveryExpressTemplateChargeDO.java | 11 +- .../DeliveryExpressTemplateFreeDO.java | 12 ++- .../DeliveryExpressTemplateChargeMapper.java | 4 - .../DeliveryExpressTemplateFreeMapper.java | 4 - .../DeliveryExpressTemplateMapper.java | 16 +-- .../DeliveryExpressTemplateService.java | 9 -- .../DeliveryExpressTemplateServiceImpl.java | 101 ++++++++---------- .../controller/admin/ip/AreaController.java | 22 ++-- .../admin/ip/vo/AreaNodeSimpleRespVO.java | 19 ++++ .../admin/ip/vo/LazyAreaNodeRespVO.java | 24 ----- .../module/system/convert/ip/AreaConvert.java | 8 +- 26 files changed, 193 insertions(+), 254 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerListTypeHandler.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index ca9f584b2..1cfda1722 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -350,7 +350,7 @@ DROP TABLE IF EXISTS `trade_delivery_express_template_free`; CREATE TABLE `trade_delivery_express_template_free` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', `template_id` bigint NOT NULL COMMENT '快递运费模板编号', - `area_id` int NOT NULL COMMENT '包邮区域 id', + `area_ids` varchar(100) NOT NULL COMMENT '包邮区域 ids', `free_price` int NOT NULL COMMENT '包邮金额,单位:分', `free_count` int NOT NULL DEFAULT 0 COMMENT '包邮件数,', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', @@ -369,7 +369,7 @@ DROP TABLE IF EXISTS `trade_delivery_express_template_charge`; CREATE TABLE `trade_delivery_express_template_charge` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', `template_id` bigint NOT NULL COMMENT '快递运费模板编号', - `area_id` int NOT NULL COMMENT '配送区域 id', + `area_ids` varchar(100) NOT NULL COMMENT '配送区域 ids', `charge_mode` tinyint NOT NULL COMMENT '配送计费方式', `start_count` double NOT NULL COMMENT '首件数量', `start_price` int NOT NULL COMMENT '起步价,单位:分', @@ -501,7 +501,7 @@ INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, ` INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2164, '配送管理', '', 1, 0, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-18 09:48:48', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2165, '快递发货', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0'); -INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '门店自提', '', 1, 1, 2164, 'pick-up', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2167, '快递公司', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java index 88ba22d87..2ac7278a4 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java @@ -45,4 +45,10 @@ public class StrUtils { return Arrays.stream(longs).boxed().collect(Collectors.toList()); } + public static List splitToInteger(String value, CharSequence separator) { + int[] integers = StrUtil.splitToInt(value, separator); + return Arrays.stream(integers).boxed().collect(Collectors.toList()); + } + + } diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java index 87cf0dddc..7788d2895 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java @@ -113,10 +113,20 @@ public interface BaseMapperX extends MPJBaseMapper { Db.saveBatch(entities, size); } + // @芋艿 是不是叫 updateByDo 或者 updateByEntity 更合适 default void updateBatch(T update) { update(update, new QueryWrapper<>()); } + /** + * 根据ID 批量更新,适合大量数据更新 + * + * @param entities 实体们 + */ + default void updateBatch(Collection entities) { + Db.updateBatchById(entities); + } + default void updateBatch(Collection entities, int size) { Db.updateBatchById(entities, size); } diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerListTypeHandler.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerListTypeHandler.java new file mode 100644 index 000000000..18455ba11 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/IntegerListTypeHandler.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.framework.mybatis.core.type; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.util.string.StrUtils; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedJdbcTypes; +import org.apache.ibatis.type.MappedTypes; +import org.apache.ibatis.type.TypeHandler; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * List 的类型转换器实现类,对应数据库的 varchar 类型 + * + * @author jason + */ +@MappedJdbcTypes(JdbcType.VARCHAR) +@MappedTypes(List.class) +public class IntegerListTypeHandler implements TypeHandler> { + + private static final String COMMA = ","; + + @Override + public void setParameter(PreparedStatement ps, int i, List strings, JdbcType jdbcType) throws SQLException { + ps.setString(i, CollUtil.join(strings, COMMA)); + } + + @Override + public List getResult(ResultSet rs, String columnName) throws SQLException { + String value = rs.getString(columnName); + return getResult(value); + } + + @Override + public List getResult(ResultSet rs, int columnIndex) throws SQLException { + String value = rs.getString(columnIndex); + return getResult(value); + } + + @Override + public List getResult(CallableStatement cs, int columnIndex) throws SQLException { + String value = cs.getString(columnIndex); + return getResult(value); + } + + private List getResult(String value) { + if (value == null) { + return null; + } + return StrUtils.splitToInteger(value, COMMA); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index b245ec860..5b3a84284 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -74,7 +74,7 @@ public class DeliveryExpressController { return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); } - // TODO @jason:运费模版,可以去掉哈,没啥用; + // TODO @jason:运费模版,@芋艿 你的意思是运费模板导出没有必要吧。已经去掉了。这个是快递公司导出 @GetMapping("/export-excel") @Operation(summary = "导出快递公司 Excel") @PreAuthorize("@ss.hasPermission('trade:delivery:express:export')") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 9ea4c4d1b..3471b2233 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -84,17 +84,4 @@ public class DeliveryExpressTemplateController { PageResult pageResult = deliveryExpressTemplateService.getDeliveryExpressTemplatePage(pageVO); return success(DeliveryExpressTemplateConvert.INSTANCE.convertPage(pageResult)); } - - @GetMapping("/export-excel") - @Operation(summary = "导出快递运费模板 Excel") - @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:export')") - @OperateLog(type = EXPORT) - public void exportDeliveryExpressTemplateExcel(@Valid DeliveryExpressTemplateExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(exportReqVO); - // 导出 Excel - List datas = DeliveryExpressTemplateConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "快递运费模板.xls", "数据", DeliveryExpressTemplateExcelVO.class, datas); - } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java index 45d92aa43..4df6c0d7d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @@ -7,8 +10,6 @@ import java.time.LocalDateTime; /** * 快递公司 Excel VO - * - * @author jason */ @Data public class DeliveryExpressExcelVO { @@ -28,9 +29,9 @@ public class DeliveryExpressExcelVO { @ExcelProperty("排序") private Integer sort; - @ExcelProperty("状态") - // TODO @jason:可以使用 @DictFormat(DictTypeConstants.COMMON_STATUS) - private Byte status; + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.COMMON_STATUS) + private Integer status; @ExcelProperty("创建时间") private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java deleted file mode 100644 index 60ae499f0..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExcelVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; - -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 快递运费模板 Excel VO - * - * @author jason - */ -@Data -public class DeliveryExpressTemplateExcelVO { - - @ExcelProperty("编号,自增") - private Long id; - - @ExcelProperty("模板名称") - private String name; - - @ExcelProperty("配送计费方式 1:按件 2:按重量 3:按体积") - private Integer chargeMode; - - @ExcelProperty("排序") - private Integer sort; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java deleted file mode 100644 index c02133165..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateExportReqVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; - -import lombok.*; -import java.util.*; -import io.swagger.v3.oas.annotations.media.Schema; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import java.time.LocalDateTime; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 快递运费模板 Excel 导出 Request VO,参数和 DeliveryExpressTemplatePageReqVO 是一致的") -@Data -public class DeliveryExpressTemplateExportReqVO { - - @Schema(description = "模板名称", example = "王五") - private String name; - - @Schema(description = "配送计费方式 1:按件 2:按重量 3:按体积") - private Integer chargeMode; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java index 5da76845e..8bd2617b7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.List; /** * 快递运费模板运费设置 Base VO,提供给添加运费模板使用 - * - * @author jason */ @Data public class ExpressTemplateChargeBaseVO { - @Schema(description = "区域编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "区域编号不能为空") - private Integer areaId; + @Schema(description = "区域编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,120000]") + @NotEmpty(message = "区域编号列表不能为空") + private List areaIds; @Schema(description = "首件数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") @NotNull(message = "首件数量不能为空") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java index a0fb2315c..995ea4a18 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java @@ -3,9 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -/** - * @author jason - */ + @Data public class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java index ff6dbbcaa..7523b0f53 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.List; /** * 快递运费模板包邮 Base VO,提供给添加运费模板使用 - * - * @author jason */ @Data public class ExpressTemplateFreeBaseVO { - @Schema(description = "区域编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "区域编号不能为空") - private Integer areaId; + @Schema(description = "区域编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,120000]") + @NotEmpty(message = "区域编号列表不能为空") + private List areaIds; @Schema(description = "包邮金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "5000") @NotNull(message = "包邮金额不能为空") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java index 56485b579..e0c7e47b0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java @@ -5,8 +5,6 @@ import lombok.Data; /** * 快递运费模板包邮 更新 VO - * - * @author jason */ @Data public class ExpressTemplateFreeUpdateVO extends ExpressTemplateFreeBaseVO { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java index 768530ace..e896962a2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java @@ -16,7 +16,7 @@ import org.mapstruct.factory.Mappers; /** * 快递公司 Convert * - * @author 芋道源码 + * @author jason */ @Mapper public interface DeliveryExpressConvert { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index d4d23cb0a..7e2a51cc1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.convert.delivery; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; @@ -16,7 +17,7 @@ import java.util.List; /** * 快递运费模板 Convert * - * @author 芋道源码 + * @author jason */ @Mapper public interface DeliveryExpressTemplateConvert { @@ -37,8 +38,6 @@ public interface DeliveryExpressTemplateConvert { PageResult convertPage(PageResult page); - List convertList02(List list); - default DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean, List chargeList, List freeList){ @@ -55,15 +54,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(ExpressTemplateChargeUpdateVO vo); default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { - // TODO @jason:可以使用 CollectionUtils.convertList,本质上就是 stream convert list - if(CollUtil.isEmpty(list)){ - return Collections.emptyList(); - } - List templateChargeList = new ArrayList<>(list.size()); - for (ExpressTemplateChargeBaseVO item : list) { - templateChargeList.add(convertTemplateCharge(templateId, chargeMode, item)); - } - return templateChargeList; + return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); } // ========== Template Free ========== @@ -76,17 +67,8 @@ public interface DeliveryExpressTemplateConvert { List convertTemplateFreeList(List list); - // TODO @jason:, List,中间一个空格哈。代码的空格和空行要注意,嘿嘿~ - default List convertTemplateFreeList(Long templateId, List list) { - // TODO @jason:可以使用 CollectionUtils.convertList,本质上就是 stream convert list - if (CollUtil.isEmpty(list)) { - return Collections.emptyList(); - } - List templateFreeList = new ArrayList<>(list.size()); - for (ExpressTemplateFreeBaseVO item : list) { - templateFreeList.add(convertTemplateFree(templateId, item)); - } - return templateFreeList; + default List convertTemplateFreeList(Long templateId, List list) { + return CollectionUtils.convertList(list, vo -> convertTemplateFree(templateId, vo)); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java index 803576503..c3bb30e9a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java @@ -1,17 +1,21 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler; import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import java.util.List; + /** * 快递运费模板计费配置 DO * * @author jason */ -@TableName(value ="trade_delivery_express_template_charge") +@TableName(value ="trade_delivery_express_template_charge", autoResultMap = true) @KeySequence("trade_delivery_express_template_charge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryExpressTemplateChargeDO extends BaseDO { @@ -30,9 +34,10 @@ public class DeliveryExpressTemplateChargeDO extends BaseDO { private Long templateId; /** - * 配送区域 + * 配送区域编号列表 */ - private Integer areaId; + @TableField(typeHandler = IntegerListTypeHandler.class) + private List areaIds; /** * 配送计费方式 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java index 351a1dd24..07eef1be2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java @@ -1,17 +1,21 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.delivery; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler; import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import java.util.List; + /** * 快递运费模板包邮配置 DO * * @author jason */ -@TableName(value ="trade_delivery_express_template_free") +@TableName(value ="trade_delivery_express_template_free", autoResultMap = true) @KeySequence("trade_delivery_express_template_free_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class DeliveryExpressTemplateFreeDO extends BaseDO { @@ -29,10 +33,12 @@ public class DeliveryExpressTemplateFreeDO extends BaseDO { */ private Long templateId; + /** - * 包邮区域id + * 配送区域编号列表 */ - private Integer areaId; + @TableField(typeHandler = IntegerListTypeHandler.class) + private List areaIds; /** * 包邮金额,单位:分 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java index ed0314018..dc96b24f2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -14,10 +14,6 @@ import java.util.List; @Mapper public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX { - @Repository - class BatchInsertMapper extends ServiceImpl { - } - default List selectListByTemplateId(Long templateId){ return selectList(new LambdaQueryWrapper() .eq(DeliveryExpressTemplateChargeDO::getTemplateId, templateId)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java index 97a4d31d3..58caaf9af 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -14,10 +14,6 @@ import java.util.List; @Mapper public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX { - @Repository - class BatchInsertMapper extends ServiceImpl { - } - default List selectListByTemplateId(Long templateId) { return selectList(new LambdaQueryWrapper() .eq(DeliveryExpressTemplateFreeDO::getTemplateId, templateId)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java index 85b52851e..734298042 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java @@ -4,14 +4,10 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplateExportReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplatePageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; -import java.util.List; - @Mapper public interface DeliveryExpressTemplateMapper extends BaseMapperX { @@ -23,18 +19,8 @@ public interface DeliveryExpressTemplateMapper extends BaseMapperX selectList(DeliveryExpressTemplateExportReqVO reqVO) { - return selectList(new LambdaQueryWrapperX() - .likeIfPresent(DeliveryExpressTemplateDO::getName, reqVO.getName()) - .eqIfPresent(DeliveryExpressTemplateDO::getChargeMode, reqVO.getChargeMode()) - .betweenIfPresent(DeliveryExpressTemplateDO::getCreateTime, reqVO.getCreateTime()) - .orderByAsc(DeliveryExpressTemplateDO::getSort)); - } - - // TODO @jason:可以用 selectOne(DeliveryExpressTemplateDO::getName, name),常用的我封装了哈。简洁一点~ default DeliveryExpressTemplateDO selectByName(String name) { - return selectOne(new LambdaQueryWrapper() - .eq(DeliveryExpressTemplateDO::getName, name)); + return selectOne(DeliveryExpressTemplateDO::getName,name); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 30cb85b75..71721fec2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -58,13 +58,4 @@ public interface DeliveryExpressTemplateService { * @return 快递运费模板分页 */ PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO); - - /** - * 获得快递运费模板列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 快递运费模板列表 - */ - List getDeliveryExpressTemplateList(DeliveryExpressTemplateExportReqVO exportReqVO); - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 76182eed7..2bda89a91 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -36,32 +36,24 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; @Resource private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; - // TODO @jason:应该不用 BatchInsertMapper 拉,直接走 expressTemplateChargeMapper.insertBatch - @Resource - private DeliveryExpressTemplateChargeMapper.BatchInsertMapper expressTemplateChargeBatchMapper; - @Resource - private DeliveryExpressTemplateFreeMapper.BatchInsertMapper expressTemplateFreeBatchMapper; @Override @Transactional(rollbackFor = Exception.class) public Long createDeliveryExpressTemplate(DeliveryExpressTemplateCreateReqVO createReqVO) { - // TODO @jason:中英文之间,要有空格哈。例如说, // 校验模板名是否唯一 - //校验模板名是否唯一 + // 校验模板名是否唯一 validateTemplateNameUnique(createReqVO.getName(), null); - // 插入 DeliveryExpressTemplateDO deliveryExpressTemplate = INSTANCE.convert(createReqVO); expressTemplateMapper.insert(deliveryExpressTemplate); - //插入运费模板计费表 - // TODO @jason:if (,中间要有空格 - if(CollUtil.isNotEmpty(createReqVO.getTemplateCharge())) { - expressTemplateChargeBatchMapper.saveBatch( - INSTANCE.convertTemplateChargeList(deliveryExpressTemplate.getId(), createReqVO.getChargeMode(), createReqVO.getTemplateCharge()) + // 插入运费模板计费表 + if (CollUtil.isNotEmpty(createReqVO.getTemplateCharge())) { + expressTemplateChargeMapper.insertBatch( + INSTANCE.convertTemplateChargeList(deliveryExpressTemplate.getId(), createReqVO.getChargeMode(), createReqVO.getTemplateCharge()) ); } - //插入运费模板包邮表 - if(CollUtil.isNotEmpty(createReqVO.getTemplateFree())) { - expressTemplateFreeBatchMapper.saveBatch( + // 插入运费模板包邮表 + if (CollUtil.isNotEmpty(createReqVO.getTemplateFree())) { + expressTemplateFreeMapper.insertBatch( INSTANCE.convertTemplateFreeList(deliveryExpressTemplate.getId(), createReqVO.getTemplateFree()) ); } @@ -73,14 +65,13 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public void updateDeliveryExpressTemplate(DeliveryExpressTemplateUpdateReqVO updateReqVO) { // 校验存在 validateDeliveryExpressTemplateExists(updateReqVO.getId()); - //校验模板名是否唯一 + // 校验模板名是否唯一 validateTemplateNameUnique(updateReqVO.getName(), updateReqVO.getId()); - - //更新运费从表 + // 更新运费从表 updateExpressTemplateCharge(updateReqVO); - //更新包邮从表 + // 更新包邮从表 updateExpressTemplateFree(updateReqVO); - //更新模板主表 + // 更新模板主表 DeliveryExpressTemplateDO updateObj = INSTANCE.convert(updateReqVO); expressTemplateMapper.updateById(updateObj); } @@ -88,29 +79,29 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private void updateExpressTemplateFree(DeliveryExpressTemplateUpdateReqVO updateReqVO) { List oldFreeList = expressTemplateFreeMapper.selectListByTemplateId(updateReqVO.getId()); List newFreeList = updateReqVO.getTemplateFree(); - //新增包邮区域列表 + // 新增包邮区域列表 List addFreeList = new ArrayList<>(newFreeList.size()); - //更新包邮区域列表 + // 更新包邮区域列表 List updateFreeList = new ArrayList<>(newFreeList.size()); for (ExpressTemplateFreeUpdateVO item : newFreeList) { if (Objects.nonNull(item.getId())) { updateFreeList.add(INSTANCE.convertTemplateFree(item)); - }else{ + } else { item.setTemplateId(updateReqVO.getId()); addFreeList.add(INSTANCE.convertTemplateFree(item)); } } - //删除的包邮区域id + // 新增 + if (CollUtil.isNotEmpty(addFreeList)) { + expressTemplateFreeMapper.insertBatch(addFreeList); + } + // 修改 + if (CollUtil.isNotEmpty(updateFreeList)) { + expressTemplateFreeMapper.updateBatch(updateFreeList); + } + // 得到删除ids Set deleteFreeIds = CollectionUtils.convertSet(oldFreeList, DeliveryExpressTemplateFreeDO::getId); deleteFreeIds.removeAll(CollectionUtils.convertSet(updateFreeList, DeliveryExpressTemplateFreeDO::getId)); - //新增 - if (CollUtil.isNotEmpty(addFreeList)) { - expressTemplateFreeBatchMapper.saveBatch(addFreeList); - } - //修改 - if (CollUtil.isNotEmpty(updateFreeList)) { - expressTemplateFreeBatchMapper.saveOrUpdateBatch(updateFreeList); - } //删除 if (CollUtil.isNotEmpty(deleteFreeIds)) { expressTemplateFreeMapper.deleteBatchIds(deleteFreeIds); @@ -120,33 +111,33 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private void updateExpressTemplateCharge(DeliveryExpressTemplateUpdateReqVO updateReqVO) { List oldChargeList = expressTemplateChargeMapper.selectListByTemplateId(updateReqVO.getId()); List newChargeList = updateReqVO.getTemplateCharge(); - //新增运费区域列表 + // 新增运费区域列表 List addList = new ArrayList<>(newChargeList.size()); - //更新运费区域列表 + // 更新运费区域列表 List updateList = new ArrayList<>(newChargeList.size()); for (ExpressTemplateChargeUpdateVO item : newChargeList) { - if (Objects.nonNull(item.getId())) { // TODO @jason:null 的判断,还是用 item.getId() != null 好一点。一般数组用方法,主要考虑 null + length = 0; - //计费模式以主表为准 + if (item.getId() != null) { + // 计费模式以主表为准 item.setChargeMode(updateReqVO.getChargeMode()); updateList.add(INSTANCE.convertTemplateCharge(item)); - }else{ + } else { item.setTemplateId(updateReqVO.getId()); item.setChargeMode(updateReqVO.getChargeMode()); addList.add(INSTANCE.convertTemplateCharge(item)); } } - //删除的运费区域id TODO @jason:这块放到删除部分的那块逻辑会好点(149 - 152 行),主要变量要贴相应的逻辑近一点哈。 + // 新增 + if (CollUtil.isNotEmpty(addList)) { + expressTemplateChargeMapper.insertBatch(addList); + } + // 修改 + if (CollUtil.isNotEmpty(updateList)) { + expressTemplateChargeMapper.updateBatch(updateList); + } + // 得到删除的ids Set deleteChargeIds = CollectionUtils.convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId); deleteChargeIds.removeAll(CollectionUtils.convertSet(updateList, DeliveryExpressTemplateChargeDO::getId)); - //新增 - if (CollUtil.isNotEmpty(addList)) { - expressTemplateChargeBatchMapper.saveBatch(addList); - } - //修改 - if (CollUtil.isNotEmpty(updateList)) { - expressTemplateChargeBatchMapper.saveOrUpdateBatch(updateList); - } - //删除 + // 删除 if (CollUtil.isNotEmpty(deleteChargeIds)) { expressTemplateChargeMapper.deleteBatchIds(deleteChargeIds); } @@ -157,7 +148,6 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public void deleteDeliveryExpressTemplate(Long id) { // 校验存在 validateDeliveryExpressTemplateExists(id); - // 删除主表 expressTemplateMapper.deleteById(id); // 删除运费从表 @@ -167,9 +157,10 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } /** - * 校验运费模板名是否唯一 // TODO @jason:方法注释,和参数,要空一行。 + * 校验运费模板名是否唯一 + * * @param name 模板名称 - * @param id 运费模板编号, 可以为null // TODO @jason:中英文之间,要空一行;其它地方也看看哈 + * @param id 运费模板编号,可以为 null */ private void validateTemplateNameUnique(String name, Long id) { DeliveryExpressTemplateDO template = expressTemplateMapper.selectByName(name); @@ -196,7 +187,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla List chargeList = expressTemplateChargeMapper.selectListByTemplateId(id); List freeList = expressTemplateFreeMapper.selectListByTemplateId(id); DeliveryExpressTemplateDO template = expressTemplateMapper.selectById(id); - return INSTANCE.convert(template, chargeList,freeList); + return INSTANCE.convert(template, chargeList, freeList); } @Override @@ -208,10 +199,4 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO) { return expressTemplateMapper.selectPage(pageReqVO); } - - @Override - public List getDeliveryExpressTemplateList(DeliveryExpressTemplateExportReqVO exportReqVO) { - return expressTemplateMapper.selectList(exportReqVO); - } - } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index 0988cbe90..b3bc0c03c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.IPUtils; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; -import cn.iocoder.yudao.module.system.controller.admin.ip.vo.LazyAreaNodeRespVO; +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO; import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -34,23 +34,23 @@ public class AreaController { return success(AreaConvert.INSTANCE.convertList(area.getChildren())); } - // TODO @jason:1)url 使用中划线分隔哈,然后可以改成 children;2)id 需要添加 @RequestParam,因为可能会混淆编译; - // 3) swagger 注解要写下哈; - @GetMapping("/getChildrenArea") + @GetMapping("/get-children") @Operation(summary = "获得地区的下级区域") - public CommonResult> getChildrenArea(Integer id) { + @Parameter(name = "id", description = "区域编号", required = true, example = "150000") + public CommonResult> getChildren(@RequestParam("id") Integer id) { Area area = AreaUtils.getArea(id); - Assert.notNull(area, String.format("获取不到 id : %d的区域", id)); + Assert.notNull(area, String.format("获取不到 id : %d 的区域", id)); return success(AreaConvert.INSTANCE.convertList2(area.getChildren())); } - // TODO @jason:1)读请求,使用 get 哈。2)然后参数不应该使用 @RequestBody;3)areaIds 改成 ids 更合适; // 4)方法改成 getAreaChildrenList 获得子节点们;5)url 可以已改成 children-list - @PostMapping("/list") + //@芋艿 是不是叫 getAreaListByIds 更合适。 因为不一定是子节点。 用于前端树选择获取缓存数据。 见 + @GetMapping("/get-by-ids") @Operation(summary = "通过区域 ids 获得地区列表") - public CommonResult> list(@RequestBody Set areaIds) { - List areaList = new ArrayList<>(areaIds.size()); - for (Integer areaId : areaIds) { + @Parameter(name = "ids", description = "区域编号 ids", required = true, example = "1,150000") + public CommonResult> getAreaListByIds(@RequestParam("ids") Set ids) { + List areaList = new ArrayList<>(ids.size()); + for (Integer areaId : ids) { areaList.add(AreaUtils.getArea(areaId)); } return success(AreaConvert.INSTANCE.convertList2(areaList)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java new file mode 100644 index 000000000..a37430248 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.system.controller.admin.ip.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 简洁的地区节点 Response VO") +@Data +public class AreaNodeSimpleRespVO { + + @Schema(description = "编号", required = true, example = "110000") + private Integer id; + + @Schema(description = "名字", required = true, example = "北京") + private String name; + + @Schema(description = "是否叶子节点", required = false, example = "false") + private Boolean leaf; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java deleted file mode 100644 index e95defb1c..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/LazyAreaNodeRespVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.ip.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -// TODO @jason:1)VO 不添加注释作者哈。2)是不是改成 AreaNodeSimpleRespVO,它其实是返回一个简洁的地区,懒加载只是它的使用场景; -/** - * @author jason - */ -@Schema(description = "管理后台 - 懒加载地区节点 Response VO") -@Data -public class LazyAreaNodeRespVO { - - @Schema(description = "编号", required = true, example = "110000") - private Integer id; - - @Schema(description = "名字", required = true, example = "北京") - private String name; - - // TODO @jason:1)不设置默认值,交给业务逻辑那写入;2)这个字段必须返回哇? - @Schema(description = "是否叶子节点", required = true, example = "false") - private Boolean leaf = Boolean.FALSE; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java index 540272e12..05d193717 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java @@ -3,12 +3,10 @@ package cn.iocoder.yudao.module.system.convert.ip; import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; -import cn.iocoder.yudao.module.system.controller.admin.ip.vo.LazyAreaNodeRespVO; +import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Named; import org.mapstruct.factory.Mappers; -import org.springframework.context.annotation.Lazy; import java.util.List; import java.util.Objects; @@ -20,10 +18,10 @@ public interface AreaConvert { List convertList(List list); - List convertList2(List list); + List convertList2(List list); @Mapping(source = "type", target = "leaf") - LazyAreaNodeRespVO convert(Area area); + AreaNodeSimpleRespVO convert(Area area); default Boolean convertAreaType(Integer type){ return Objects.equals(AreaTypeEnum.DISTRICT.getType(),type); From 6a9146ff8de5e7e1156d3ea3eaf02905b71636bd Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 28 May 2023 20:09:51 +0800 Subject: [PATCH 063/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/api/coupon/CouponApi.java | 10 + .../api/coupon/dto/CouponRespDTO.java | 109 ++++ .../api/coupon/dto/CouponValidReqDTO.java | 27 + .../api/discount/DiscountActivityApi.java | 23 + .../discount/dto/DiscountProductRespDTO.java} | 18 +- .../module/promotion/api/package-info.java | 4 - .../api/price/dto/PriceCalculateReqDTO.java | 5 + .../api/price/dto/PriceCalculateRespDTO.java | 10 +- .../api/reward/RewardActivityApi.java | 24 + .../dto/RewardActivityMatchRespDTO.java | 77 +++ .../enums/common/PromotionLevelEnum.java | 40 -- .../enums/common/PromotionTypeEnum.java | 3 +- .../promotion/api/coupon/CouponApiImpl.java | 10 + .../api/discount/DiscountActivityApiImpl.java | 28 ++ .../promotion/api/discount/package-info.java | 1 - .../api/reward/RewardActivityApiImpl.java | 27 + .../convert/coupon/CouponConvert.java | 3 + .../discount/DiscountActivityConvert.java | 20 +- .../discount/DiscountActivityDO.java | 7 +- .../discount/DiscountProductDO.java | 3 + .../dataobject/reward/RewardActivityDO.java | 1 + .../discount/DiscountActivityService.java | 4 +- .../discount/DiscountActivityServiceImpl.java | 42 +- .../promotion/service/price/PriceService.java | 9 - .../service/price/PriceServiceImpl.java | 466 +----------------- .../service/reward/RewardActivityService.java | 9 +- .../reward/RewardActivityServiceImpl.java | 37 +- .../service/price/PriceServiceTest.java | 30 +- .../trade/enums/ErrorCodeConstants.java | 4 + .../service/price/TradePriceService.java | 21 + .../service/price/TradePriceServiceImpl.java | 73 +++ .../price/bo/TradePriceCalculateReqBO.java | 86 ++++ .../price/bo/TradePriceCalculateRespBO.java | 249 ++++++++++ .../TradeCouponPriceCalculator.java | 109 ++++ .../TradeDiscountActivityPriceCalculator.java | 80 +++ .../calculator/TradePriceCalculator.java | 19 + .../TradePriceCalculatorHelper.java | 221 +++++++++ .../TradeRewardActivityPriceCalculator.java | 133 +++++ .../app/address/AppAddressController.java | 8 +- .../convert/address/AddressConvert.java | 14 +- .../{AddressDO.java => MemberAddressDO.java} | 2 +- .../dal/mysql/address/AddressMapper.java | 14 +- .../service/address/AddressService.java | 8 +- .../service/address/AddressServiceImpl.java | 24 +- .../address/AddressServiceImplTest.java | 10 +- 45 files changed, 1465 insertions(+), 657 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java rename yudao-module-mall/{yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java => yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java} (72%) delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/{AddressDO.java => MemberAddressDO.java} (95%) diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java index f99ff815f..ce7a712da 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.promotion.api.coupon; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; import javax.validation.Valid; @@ -18,4 +20,12 @@ public interface CouponApi { */ void useCoupon(@Valid CouponUseReqDTO useReqDTO); + /** + * 校验优惠劵 + * + * @param validReqDTO 校验请求 + * @return 优惠劵 + */ + CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO); + } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java new file mode 100644 index 000000000..34031e604 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.promotion.api.coupon.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 优惠劵 Response DTO + * + * @author 芋道源码 + */ +@Data +public class CouponRespDTO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Long id; + /** + * 优惠劵模板编号 + */ + private Integer templateId; + /** + * 优惠劵名 + */ + private String name; + /** + * 优惠码状态 + * + * 枚举 {@link CouponStatusEnum} + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 字段 + */ + private Long userId; + /** + * 领取类型 + * + * 枚举 {@link CouponTakeTypeEnum} + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + */ + private Integer usePrice; + /** + * 生效开始时间 + */ + private LocalDateTime validStartTime; + /** + * 生效结束时间 + */ + private LocalDateTime validEndTime; + /** + * 商品范围 + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + private List productSpuIds; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 折扣类型 + */ + private Integer discountType; + /** + * 折扣百分比 + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + */ + private Integer discountPrice; + /** + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 + */ + private Integer discountLimitPrice; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 使用订单号 + */ + private Long useOrderId; + /** + * 使用时间 + */ + private LocalDateTime useTime; + + // ========== 使用情况 END ========== +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java new file mode 100644 index 000000000..dd25c6408 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.coupon.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 优惠劵使用 Request DTO + * + * @author 芋道源码 + */ +@Data +public class CouponValidReqDTO { + + /** + * 优惠劵编号 + */ + @NotNull(message = "优惠劵编号不能为空") + private Long id; + + /** + * 用户编号 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java new file mode 100644 index 000000000..b25f67d9f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.promotion.api.discount; + +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 限时折扣 API 接口 + * + * @author 芋道源码 + */ +public interface DiscountActivityApi { + + /** + * 获得商品匹配的的限时折扣信息 + * + * @param skuIds 商品 SKU 编号数组 + * @return 限时折扣信息 + */ + List getMatchDiscountProductList(Collection skuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java similarity index 72% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java rename to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java index 7b8f4a20f..52dfdbe27 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java @@ -1,25 +1,19 @@ -package cn.iocoder.yudao.module.promotion.service.discount.bo; +package cn.iocoder.yudao.module.promotion.api.discount.dto; import lombok.Data; /** - * 限时折扣活动商品 BO + * 限时折扣活动商品 Response DTO * * @author 芋道源码 */ @Data -public class DiscountProductDetailBO { - - // ========== DiscountProductDO 字段 ========== +public class DiscountProductRespDTO { /** * 编号,主键自增 */ private Long id; - /** - * 限时折扣活动的编号 - */ - private Long activityId; /** * 商品 SPU 编号 */ @@ -41,7 +35,11 @@ public class DiscountProductDetailBO { */ private Integer discountPrice; - // ========== DiscountActivityDO 字段 ========== + // ========== 活动字段 ========== + /** + * 限时折扣活动的编号 + */ + private Long activityId; /** * 活动标题 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java deleted file mode 100644 index 08e1020a6..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.module.promotion.api; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java index 01f0ac220..ce53de50e 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java @@ -26,6 +26,11 @@ public class PriceCalculateReqDTO { */ private Long couponId; + /** + * 收货地址编号 + */ + private Long addressId; + /** * 商品 SKU 数组 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java index a067aa0b5..9a98029b7 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -24,6 +24,7 @@ import java.util.List; * @author 芋道源码 */ @Data +@Deprecated public class PriceCalculateRespDTO { /** @@ -174,6 +175,7 @@ public class PriceCalculateRespDTO { * 营销明细 */ @Data + @Deprecated public static class Promotion { /** @@ -216,14 +218,14 @@ public class PriceCalculateRespDTO { /** * 是否满足优惠条件 */ - private Boolean meet; + private Boolean match; /** * 满足条件的提示 * - * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” - * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” + * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元” */ - private String meetTip; + private String description; } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java new file mode 100644 index 000000000..efeddf3d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.api.reward; + +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 满减送活动 API 接口 + * + * @author 芋道源码 + */ +public interface RewardActivityApi { + + + /** + * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 + * + * @param spuIds SPU 编号数组 + * @return 满减送活动列表 + */ + List getMatchRewardActivityList(Collection spuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java new file mode 100644 index 000000000..19f46a49a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.promotion.api.reward.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 满减送活动的匹配 Response DTO + * + * @author 芋道源码 + */ +@Data +public class RewardActivityMatchRespDTO { + + /** + * 活动编号,主键自增 + */ + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 条件类型 + * + * 枚举 {@link PromotionConditionTypeEnum} + */ + private Integer conditionType; + /** + * 优惠规则的数组 + */ + private List rules; + + /** + * 商品 SPU 编号的数组 + */ + private List spuIds; + + // TODO 芋艿:后面 RewardActivityRespDTO 有了之后,Rule 可以放过去 + /** + * 优惠规则 + */ + @Data + public static class Rule { + + /** + * 优惠门槛 + * + * 1. 满 N 元,单位:分 + * 2. 满 N 件 + */ + private Integer limit; + /** + * 优惠价格,单位:分 + */ + private Integer discountPrice; + /** + * 是否包邮 + */ + private Boolean freeDelivery; + /** + * 赠送的积分 + */ + private Integer point; + /** + * 赠送的优惠劵编号的数组 + */ + private List couponIds; + /** + * 赠送的优惠卷数量的数组 + */ + private List couponCounts; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java deleted file mode 100644 index ed0564a70..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的级别枚举 - * - * 参考有赞:营销级别 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionLevelEnum implements IntArrayValuable { - - ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 - SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 - COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); - - /** - * 级别值 - */ - private final Integer level; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java index eea48f7dc..ee87306bf 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java @@ -18,7 +18,7 @@ public enum PromotionTypeEnum implements IntArrayValuable { DISCOUNT_ACTIVITY(1, "限时折扣"), REWARD_ACTIVITY(2, "满减送"), - MEMBER(3, "会员折扣"), + MEMBER(3, "会员折扣"), // TODO 芋艿:待实现 StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice) COUPON(4, "优惠劵") ; @@ -37,4 +37,5 @@ public enum PromotionTypeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java index 349eba1ff..a06ab57cd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.promotion.api.coupon; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; import org.springframework.stereotype.Service; @@ -24,4 +28,10 @@ public class CouponApiImpl implements CouponApi { useReqDTO.getOrderId()); } + @Override + public CouponRespDTO validateCoupon(CouponValidReqDTO validReqDTO) { + CouponDO coupon = couponService.validCoupon(validReqDTO.getId(), validReqDTO.getUserId()); + return CouponConvert.INSTANCE.convert(coupon); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java new file mode 100644 index 000000000..2227da43e --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.api.discount; + +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 限时折扣 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class DiscountActivityApiImpl implements DiscountActivityApi { + + @Resource + private DiscountActivityService discountActivityService; + + @Override + public List getMatchDiscountProductList(Collection skuIds) { + return DiscountActivityConvert.INSTANCE.convertList02(discountActivityService.getMatchDiscountProductList(skuIds)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java deleted file mode 100644 index 4e3ce77a8..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java new file mode 100644 index 000000000..ee8bac7c9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.reward; + +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 满减送活动 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class RewardActivityApiImpl implements RewardActivityApi { + + @Resource + private RewardActivityService rewardActivityService; + + @Override + public List getMatchRewardActivityList(Collection spuIds) { + return rewardActivityService.getMatchRewardActivityList(spuIds); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java index 281318f7d..7bfdca706 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.convert.coupon; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import org.mapstruct.Mapper; @@ -18,4 +19,6 @@ public interface CouponConvert { PageResult convertPage(PageResult page); + CouponRespDTO convert(CouponDO bean); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java index 07d2e03ab..ebf53ce8a 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java @@ -2,18 +2,15 @@ package cn.iocoder.yudao.module.promotion.convert.discount; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; -import java.util.Map; /** * 限时折扣活动 Convert @@ -33,20 +30,10 @@ public interface DiscountActivityConvert { List convertList(List list); + List convertList02(List list); + PageResult convertPage(PageResult page); - DiscountProductDetailBO convert(DiscountProductDO product); - - default List convertList(List products, Map activityMap) { - return CollectionUtils.convertList(products, product -> { - DiscountProductDetailBO detail = convert(product); - MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> { - detail.setActivityName(activity.getName()); - }); - return detail; - }); - } - DiscountProductDO convert(DiscountActivityBaseVO.Product bean); DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List products); @@ -99,4 +86,5 @@ public interface DiscountActivityConvert { return true; } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java index 91071f309..fd0726e39 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -33,10 +33,13 @@ public class DiscountActivityDO extends BaseDO { * 活动标题 */ private String name; + // TODO 芋艿:状态调整,只有开启和关闭; /** * 状态 * - * 枚举 {@link PromotionActivityStatusEnum} + * 枚举 {@link CommonStatusEnum} + * + * 活动被关闭后,不允许再次开启。 */ private Integer status; /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java index 55c924e4f..7f61f7f6d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java @@ -24,12 +24,15 @@ public class DiscountProductDO extends BaseDO { */ @TableId private Long id; + + // TODO 芋艿:把 activity 所有的字段冗余过来 /** * 限时折扣活动的编号 * * 关联 {@link DiscountActivityDO#getId()} */ private Long activityId; + /** * 商品 SPU 编号 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java index e825881d1..9d417d75f 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java @@ -38,6 +38,7 @@ public class RewardActivityDO extends BaseDO { * 活动标题 */ private String name; + // TODO @芋艿:改成开启、禁用两种状态 /** * 状态 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java index 8b6e5895b..7473f12cd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java @@ -6,12 +6,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountAc import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import javax.validation.Valid; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 限时折扣 Service 接口 @@ -28,7 +26,7 @@ public interface DiscountActivityService { * @param skuIds SKU 编号数组 * @return 匹配的限时折扣商品 */ - Map getMatchDiscountProducts(Collection skuIds); + List getMatchDiscountProductList(Collection skuIds); /** * 创建限时折扣活动 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java index df54d44f2..97d70491b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.discount; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; @@ -14,18 +13,17 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProduct import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import cn.iocoder.yudao.module.promotion.util.PromotionUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.*; +import java.util.Collection; +import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; /** * 限时折扣 Service 实现类 @@ -42,9 +40,9 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { private DiscountProductMapper discountProductMapper; @Override - public Map getMatchDiscountProducts(Collection skuIds) { - List discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(discountProducts, DiscountProductDetailBO::getSkuId); + public List getMatchDiscountProductList(Collection skuIds) { + // TODO 芋艿:开启、满足 skuId、日期内 + return null; } @Override @@ -101,6 +99,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { } } + // TODO 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。 /** * 校验商品是否冲突 * @@ -112,9 +111,10 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { return; } // 查询商品参加的活动 - List discountActivityProductList = getRewardProductListBySkuIds( - convertSet(products, DiscountActivityBaseVO.Product::getSkuId), - asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); + List discountActivityProductList = null; +// getRewardProductListBySkuIds( +// convertSet(products, DiscountActivityBaseVO.Product::getSkuId), +// asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); if (id != null) { // 排除自己这个活动 discountActivityProductList.removeIf(product -> id.equals(product.getActivityId())); } @@ -124,24 +124,6 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { } } - private List getRewardProductListBySkuIds(Collection skuIds, - Collection statuses) { - // 查询商品 - List products = discountProductMapper.selectListBySkuId(skuIds); - if (CollUtil.isEmpty(products)) { - return new ArrayList<>(0); - } - - // 查询活动 - List activities = discountActivityMapper.selectBatchIds(skuIds); - activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的 - Map activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId); - - // 移除不满足活动的商品 - products.removeIf(product -> !activityMap.containsKey(product.getActivityId())); - return DiscountActivityConvert.INSTANCE.convertList(products, activityMap); - } - @Override public void closeRewardActivity(Long id) { // 校验存在 @@ -153,7 +135,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END); } - // 更新 + // 更新为关闭。 DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); discountActivityMapper.updateById(updateObj); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java index a7420e119..f402cb1be 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.service.price; import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import java.util.List; @@ -13,14 +12,6 @@ import java.util.List; */ public interface PriceService { - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格响应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - /** * 获得优惠劵的匹配信息列表 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java index 7aab0bee5..439c03d37 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java @@ -1,39 +1,25 @@ package cn.iocoder.yudao.module.promotion.service.price; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.enums.common.*; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import com.google.common.base.Suppliers; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.*; -import java.util.function.Supplier; +import java.util.Collections; +import java.util.List; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Collections.singletonList; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; /** * 价格计算 Service 实现类 @@ -54,43 +40,14 @@ import static java.util.Collections.singletonList; @Slf4j public class PriceServiceImpl implements PriceService { - @Resource - private DiscountActivityService discountService; - @Resource - private RewardActivityService rewardActivityService; @Resource private CouponService couponService; - @Resource - private ProductSkuApi productSkuApi; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - List skuList = checkSkus(calculateReqDTO); - // 初始化 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); - - // 计算商品级别的价格 - calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算订单级别的价格 - calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算优惠劵级别的价格 - calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); - - // 如果最终支付金额小于等于 0,则抛出业务异常 - if (priceCalculate.getOrder().getPayPrice() <= 0) { - log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", - calculateReqDTO, priceCalculate); - throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); - } - return priceCalculate; - } - @Override public List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO) { // 先计算一轮价格 - PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); +// PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); + PriceCalculateRespDTO priceCalculate = null; // 获得用户的待使用优惠劵 List couponList = couponService.getCouponList(calculateReqDTO.getUserId(), CouponStatusEnum.UNUSED.getStatus()); @@ -106,7 +63,9 @@ public class PriceServiceImpl implements PriceService { couponService.validCoupon(coupon); // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + // TODO 芋艿:后续处理 +// List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + List orderItems = null; if (CollUtil.isEmpty(orderItems)) { return couponMeetRespDTO.setMeet(false).setMeetTip("所结算商品没有符合条件的商品"); } @@ -134,413 +93,4 @@ public class PriceServiceImpl implements PriceService { }); } - private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); - - // 校验商品 SKU - skus.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - if (count == null) { - throw exception(SKU_NOT_EXISTS); - } - // 不校验库存不足,避免购物车场景,商品无货的情况 - }); - return skus; - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算商品级别的价格,例如说: - * 1. 会员折扣 - * 2. 限时折扣 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO} - * - * 其中,会员折扣、限时折扣取最低价 - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Supplier memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId); - Map discountProducts = discountService.getMatchDiscountProducts( - convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); - - // 处理每个 SKU 的优惠 - priceCalculate.getOrder().getItems().forEach(orderItem -> { - // 获取该 SKU 的优惠信息 - Double memberDiscountPercent = memberDiscountPercentSupplier.get(); - DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId()); - if (memberDiscountPercent == null && discountProduct == null) { - return; - } - // 计算价格,判断选择哪个折扣 - Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null; - Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null; - if (memberPrice == null) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else if (promotionPrice == null) { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } else if (memberPrice < promotionPrice) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } - }); - } - - private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct, - PriceCalculateRespDTO.OrderItem orderItem) { - Integer price = orderItem.getPayPrice(); - if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 - price -= discountProduct.getDiscountPrice() * orderItem.getCount(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 - price = price * discountProduct.getDiscountPercent() / 100; - } else { - throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); - } - return price; - } - - private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Integer memberPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), - PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, - true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); - } - - private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - DiscountProductDetailBO discountProduct, Integer promotionPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), - PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, - true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); - } - - // TODO 芋艿:提前实现 - private Supplier getMemberDiscountPercentSupplier(Long userId) { - return Suppliers.memoize(() -> { - if (userId == 1) { - return 90d; - } - if (userId == 2) { - return 80d; - } - return null; // 无优惠 - }); - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算订单级别的价格,例如说: - * 1. 满减送 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO} - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - @SuppressWarnings("unused") - private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); - Map> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); - - // 处理满减送活动 - if (CollUtil.isNotEmpty(rewardActivities)) { - rewardActivities.forEach((rewardActivity, activitySpuIds) -> { - List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); - calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); - }); - } - } - - private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, - RewardActivityDO rewardActivity) { - // 获得最大匹配的满减送活动的规则 - RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); - if (rule == null) { - // 获取不到的情况下,记录不满足的优惠明细 - addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), - getRewardActivityNotMeetTip(rewardActivity)); - return; - } - - // 分摊金额 - List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, - true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); - } - } - - /** - * 获得最大匹配的满减送活动的规则 - * - * @param rewardActivity 满减送活动 - * @param orderItems 商品项 - * @return 匹配的活动规则 - */ - private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, - List orderItems) { - Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); - // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 - Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert count != null && price != null; - for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { - RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); - if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) - && price >= rule.getLimit()) { - return rule; - } - if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) - && count >= rule.getLimit()) { - return rule; - } - } - return null; - } - - /** - * 获得满减送活动部匹配时的提示 - * - * @param rewardActivity 满减送活动 - * @return 提示 - */ - private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { - return "TODO"; // TODO 芋艿:后面再想想 - } - - // ========== 计算优惠劵级别的价格 ========== - - private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { - // 校验优惠劵 - if (couponId == null) { - return; - } - CouponDO coupon = couponService.validCoupon(couponId, userId); - - // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); - if (CollUtil.isEmpty(orderItems)) { - throw exception(COUPON_NO_MATCH_SPU); - } - - // 计算是否满足优惠劵的使用金额 - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert originPrice != null; - if (originPrice < coupon.getUsePrice()) { - throw exception(COUPON_NO_MATCH_MIN_PRICE); - } - - // 计算可以优惠的金额 - priceCalculate.getOrder().setCouponId(couponId); - Integer couponPrice = getCouponPrice(coupon, originPrice); - // 分摊金额 - List couponPartPrices = dividePrice(orderItems, couponPrice); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(), - PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, - true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); - } - } - - private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, - CouponDO coupon) { - if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { - return priceCalculate.getOrder().getItems(); - } - return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); - } - - private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { - if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 - return coupon.getDiscountPrice(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 - int couponPrice = originPrice * coupon.getDiscountPercent() / 100; - return coupon.getDiscountLimitPrice() == null ? couponPrice - : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 - } - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); - } - - // ========== 其它相对通用的方法 ========== - - /** - * 添加单个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItem 单个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param newPayPrice 新的单实付金额(总) - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Long id, String name, Integer type, Integer level, - Integer newPayPrice, Boolean meet, String meetTip) { - // 创建营销明细 Item - // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice - PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) - .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 添加多个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, - List discountPrices, Boolean meet, String meetTip) { - // 创建营销明细 Item - List promotionItems = new ArrayList<>(discountPrices.size()); - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); - } - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) - .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) - .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, String meetTip) { - // 创建营销明细 Item - List promotionItems = CollectionUtils.convertList(orderItems, - orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); - // 创建营销明细 - Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(originalPrice).setDiscountPrice(0) - .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 - * - * @param orderItem 订单商品 SKU - * @param newPayPrice 新的 payPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, - PriceCalculateRespDTO priceCalculate) { - // diffPayPrice 等于额外增加的商品级的优惠 - int diffPayPrice = orderItem.getPayPrice() - newPayPrice; - // 设置 OrderItem 价格相关字段 - orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); - orderItem.setPayPrice(newPayPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setPayPrice(order.getPayPrice() - diffPayPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 - * - * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 discountPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 - * - * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 couponPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - private List dividePrice(List orderItems, Integer price) { - List prices = new ArrayList<>(orderItems.size()); - Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert total != null; - int remainPrice = price; - // 遍历每一个,进行分摊 - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - int partPrice; - if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); - prices.add(partPrice); - } - return prices; - } - - private String formatPrice(Integer price) { - return String.format("%.2f", price / 100d); - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java index 40bcc2836..4dcdb0738 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.module.promotion.service.reward; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; import javax.validation.Valid; -import java.util.Map; -import java.util.Set; +import java.util.Collection; +import java.util.List; /** * 满减送活动 Service 接口 @@ -66,8 +67,8 @@ public interface RewardActivityService { * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 * * @param spuIds SPU 编号数组 - * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 + * @return 满减送活动列表 */ - Map> getMatchRewardActivities(Set spuIds); + List getMatchRewardActivityList(Collection spuIds); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java index 51d0ce626..cdb73853c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.promotion.service.reward; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.util.PromotionUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -18,15 +17,10 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.Set; -import static cn.hutool.core.collection.CollUtil.intersectionDistinct; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; import static java.util.Arrays.asList; -import static java.util.Collections.singleton; /** * 满减送活动 Service 实现类 @@ -105,6 +99,7 @@ public class RewardActivityServiceImpl implements RewardActivityService { return activity; } + // TODO @芋艿:逻辑有问题,需要优化;要分成全场、和指定来校验; /** * 校验商品参加的活动是否冲突 * @@ -151,19 +146,21 @@ public class RewardActivityServiceImpl implements RewardActivityService { } @Override - public Map> getMatchRewardActivities(Set spuIds) { - // 如果有全局活动,则直接选择它 - List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( - PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); - if (CollUtil.isNotEmpty(allActivities)) { - return MapUtil.builder(allActivities.get(0), spuIds).build(); - } - - // 查询某个活动参加的活动 - List productActivityList = getRewardActivityListBySpuIds(spuIds, - singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(productActivityList, activity -> activity, - rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 + public List getMatchRewardActivityList(Collection spuIds) { + // TODO 芋艿:待实现;先指定,然后再全局的; +// // 如果有全局活动,则直接选择它 +// List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( +// PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); +// if (CollUtil.isNotEmpty(allActivities)) { +// return MapUtil.builder(allActivities.get(0), spuIds).build(); +// } +// +// // 查询某个活动参加的活动 +// List productActivityList = getRewardActivityListBySpuIds(spuIds, +// singleton(PromotionActivityStatusEnum.RUN.getStatus())); +// return convertMap(productActivityList, activity -> activity, +// rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 + return null; } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 9e40ff67b..929727077 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -96,8 +96,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getDiscountPrice(), 20); - assertTrue(promotion.getMeet()); - assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); + assertTrue(promotion.getMatch()); + assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元"); PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); assertEquals(promotion.getItems().size(), 1); assertEquals(promotionItem.getSkuId(), 10L); @@ -122,7 +122,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) .setActivityName("活动 2000 号").setSkuId(20L) .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); - when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( + when(discountService.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn( MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); // 10L: 100 * 2 - 40 * 2 = 120 @@ -167,8 +167,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion01.getTotalPrice(), 200); assertEquals(promotion01.getDiscountPrice(), 80); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "限时折扣:省 0.80 元"); PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); assertEquals(promotion01.getItems().size(), 1); assertEquals(promotionItem01.getSkuId(), 10L); @@ -181,8 +181,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion02.getTotalPrice(), 150); assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); + assertTrue(promotion02.getMatch()); + assertEquals(promotion02.getDescription(), "限时折扣:省 0.60 元"); PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); assertEquals(promotion02.getItems().size(), 1); assertEquals(promotionItem02.getSkuId(), 20L); @@ -267,8 +267,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "满减送:省 0.70 元"); assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); @@ -286,8 +286,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); + assertTrue(promotion02.getMatch()); + assertEquals(promotion02.getDescription(), "满减送:省 0.60 元"); PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); assertEquals(promotion02.getItems().size(), 1); assertEquals(promotionItem02.getSkuId(), 30L); @@ -355,8 +355,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 0); - assertFalse(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 + assertFalse(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "TODO"); // TODO 芋艿:后面再想想 assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); @@ -437,8 +437,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index cb0ac8474..b887ae8c8 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -50,4 +50,8 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); + + // ========== Price 相关 1011004000 ============ + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java new file mode 100644 index 000000000..2dd0c41ca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.service.price; + +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +/** + * 价格计算 Service 接口 + * + * @author 芋道源码 + */ +public interface TradePriceService { + + /** + * 价格计算 + * + * @param calculateReqDTO 计算信息 + * @return 计算结果 + */ + TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java new file mode 100644 index 000000000..f0ebce5ba --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java @@ -0,0 +1,73 @@ +package cn.iocoder.yudao.module.trade.service.price; + +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; + +/** + * 价格计算 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class TradePriceServiceImpl implements TradePriceService { + + @Resource + private ProductSkuApi productSkuApi; + @Resource + private List priceCalculators; + + @Override + public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) { + // 1. 获得商品 SKU 数组 + List skuList = checkSkus(calculateReqBO); + + // 2.1 计算价格 + TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper + .buildCalculateResp(calculateReqBO, skuList); + priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); + // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 + if (calculateRespBO.getPrice().getPayPrice() <= 0) { + log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", + calculateReqBO, calculateRespBO); + throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); + } + return calculateRespBO; + } + + private List checkSkus(TradePriceCalculateReqBO reqBO) { + // 获得商品 SKU 数组 + Map skuIdCountMap = convertMap(reqBO.getItems(), + TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount); + List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); + + // 校验商品 SKU + skus.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + if (count == null) { + throw exception(SKU_NOT_EXISTS); + } + if (count > sku.getStock()) { + throw exception(SKU_STOCK_NOT_ENOUGH); + } + }); + return skus; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java new file mode 100644 index 000000000..2a014c0e0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.trade.service.price.bo; + +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 价格计算 Request BO + * + * @author yudao源码 + */ +@Data +public class TradePriceCalculateReqBO { + + /** + * 订单类型 + * + * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer orderType; + + /** + * 用户编号 + * + * 对应 MemberUserDO 的 id 编号 + */ + private Long userId; + + /** + * 优惠劵编号 + * + * 对应 CouponDO 的 id 编号 + */ + private Long couponId; + + /** + * 收货地址编号 + * + * 对应 MemberAddressDO 的 id 编号 + */ + private Long addressId; + + /** + * 商品 SKU 数组 + */ + @NotNull(message = "商品数组不能为空") + private List items; + + /** + * 商品 SKU + */ + @Data + @Valid + public static class Item { + + /** + * SKU 编号 + */ + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + /** + * SKU 数量 + */ + @NotNull(message = "商品 SKU 数量不能为空") + @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") + private Integer count; + + /** + * 购物车项的编号 + */ + private Long cartId; + + /** + * 是否选中 + */ + @NotNull(message = "是否选中不能为空") + private Boolean selected; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java new file mode 100644 index 000000000..b30ba8855 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -0,0 +1,249 @@ +package cn.iocoder.yudao.module.trade.service.price.bo; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 价格计算 Response BO + * + * 整体设计,参考 taobao 的技术文档: + * 1. 订单管理 + * 2. 常用订单金额说明 + * + * @author 芋道源码 + */ +@Data +public class TradePriceCalculateRespBO { + + /** + * 订单类型 + * + * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer orderType; + + /** + * 订单价格 + */ + private Price price; + + /** + * 订单项数组 + */ + private List items; + + /** + * 营销活动数组 + * + * 只对应 {@link Price#items} 商品匹配的活动 + */ + private List promotions; + + /** + * 优惠劵编号 + */ + private Long couponId; + + /** + * 订单价格 + */ + @Data + public static class Price { + + /** + * 商品原价(总),单位:分 + * + * 基于 {@link OrderItem#getPrice()} * {@link OrderItem#getCount()} 求和 + * + * 对应 taobao 的 trade.total_fee 字段 + */ + private Integer totalPrice; + /** + * 订单优惠(总),单位:分 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 运费金额,单位:分 + */ + private Integer deliveryPrice; + /** + * 优惠劵减免金额(总),单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 最终购买金额(总),单位:分 + * + * = {@link #totalPrice} + * - {@link #couponPrice} + * - {@link #pointPrice} + * - {@link #discountPrice} + * + {@link #deliveryPrice} + */ + private Integer payPrice; + + } + + /** + * 订单商品 SKU + */ + @Data + public static class OrderItem { + + /** + * SPU 编号 + */ + private Long spuId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 购买数量 + */ + private Integer count; + /** + * 购物车项的编号 + */ + private Long cartId; + /** + * 是否选中 + */ + private Boolean selected; + + /** + * 商品原价(单),单位:分 + * + * 对应 ProductSkuDO 的 price 字段 + * 对应 taobao 的 order.price 字段 + */ + private Integer price; + /** + * 优惠金额(总),单位:分 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 运费金额(总),单位:分 + */ + private Integer deliveryPrice; + /** + * 优惠劵减免金额,单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 应付金额(总),单位:分 + * + * = {@link #price} * {@link #count} + * - {@link #couponPrice} + * - {@link #pointPrice} + * - {@link #discountPrice} + * + {@link #deliveryPrice} + */ + private Integer payPrice; + + // TODO 芋艿:这里补充下基本信息,简单一点。 + + } + + /** + * 营销明细 + */ + @Data + public static class Promotion { + + /** + * 营销编号 + * + * 例如说:营销活动的编号、优惠劵的编号 + */ + private Long id; + /** + * 营销名字 + */ + private String name; + /** + * 营销类型 + * + * 枚举 {@link PromotionTypeEnum} + */ + private Integer type; + /** + * 营销级别 + * + * 枚举 {@link PromotionLevelEnum} + */ + private Integer level; + /** + * 计算时的原价(总),单位:分 + */ + private Integer totalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + /** + * 匹配的商品 SKU 数组 + */ + private List items; + + // ========== 匹配情况 ========== + + /** + * 是否满足优惠条件 + */ + private Boolean match; + /** + * 满足条件的提示 + * + * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元” + */ + private String description; + + } + + /** + * 营销匹配的商品 SKU + */ + @Data + public static class PromotionItem { + + /** + * 商品 SKU 编号 + */ + private Long skuId; + /** + * 计算时的原价(总),单位:分 + */ + private Integer totalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java new file mode 100644 index 000000000..52ebf84a0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.function.Predicate; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU; + +/** + * 优惠劵的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_COUPON) +public class TradeCouponPriceCalculator implements TradePriceCalculator { + + @Resource + private CouponApi couponApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1.1 校验优惠劵 + if (param.getCouponId() == null) { + return; + } + CouponRespDTO coupon = couponApi.validateCoupon(new CouponValidReqDTO() + .setId(param.getCouponId()).setUserId(param.getUserId())); + Assert.notNull(coupon, "校验通过的优惠劵({}),不能为空", param.getCouponId()); + + // 2.1 获得匹配的商品 SKU 数组 + List orderItems = filterMatchCouponOrderItems(result, coupon); + if (CollUtil.isEmpty(orderItems)) { + throw exception(COUPON_NO_MATCH_SPU); + } + // 2.2 计算是否满足优惠劵的使用金额 + Integer totalPayPrice = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems); + if (totalPayPrice < coupon.getUsePrice()) { + throw exception(COUPON_NO_MATCH_MIN_PRICE); + } + + // 3.1 计算可以优惠的金额 + Integer couponPrice = getCouponPrice(coupon, totalPayPrice); + Assert.isTrue(couponPrice < totalPayPrice, + "优惠劵({}) 的优惠金额({}),不能大于订单总金额({})", coupon.getId(), couponPrice, totalPayPrice); + // 3.2 计算分摊的优惠金额 + List divideCouponPrices = TradePriceCalculatorHelper.dividePrice(orderItems, couponPrice); + + // 4.1 记录使用的优惠劵 + result.setCouponId(param.getCouponId()); + // 4.2 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItems, + param.getCouponId(), coupon.getName(), PromotionTypeEnum.COUPON.getType(), + StrUtil.format("优惠劵:省 {} 元", TradePriceCalculatorHelper.formatPrice(couponPrice)), + divideCouponPrices); + // 4.3 更新 SKU 优惠金额 + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + orderItem.setCouponPrice(divideCouponPrices.get(i)); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + } + TradePriceCalculatorHelper.recountAllPrice(result); + } + + private Integer getCouponPrice(CouponRespDTO coupon, Integer totalPayPrice) { + if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 + return coupon.getDiscountPrice(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 + int couponPrice = totalPayPrice * coupon.getDiscountPercent() / 100; + return coupon.getDiscountLimitPrice() == null ? couponPrice + : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 + } + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); + } + + /** + * 获得优惠劵可使用的订单项(商品)列表 + * + * @param result 计算结果 + * @param coupon 优惠劵 + * @return 订单项(商品)列表 + */ + private List filterMatchCouponOrderItems(TradePriceCalculateRespBO result, + CouponRespDTO coupon) { + Predicate matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; + if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { + matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()); + } + return filterList(result.getItems(), matchPredicate); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java new file mode 100644 index 000000000..7bcd8ffb7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi; +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice; + +/** + * 限时折扣的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY) +public class TradeDiscountActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private DiscountActivityApi discountActivityApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 获得 SKU 对应的限时折扣活动 + List discountProducts = discountActivityApi.getMatchDiscountProductList( + convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSkuId)); + if (CollUtil.isEmpty(discountProducts)) { + return; + } + Map discountProductMap = convertMap(discountProducts, DiscountProductRespDTO::getSkuId); + + // 处理每个 SKU 的限时折扣 + result.getItems().forEach(orderItem -> { + // 1. 获取该 SKU 的优惠信息 + DiscountProductRespDTO discountProduct = discountProductMap.get(orderItem.getSkuId()); + if (discountProduct == null) { + return; + } + // 2. 计算优惠金额 + Integer newPayPrice = calculatePayPrice(discountProduct, orderItem); + Integer newDiscountPrice = orderItem.getPayPrice() - newPayPrice; + + // 3.1 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItem, + discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), + StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)), + newDiscountPrice); + // 3.2 更新 SKU 优惠金额 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + newDiscountPrice); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + }); + TradePriceCalculatorHelper.recountAllPrice(result); + } + + private Integer calculatePayPrice(DiscountProductRespDTO discountProduct, + TradePriceCalculateRespBO.OrderItem orderItem) { + Integer price = orderItem.getPayPrice(); + if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 + price -= discountProduct.getDiscountPrice() * orderItem.getCount(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 + price = price * discountProduct.getDiscountPercent() / 100; + } else { + throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); + } + return price; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java new file mode 100644 index 000000000..1c9b4f988 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +/** + * 价格计算的计算器接口 + * + * @author 芋道源码 + */ +public interface TradePriceCalculator { + + int ORDER_DISCOUNT_ACTIVITY = 10; + int ORDER_REWARD_ACTIVITY = 20; + int ORDER_COUPON = 30; + + void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java new file mode 100644 index 000000000..9ed94b692 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -0,0 +1,221 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static java.util.Collections.singletonList; + +/** + * {@link TradePriceCalculator} 的工具类 + * + * 主要实现对 {@link TradePriceCalculateRespBO} 计算结果的操作 + * + * @author 芋道源码 + */ +public class TradePriceCalculatorHelper { + + public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, + List skuList) { + // 创建 PriceCalculateRespDTO 对象 + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); + result.setOrderType(param.getOrderType()); + // 创建它的 OrderItem 属性 + Map skuItemMap = convertMap(param.getItems(), + TradePriceCalculateReqBO.Item::getSkuId); + result.setItems(new ArrayList<>(skuItemMap.size())); + skuList.forEach(sku -> { + TradePriceCalculateReqBO.Item skuItem = skuItemMap.get(sku.getId()); + TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem() + // SKU 字段 + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()) + .setCount(skuItem.getCount()).setCartId(skuItem.getCartId()).setSelected(skuItem.getSelected()) + // 价格字段 + .setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * skuItem.getCount()) + .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); + result.getItems().add(orderItem); + }); + // 创建它的 Price 属性 + result.setPrice(new TradePriceCalculateRespBO.Price()); + recountAllPrice(result); + return result; + } + + /** + * 基于订单项,重新计算 price 总价 + * + * @param result 计算结果 + */ + public static void recountAllPrice(TradePriceCalculateRespBO result) { + // 先重置 + TradePriceCalculateRespBO.Price price = result.getPrice(); + price.setTotalPrice(0).setDiscountPrice(0).setDeliveryPrice(0) + .setCouponPrice(0).setPointPrice(0).setPayPrice(0); + // 再合计 item + result.getItems().forEach(item -> { + if (!item.getSelected()) { + return; + } + price.setTotalPrice(price.getTotalPrice() + item.getPrice() * item.getCount()); + price.setDiscountPrice(price.getDiscountPrice() + item.getDiscountPrice()); + price.setDeliveryPrice(price.getDeliveryPrice() + item.getDeliveryPrice()); + price.setCouponPrice(price.getCouponPrice() + item.getCouponPrice()); + price.setPointPrice(price.getPointPrice() + item.getPointPrice()); + price.setPayPrice(price.getPayPrice() + item.getPayPrice()); + }); + } + + /** + * 重新计算单个订单项的支付金额 + * + * @param orderItem 订单项 + */ + public static void recountPayPrice(TradePriceCalculateRespBO.OrderItem orderItem) { + orderItem.setPayPrice(orderItem.getPrice()* orderItem.getCount() + - orderItem.getDiscountPrice() + + orderItem.getDeliveryPrice() + - orderItem.getCouponPrice() + - orderItem.getPointPrice()); + } + + /** + * 计算已选中的订单项,总支付金额 + * + * @param orderItems 订单项数组 + * @return 总支付金额 + */ + public static Integer calculateTotalPayPrice(List orderItems) { + return getSumValue(orderItems, + orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 + Integer::sum); + } + + /** + * 计算已选中的订单项,总商品数 + * + * @param orderItems 订单项数组 + * @return 总商品数 + */ + public static Integer calculateTotalCount(List orderItems) { + return getSumValue(orderItems, + orderItem -> orderItem.getSelected() ? orderItem.getCount() : 0, // 未选中的情况下,不计算数量 + Integer::sum); + } + + /** + * 按照支付金额,返回每个订单项的分摊金额数组 + * + * @param orderItems 订单项数组 + * @param price 金额 + * @return 分摊金额数组,和传入的 orderItems 一一对应 + */ + public static List dividePrice(List orderItems, Integer price) { + Integer total = calculateTotalPayPrice(orderItems); + assert total != null; + // 遍历每一个,进行分摊 + List prices = new ArrayList<>(orderItems.size()); + int remainPrice = price; + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + // 1. 如果是未选中,则分摊为 0 + if (!orderItem.getSelected()) { + prices.add(0); + continue; + } + // 2. 如果选中,则按照百分比,进行分摊 + int partPrice; + if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 + partPrice = (int) (price * (1.0D * orderItem.getPayPrice() / total)); + remainPrice -= partPrice; + } else { + partPrice = remainPrice; + } + Assert.isTrue(partPrice >= 0, "分摊金额必须大于等于 0"); + prices.add(partPrice); + } + return prices; + } + + /** + * 添加【匹配】单个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItem 单个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + * @param discountPrice 单个订单商品 SKU 的优惠价格(总) + */ + public static void addPromotion(TradePriceCalculateRespBO result, TradePriceCalculateRespBO.OrderItem orderItem, + Long id, String name, Integer type, String description, Integer discountPrice) { + addPromotion(result, singletonList(orderItem), id, name, type, description, singletonList(discountPrice)); + } + + /** + * 添加【匹配】多个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 + */ + public static void addPromotion(TradePriceCalculateRespBO result, List orderItems, + Long id, String name, Integer type, String description, List discountPrices) { + // 创建营销明细 Item + List promotionItems = new ArrayList<>(discountPrices.size()); + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + promotionItems.add(new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); + } + // 创建营销明细 + TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() + .setId(id).setName(name).setType(type) + .setTotalPrice(calculateTotalPayPrice(orderItems)) + .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) + .setItems(promotionItems).setMatch(true).setDescription(description); + result.getPromotions().add(promotion); + } + + /** + * 添加【不匹配】多个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + */ + public static void addNotMatchPromotion(TradePriceCalculateRespBO result, List orderItems, + Long id, String name, Integer type, String description) { + // 创建营销明细 Item + List promotionItems = CollectionUtils.convertList(orderItems, + orderItem -> new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(0)); + // 创建营销明细 + TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() + .setId(id).setName(name).setType(type) + .setTotalPrice(calculateTotalPayPrice(orderItems)) + .setDiscountPrice(0) + .setItems(promotionItems).setMatch(false).setDescription(description); + result.getPromotions().add(promotion); + } + + public static String formatPrice(Integer price) { + return String.format("%.2f", price / 100d); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java new file mode 100644 index 000000000..b0947fcc3 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice; + +/** + * 满减送活动的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_REWARD_ACTIVITY) +public class TradeRewardActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private RewardActivityApi rewardActivityApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 获得 SKU 对应的满减送活动 + List rewardActivities = rewardActivityApi.getMatchRewardActivityList( + convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSpuId)); + if (CollUtil.isEmpty(rewardActivities)) { + return; + } + + // 处理每个满减送活动 + rewardActivities.forEach(rewardActivity -> calculate(param, result, rewardActivity)); + } + + private void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result, + RewardActivityMatchRespDTO rewardActivity) { + // 1.1 获得满减送的订单项(商品)列表 + List orderItems = filterMatchCouponOrderItems(result, rewardActivity); + if (CollUtil.isEmpty(orderItems)) { + return; + } + // 1.2 获得最大匹配的满减送活动的规则 + RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); + if (rule == null) { + return; + } + + // 2.1 计算可以优惠的金额 + Integer newDiscountPrice = rule.getDiscountPrice(); + // 2.2 计算分摊的优惠金额 + List divideDiscountPrices = TradePriceCalculatorHelper.dividePrice(orderItems, newDiscountPrice); + + // 3.1 记录使用的优惠劵 + result.setCouponId(param.getCouponId()); + // 3.2 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItems, + rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(), + StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice())), + divideDiscountPrices); + // 3.3 更新 SKU 优惠金额 + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + divideDiscountPrices.get(i)); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + } + TradePriceCalculatorHelper.recountAllPrice(result); + } + + /** + * 获得满减送的订单项(商品)列表 + * + * @param result 计算结果 + * @param rewardActivity 满减送活动 + * @return 订单项(商品)列表 + */ + private List filterMatchCouponOrderItems(TradePriceCalculateRespBO result, + RewardActivityMatchRespDTO rewardActivity) { + return filterList(result.getItems(), + orderItem -> CollUtil.contains(rewardActivity.getSpuIds(), orderItem.getSpuId())); + } + + /** + * 获得最大匹配的满减送活动的规则 + * + * @param rewardActivity 满减送活动 + * @param orderItems 商品项 + * @return 匹配的活动规则 + */ + private RewardActivityMatchRespDTO.Rule getMaxMatchRewardActivityRule(RewardActivityMatchRespDTO rewardActivity, + List orderItems) { + // 1. 计算数量和价格 + Integer count = TradePriceCalculatorHelper.calculateTotalCount(orderItems); + Integer price = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems); + assert count != null && price != null; + + // 2. 倒序找一个最大优惠的规则 + for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { + RewardActivityMatchRespDTO.Rule rule = rewardActivity.getRules().get(i); + if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) + && price >= rule.getLimit()) { + return rule; + } + if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) + && count >= rule.getLimit()) { + return rule; + } + } + return null; + } + + /** + * 获得满减送活动部匹配时的提示 + * + * @param rewardActivity 满减送活动 + * @return 提示 + */ + private String getRewardActivityNotMeetTip(RewardActivityMatchRespDTO rewardActivity) { + // TODO 芋艿:后面再想想;应该找第一个规则,算下还差多少即可。 + return "TODO"; + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java index bd65bddfd..78f1c7902 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreate import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; import cn.iocoder.yudao.module.member.convert.address.AddressConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.service.address.AddressService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; @@ -54,21 +54,21 @@ public class AppAddressController { @Operation(summary = "获得用户收件地址") @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getAddress(@RequestParam("id") Long id) { - AddressDO address = addressService.getAddress(getLoginUserId(), id); + MemberAddressDO address = addressService.getAddress(getLoginUserId(), id); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/get-default") @Operation(summary = "获得默认的用户收件地址") public CommonResult getDefaultUserAddress() { - AddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); + MemberAddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/list") @Operation(summary = "获得用户收件地址列表") public CommonResult> getAddressList() { - List list = addressService.getAddressList(getLoginUserId()); + List list = addressService.getAddressList(getLoginUserId()); return success(AddressConvert.INSTANCE.convertList(list)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java index 49a01805d..a93d79ec1 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -21,16 +21,16 @@ public interface AddressConvert { AddressConvert INSTANCE = Mappers.getMapper(AddressConvert.class); - AddressDO convert(AppAddressCreateReqVO bean); + MemberAddressDO convert(AppAddressCreateReqVO bean); - AddressDO convert(AppAddressUpdateReqVO bean); + MemberAddressDO convert(AppAddressUpdateReqVO bean); - AppAddressRespVO convert(AddressDO bean); + AppAddressRespVO convert(MemberAddressDO bean); - List convertList(List list); + List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); - AddressRespDTO convert02(AddressDO bean); + AddressRespDTO convert02(MemberAddressDO bean); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java similarity index 95% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java index 7d8a96250..560edbba9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java @@ -17,7 +17,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class AddressDO extends BaseDO { +public class MemberAddressDO extends BaseDO { /** * 编号 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java index 80f78d41f..13ca89ef9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java @@ -2,21 +2,21 @@ package cn.iocoder.yudao.module.member.dal.mysql.address; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper -public interface AddressMapper extends BaseMapperX { +public interface AddressMapper extends BaseMapperX { - default AddressDO selectByIdAndUserId(Long id, Long userId) { - return selectOne(AddressDO::getId, id, AddressDO::getUserId, userId); + default MemberAddressDO selectByIdAndUserId(Long id, Long userId) { + return selectOne(MemberAddressDO::getId, id, MemberAddressDO::getUserId, userId); } - default List selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) { - return selectList(new LambdaQueryWrapperX().eq(AddressDO::getUserId, userId) - .eqIfPresent(AddressDO::getDefaulted, defaulted)); + default List selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) { + return selectList(new LambdaQueryWrapperX().eq(MemberAddressDO::getUserId, userId) + .eqIfPresent(MemberAddressDO::getDefaulted, defaulted)); } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java index 456a3d8ac..099c49c42 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.member.service.address; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import javax.validation.Valid; import java.util.List; @@ -46,7 +46,7 @@ public interface AddressService { * @param id 编号 * @return 用户收件地址 */ - AddressDO getAddress(Long userId, Long id); + MemberAddressDO getAddress(Long userId, Long id); /** * 获得用户收件地址列表 @@ -54,7 +54,7 @@ public interface AddressService { * @param userId 用户编号 * @return 用户收件地址列表 */ - List getAddressList(Long userId); + List getAddressList(Long userId); /** * 获得用户默认的收件地址 @@ -62,6 +62,6 @@ public interface AddressService { * @param userId 用户编号 * @return 用户收件地址 */ - AddressDO getDefaultUserAddress(Long userId); + MemberAddressDO getDefaultUserAddress(Long userId); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java index bbcbbe592..488e7d32c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; import cn.iocoder.yudao.module.member.convert.address.AddressConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,12 +33,12 @@ public class AddressServiceImpl implements AddressService { public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) { // 如果添加的是默认收件地址,则将原默认地址修改为非默认 if (Boolean.TRUE.equals(createReqVO.getDefaulted())) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); - addresses.forEach(address -> addressMapper.updateById(new AddressDO().setId(address.getId()).setDefaulted(false))); + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + addresses.forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false))); } // 插入 - AddressDO address = AddressConvert.INSTANCE.convert(createReqVO); + MemberAddressDO address = AddressConvert.INSTANCE.convert(createReqVO); address.setUserId(userId); addressMapper.insert(address); // 返回 @@ -53,13 +53,13 @@ public class AddressServiceImpl implements AddressService { // 如果修改的是默认收件地址,则将原默认地址修改为非默认 if (Boolean.TRUE.equals(updateReqVO.getDefaulted())) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己 - .forEach(address -> addressMapper.updateById(new AddressDO().setId(address.getId()).setDefaulted(false))); + .forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false))); } // 更新 - AddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO); + MemberAddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO); addressMapper.updateById(updateObj); } @@ -72,25 +72,25 @@ public class AddressServiceImpl implements AddressService { } private void validAddressExists(Long userId, Long id) { - AddressDO addressDO = getAddress(userId, id); + MemberAddressDO addressDO = getAddress(userId, id); if (addressDO == null) { throw exception(ADDRESS_NOT_EXISTS); } } @Override - public AddressDO getAddress(Long userId, Long id) { + public MemberAddressDO getAddress(Long userId, Long id) { return addressMapper.selectByIdAndUserId(id, userId); } @Override - public List getAddressList(Long userId) { + public List getAddressList(Long userId) { return addressMapper.selectListByUserIdAndDefaulted(userId, null); } @Override - public AddressDO getDefaultUserAddress(Long userId) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + public MemberAddressDO getDefaultUserAddress(Long userId) { + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); return CollUtil.getFirst(addresses); } diff --git a/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java b/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java index 6ddf80a0e..77b40705e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java +++ b/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.service.address; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; @@ -42,14 +42,14 @@ public class AddressServiceImplTest extends BaseDbUnitTest { // 断言 assertNotNull(addressId); // 校验记录的属性是否正确 - AddressDO address = addressMapper.selectById(addressId); + MemberAddressDO address = addressMapper.selectById(addressId); assertPojoEquals(reqVO, address); } @Test public void testUpdateAddress_success() { // mock 数据 - AddressDO dbAddress = randomPojo(AddressDO.class); + MemberAddressDO dbAddress = randomPojo(MemberAddressDO.class); addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据 // 准备参数 AppAddressUpdateReqVO reqVO = randomPojo(AppAddressUpdateReqVO.class, o -> { @@ -59,7 +59,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest { // 调用 addressService.updateAddress(dbAddress.getUserId(), reqVO); // 校验是否更新正确 - AddressDO address = addressMapper.selectById(reqVO.getId()); // 获取最新的 + MemberAddressDO address = addressMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, address); } @@ -75,7 +75,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest { @Test public void testDeleteAddress_success() { // mock 数据 - AddressDO dbAddress = randomPojo(AddressDO.class); + MemberAddressDO dbAddress = randomPojo(MemberAddressDO.class); addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbAddress.getId(); From 0631c51d93aec31c42533bf54b30b2dfc6f84d3e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 28 May 2023 20:09:51 +0800 Subject: [PATCH 064/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/string/StrUtils.java | 5 +- .../mybatis/core/mapper/BaseMapperX.java | 2 +- .../promotion/api/coupon/CouponApi.java | 10 + .../api/coupon/dto/CouponRespDTO.java | 109 ++++ .../api/coupon/dto/CouponValidReqDTO.java | 27 + .../api/discount/DiscountActivityApi.java | 23 + .../discount/dto/DiscountProductRespDTO.java} | 18 +- .../module/promotion/api/package-info.java | 4 - .../api/price/dto/PriceCalculateReqDTO.java | 5 + .../api/price/dto/PriceCalculateRespDTO.java | 10 +- .../api/reward/RewardActivityApi.java | 24 + .../dto/RewardActivityMatchRespDTO.java | 77 +++ .../enums/common/PromotionLevelEnum.java | 40 -- .../enums/common/PromotionTypeEnum.java | 3 +- .../promotion/api/coupon/CouponApiImpl.java | 10 + .../api/discount/DiscountActivityApiImpl.java | 28 ++ .../promotion/api/discount/package-info.java | 1 - .../api/reward/RewardActivityApiImpl.java | 27 + .../convert/coupon/CouponConvert.java | 3 + .../discount/DiscountActivityConvert.java | 20 +- .../discount/DiscountActivityDO.java | 7 +- .../discount/DiscountProductDO.java | 3 + .../dataobject/reward/RewardActivityDO.java | 1 + .../discount/DiscountActivityService.java | 4 +- .../discount/DiscountActivityServiceImpl.java | 42 +- .../promotion/service/price/PriceService.java | 9 - .../service/price/PriceServiceImpl.java | 466 +----------------- .../service/reward/RewardActivityService.java | 9 +- .../reward/RewardActivityServiceImpl.java | 37 +- .../service/price/PriceServiceTest.java | 30 +- .../trade/enums/ErrorCodeConstants.java | 4 + .../delivery/DeliveryExpressController.java | 3 +- .../DeliveryExpressTemplateController.java | 31 +- .../{ => express}/DeliveryExpressBaseVO.java | 2 +- .../DeliveryExpressCreateReqVO.java | 4 +- .../{ => express}/DeliveryExpressExcelVO.java | 2 +- .../DeliveryExpressExportReqVO.java | 2 +- .../DeliveryExpressPageReqVO.java | 2 +- .../{ => express}/DeliveryExpressRespVO.java | 2 +- .../DeliveryExpressUpdateReqVO.java | 10 +- .../DeliveryExpressTemplateBaseVO.java | 2 +- .../DeliveryExpressTemplateCreateReqVO.java | 11 +- .../DeliveryExpressTemplatePageReqVO.java | 10 +- .../DeliveryExpressTemplateRespVO.java | 2 +- .../DeliveryExpressTemplateSimpleRespVO.java | 3 +- .../DeliveryExpressTemplateUpdateReqVO.java | 14 +- .../ExpressTemplateChargeBaseVO.java | 2 +- .../ExpressTemplateChargeUpdateVO.java | 8 +- .../ExpressTemplateFreeBaseVO.java | 3 +- .../ExpressTemplateFreeUpdateVO.java | 4 +- .../delivery/DeliveryExpressConvert.java | 8 +- .../DeliveryExpressTemplateConvert.java | 5 +- .../mysql/delivery/DeliveryExpressMapper.java | 4 +- .../DeliveryExpressTemplateMapper.java | 2 +- .../delivery/DeliveryExpressService.java | 8 +- .../delivery/DeliveryExpressServiceImpl.java | 8 +- .../DeliveryExpressTemplateService.java | 11 +- .../DeliveryExpressTemplateServiceImpl.java | 49 +- .../service/price/TradePriceService.java | 21 + .../service/price/TradePriceServiceImpl.java | 73 +++ .../price/bo/TradePriceCalculateReqBO.java | 86 ++++ .../price/bo/TradePriceCalculateRespBO.java | 249 ++++++++++ .../TradeCouponPriceCalculator.java | 109 ++++ .../TradeDiscountActivityPriceCalculator.java | 80 +++ .../calculator/TradePriceCalculator.java | 19 + .../TradePriceCalculatorHelper.java | 221 +++++++++ .../TradeRewardActivityPriceCalculator.java | 133 +++++ .../app/address/AppAddressController.java | 8 +- .../convert/address/AddressConvert.java | 14 +- .../{AddressDO.java => MemberAddressDO.java} | 2 +- .../dal/mysql/address/AddressMapper.java | 14 +- .../service/address/AddressService.java | 8 +- .../service/address/AddressServiceImpl.java | 24 +- .../address/AddressServiceImplTest.java | 10 +- .../module/system/convert/ip/AreaConvert.java | 5 +- 75 files changed, 1588 insertions(+), 758 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java rename yudao-module-mall/{yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java => yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java} (72%) delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressBaseVO.java (98%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressCreateReqVO.java (84%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressExcelVO.java (98%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressExportReqVO.java (98%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressPageReqVO.java (98%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressRespVO.java (97%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => express}/DeliveryExpressUpdateReqVO.java (77%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplateBaseVO.java (97%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplateCreateReqVO.java (77%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplatePageReqVO.java (90%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplateRespVO.java (97%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplateSimpleRespVO.java (82%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/DeliveryExpressTemplateUpdateReqVO.java (77%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/ExpressTemplateChargeBaseVO.java (98%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/ExpressTemplateChargeUpdateVO.java (61%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/ExpressTemplateFreeBaseVO.java (97%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/{ => expresstemplate}/ExpressTemplateFreeUpdateVO.java (72%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/{AddressDO.java => MemberAddressDO.java} (95%) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java index 2ac7278a4..cd5db713c 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java @@ -40,15 +40,14 @@ public class StrUtils { return false; } - public static List splitToLong(String value, CharSequence separator) { + public static List splitToLong(String value, CharSequence separator) { long[] longs = StrUtil.splitToLong(value, separator); return Arrays.stream(longs).boxed().collect(Collectors.toList()); } - public static List splitToInteger(String value, CharSequence separator) { + public static List splitToInteger(String value, CharSequence separator) { int[] integers = StrUtil.splitToInt(value, separator); return Arrays.stream(integers).boxed().collect(Collectors.toList()); } - } diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java index 7788d2895..5dee2ba00 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java @@ -113,7 +113,7 @@ public interface BaseMapperX extends MPJBaseMapper { Db.saveBatch(entities, size); } - // @芋艿 是不是叫 updateByDo 或者 updateByEntity 更合适 + // @芋艿 是不是叫 updateByDo 或者 updateByEntity 更合适;回复:因为是使用实体作为条件去批量更新,所以没加 ByEntity,保持和 mybatis plus 风格一致 default void updateBatch(T update) { update(update, new QueryWrapper<>()); } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java index f99ff815f..ce7a712da 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.promotion.api.coupon; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; import javax.validation.Valid; @@ -18,4 +20,12 @@ public interface CouponApi { */ void useCoupon(@Valid CouponUseReqDTO useReqDTO); + /** + * 校验优惠劵 + * + * @param validReqDTO 校验请求 + * @return 优惠劵 + */ + CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO); + } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java new file mode 100644 index 000000000..34031e604 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.promotion.api.coupon.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 优惠劵 Response DTO + * + * @author 芋道源码 + */ +@Data +public class CouponRespDTO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Long id; + /** + * 优惠劵模板编号 + */ + private Integer templateId; + /** + * 优惠劵名 + */ + private String name; + /** + * 优惠码状态 + * + * 枚举 {@link CouponStatusEnum} + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 字段 + */ + private Long userId; + /** + * 领取类型 + * + * 枚举 {@link CouponTakeTypeEnum} + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + */ + private Integer usePrice; + /** + * 生效开始时间 + */ + private LocalDateTime validStartTime; + /** + * 生效结束时间 + */ + private LocalDateTime validEndTime; + /** + * 商品范围 + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + private List productSpuIds; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 折扣类型 + */ + private Integer discountType; + /** + * 折扣百分比 + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + */ + private Integer discountPrice; + /** + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 + */ + private Integer discountLimitPrice; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 使用订单号 + */ + private Long useOrderId; + /** + * 使用时间 + */ + private LocalDateTime useTime; + + // ========== 使用情况 END ========== +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java new file mode 100644 index 000000000..dd25c6408 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.coupon.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 优惠劵使用 Request DTO + * + * @author 芋道源码 + */ +@Data +public class CouponValidReqDTO { + + /** + * 优惠劵编号 + */ + @NotNull(message = "优惠劵编号不能为空") + private Long id; + + /** + * 用户编号 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java new file mode 100644 index 000000000..b25f67d9f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApi.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.promotion.api.discount; + +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 限时折扣 API 接口 + * + * @author 芋道源码 + */ +public interface DiscountActivityApi { + + /** + * 获得商品匹配的的限时折扣信息 + * + * @param skuIds 商品 SKU 编号数组 + * @return 限时折扣信息 + */ + List getMatchDiscountProductList(Collection skuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java similarity index 72% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java rename to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java index 7b8f4a20f..52dfdbe27 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/dto/DiscountProductRespDTO.java @@ -1,25 +1,19 @@ -package cn.iocoder.yudao.module.promotion.service.discount.bo; +package cn.iocoder.yudao.module.promotion.api.discount.dto; import lombok.Data; /** - * 限时折扣活动商品 BO + * 限时折扣活动商品 Response DTO * * @author 芋道源码 */ @Data -public class DiscountProductDetailBO { - - // ========== DiscountProductDO 字段 ========== +public class DiscountProductRespDTO { /** * 编号,主键自增 */ private Long id; - /** - * 限时折扣活动的编号 - */ - private Long activityId; /** * 商品 SPU 编号 */ @@ -41,7 +35,11 @@ public class DiscountProductDetailBO { */ private Integer discountPrice; - // ========== DiscountActivityDO 字段 ========== + // ========== 活动字段 ========== + /** + * 限时折扣活动的编号 + */ + private Long activityId; /** * 活动标题 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java deleted file mode 100644 index 08e1020a6..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.module.promotion.api; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java index 01f0ac220..ce53de50e 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java @@ -26,6 +26,11 @@ public class PriceCalculateReqDTO { */ private Long couponId; + /** + * 收货地址编号 + */ + private Long addressId; + /** * 商品 SKU 数组 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java index a067aa0b5..9a98029b7 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -24,6 +24,7 @@ import java.util.List; * @author 芋道源码 */ @Data +@Deprecated public class PriceCalculateRespDTO { /** @@ -174,6 +175,7 @@ public class PriceCalculateRespDTO { * 营销明细 */ @Data + @Deprecated public static class Promotion { /** @@ -216,14 +218,14 @@ public class PriceCalculateRespDTO { /** * 是否满足优惠条件 */ - private Boolean meet; + private Boolean match; /** * 满足条件的提示 * - * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” - * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” + * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元” */ - private String meetTip; + private String description; } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java new file mode 100644 index 000000000..efeddf3d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApi.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.api.reward; + +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 满减送活动 API 接口 + * + * @author 芋道源码 + */ +public interface RewardActivityApi { + + + /** + * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 + * + * @param spuIds SPU 编号数组 + * @return 满减送活动列表 + */ + List getMatchRewardActivityList(Collection spuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java new file mode 100644 index 000000000..19f46a49a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/dto/RewardActivityMatchRespDTO.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.promotion.api.reward.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 满减送活动的匹配 Response DTO + * + * @author 芋道源码 + */ +@Data +public class RewardActivityMatchRespDTO { + + /** + * 活动编号,主键自增 + */ + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 条件类型 + * + * 枚举 {@link PromotionConditionTypeEnum} + */ + private Integer conditionType; + /** + * 优惠规则的数组 + */ + private List rules; + + /** + * 商品 SPU 编号的数组 + */ + private List spuIds; + + // TODO 芋艿:后面 RewardActivityRespDTO 有了之后,Rule 可以放过去 + /** + * 优惠规则 + */ + @Data + public static class Rule { + + /** + * 优惠门槛 + * + * 1. 满 N 元,单位:分 + * 2. 满 N 件 + */ + private Integer limit; + /** + * 优惠价格,单位:分 + */ + private Integer discountPrice; + /** + * 是否包邮 + */ + private Boolean freeDelivery; + /** + * 赠送的积分 + */ + private Integer point; + /** + * 赠送的优惠劵编号的数组 + */ + private List couponIds; + /** + * 赠送的优惠卷数量的数组 + */ + private List couponCounts; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java deleted file mode 100644 index ed0564a70..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的级别枚举 - * - * 参考有赞:营销级别 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionLevelEnum implements IntArrayValuable { - - ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 - SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 - COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); - - /** - * 级别值 - */ - private final Integer level; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java index eea48f7dc..ee87306bf 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java @@ -18,7 +18,7 @@ public enum PromotionTypeEnum implements IntArrayValuable { DISCOUNT_ACTIVITY(1, "限时折扣"), REWARD_ACTIVITY(2, "满减送"), - MEMBER(3, "会员折扣"), + MEMBER(3, "会员折扣"), // TODO 芋艿:待实现 StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice) COUPON(4, "优惠劵") ; @@ -37,4 +37,5 @@ public enum PromotionTypeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java index 349eba1ff..a06ab57cd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.promotion.api.coupon; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; import org.springframework.stereotype.Service; @@ -24,4 +28,10 @@ public class CouponApiImpl implements CouponApi { useReqDTO.getOrderId()); } + @Override + public CouponRespDTO validateCoupon(CouponValidReqDTO validReqDTO) { + CouponDO coupon = couponService.validCoupon(validReqDTO.getId(), validReqDTO.getUserId()); + return CouponConvert.INSTANCE.convert(coupon); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java new file mode 100644 index 000000000..2227da43e --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.api.discount; + +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 限时折扣 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class DiscountActivityApiImpl implements DiscountActivityApi { + + @Resource + private DiscountActivityService discountActivityService; + + @Override + public List getMatchDiscountProductList(Collection skuIds) { + return DiscountActivityConvert.INSTANCE.convertList02(discountActivityService.getMatchDiscountProductList(skuIds)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java deleted file mode 100644 index 4e3ce77a8..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java new file mode 100644 index 000000000..ee8bac7c9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.reward; + +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 满减送活动 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class RewardActivityApiImpl implements RewardActivityApi { + + @Resource + private RewardActivityService rewardActivityService; + + @Override + public List getMatchRewardActivityList(Collection spuIds) { + return rewardActivityService.getMatchRewardActivityList(spuIds); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java index 281318f7d..7bfdca706 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.convert.coupon; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import org.mapstruct.Mapper; @@ -18,4 +19,6 @@ public interface CouponConvert { PageResult convertPage(PageResult page); + CouponRespDTO convert(CouponDO bean); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java index 07d2e03ab..ebf53ce8a 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java @@ -2,18 +2,15 @@ package cn.iocoder.yudao.module.promotion.convert.discount; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; -import java.util.Map; /** * 限时折扣活动 Convert @@ -33,20 +30,10 @@ public interface DiscountActivityConvert { List convertList(List list); + List convertList02(List list); + PageResult convertPage(PageResult page); - DiscountProductDetailBO convert(DiscountProductDO product); - - default List convertList(List products, Map activityMap) { - return CollectionUtils.convertList(products, product -> { - DiscountProductDetailBO detail = convert(product); - MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> { - detail.setActivityName(activity.getName()); - }); - return detail; - }); - } - DiscountProductDO convert(DiscountActivityBaseVO.Product bean); DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List products); @@ -99,4 +86,5 @@ public interface DiscountActivityConvert { return true; } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java index 91071f309..fd0726e39 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -33,10 +33,13 @@ public class DiscountActivityDO extends BaseDO { * 活动标题 */ private String name; + // TODO 芋艿:状态调整,只有开启和关闭; /** * 状态 * - * 枚举 {@link PromotionActivityStatusEnum} + * 枚举 {@link CommonStatusEnum} + * + * 活动被关闭后,不允许再次开启。 */ private Integer status; /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java index 55c924e4f..7f61f7f6d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java @@ -24,12 +24,15 @@ public class DiscountProductDO extends BaseDO { */ @TableId private Long id; + + // TODO 芋艿:把 activity 所有的字段冗余过来 /** * 限时折扣活动的编号 * * 关联 {@link DiscountActivityDO#getId()} */ private Long activityId; + /** * 商品 SPU 编号 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java index e825881d1..9d417d75f 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java @@ -38,6 +38,7 @@ public class RewardActivityDO extends BaseDO { * 活动标题 */ private String name; + // TODO @芋艿:改成开启、禁用两种状态 /** * 状态 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java index 8b6e5895b..7473f12cd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java @@ -6,12 +6,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountAc import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import javax.validation.Valid; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 限时折扣 Service 接口 @@ -28,7 +26,7 @@ public interface DiscountActivityService { * @param skuIds SKU 编号数组 * @return 匹配的限时折扣商品 */ - Map getMatchDiscountProducts(Collection skuIds); + List getMatchDiscountProductList(Collection skuIds); /** * 创建限时折扣活动 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java index df54d44f2..97d70491b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.discount; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; @@ -14,18 +13,17 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProduct import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import cn.iocoder.yudao.module.promotion.util.PromotionUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.*; +import java.util.Collection; +import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; /** * 限时折扣 Service 实现类 @@ -42,9 +40,9 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { private DiscountProductMapper discountProductMapper; @Override - public Map getMatchDiscountProducts(Collection skuIds) { - List discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(discountProducts, DiscountProductDetailBO::getSkuId); + public List getMatchDiscountProductList(Collection skuIds) { + // TODO 芋艿:开启、满足 skuId、日期内 + return null; } @Override @@ -101,6 +99,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { } } + // TODO 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。 /** * 校验商品是否冲突 * @@ -112,9 +111,10 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { return; } // 查询商品参加的活动 - List discountActivityProductList = getRewardProductListBySkuIds( - convertSet(products, DiscountActivityBaseVO.Product::getSkuId), - asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); + List discountActivityProductList = null; +// getRewardProductListBySkuIds( +// convertSet(products, DiscountActivityBaseVO.Product::getSkuId), +// asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); if (id != null) { // 排除自己这个活动 discountActivityProductList.removeIf(product -> id.equals(product.getActivityId())); } @@ -124,24 +124,6 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { } } - private List getRewardProductListBySkuIds(Collection skuIds, - Collection statuses) { - // 查询商品 - List products = discountProductMapper.selectListBySkuId(skuIds); - if (CollUtil.isEmpty(products)) { - return new ArrayList<>(0); - } - - // 查询活动 - List activities = discountActivityMapper.selectBatchIds(skuIds); - activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的 - Map activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId); - - // 移除不满足活动的商品 - products.removeIf(product -> !activityMap.containsKey(product.getActivityId())); - return DiscountActivityConvert.INSTANCE.convertList(products, activityMap); - } - @Override public void closeRewardActivity(Long id) { // 校验存在 @@ -153,7 +135,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END); } - // 更新 + // 更新为关闭。 DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); discountActivityMapper.updateById(updateObj); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java index a7420e119..f402cb1be 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.service.price; import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import java.util.List; @@ -13,14 +12,6 @@ import java.util.List; */ public interface PriceService { - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格响应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - /** * 获得优惠劵的匹配信息列表 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java index 7aab0bee5..439c03d37 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java @@ -1,39 +1,25 @@ package cn.iocoder.yudao.module.promotion.service.price; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.enums.common.*; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import com.google.common.base.Suppliers; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.*; -import java.util.function.Supplier; +import java.util.Collections; +import java.util.List; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Collections.singletonList; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; /** * 价格计算 Service 实现类 @@ -54,43 +40,14 @@ import static java.util.Collections.singletonList; @Slf4j public class PriceServiceImpl implements PriceService { - @Resource - private DiscountActivityService discountService; - @Resource - private RewardActivityService rewardActivityService; @Resource private CouponService couponService; - @Resource - private ProductSkuApi productSkuApi; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - List skuList = checkSkus(calculateReqDTO); - // 初始化 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); - - // 计算商品级别的价格 - calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算订单级别的价格 - calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算优惠劵级别的价格 - calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); - - // 如果最终支付金额小于等于 0,则抛出业务异常 - if (priceCalculate.getOrder().getPayPrice() <= 0) { - log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", - calculateReqDTO, priceCalculate); - throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); - } - return priceCalculate; - } - @Override public List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO) { // 先计算一轮价格 - PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); +// PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); + PriceCalculateRespDTO priceCalculate = null; // 获得用户的待使用优惠劵 List couponList = couponService.getCouponList(calculateReqDTO.getUserId(), CouponStatusEnum.UNUSED.getStatus()); @@ -106,7 +63,9 @@ public class PriceServiceImpl implements PriceService { couponService.validCoupon(coupon); // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + // TODO 芋艿:后续处理 +// List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + List orderItems = null; if (CollUtil.isEmpty(orderItems)) { return couponMeetRespDTO.setMeet(false).setMeetTip("所结算商品没有符合条件的商品"); } @@ -134,413 +93,4 @@ public class PriceServiceImpl implements PriceService { }); } - private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); - - // 校验商品 SKU - skus.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - if (count == null) { - throw exception(SKU_NOT_EXISTS); - } - // 不校验库存不足,避免购物车场景,商品无货的情况 - }); - return skus; - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算商品级别的价格,例如说: - * 1. 会员折扣 - * 2. 限时折扣 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO} - * - * 其中,会员折扣、限时折扣取最低价 - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Supplier memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId); - Map discountProducts = discountService.getMatchDiscountProducts( - convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); - - // 处理每个 SKU 的优惠 - priceCalculate.getOrder().getItems().forEach(orderItem -> { - // 获取该 SKU 的优惠信息 - Double memberDiscountPercent = memberDiscountPercentSupplier.get(); - DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId()); - if (memberDiscountPercent == null && discountProduct == null) { - return; - } - // 计算价格,判断选择哪个折扣 - Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null; - Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null; - if (memberPrice == null) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else if (promotionPrice == null) { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } else if (memberPrice < promotionPrice) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } - }); - } - - private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct, - PriceCalculateRespDTO.OrderItem orderItem) { - Integer price = orderItem.getPayPrice(); - if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 - price -= discountProduct.getDiscountPrice() * orderItem.getCount(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 - price = price * discountProduct.getDiscountPercent() / 100; - } else { - throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); - } - return price; - } - - private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Integer memberPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), - PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, - true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); - } - - private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - DiscountProductDetailBO discountProduct, Integer promotionPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), - PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, - true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); - } - - // TODO 芋艿:提前实现 - private Supplier getMemberDiscountPercentSupplier(Long userId) { - return Suppliers.memoize(() -> { - if (userId == 1) { - return 90d; - } - if (userId == 2) { - return 80d; - } - return null; // 无优惠 - }); - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算订单级别的价格,例如说: - * 1. 满减送 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO} - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - @SuppressWarnings("unused") - private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); - Map> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); - - // 处理满减送活动 - if (CollUtil.isNotEmpty(rewardActivities)) { - rewardActivities.forEach((rewardActivity, activitySpuIds) -> { - List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); - calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); - }); - } - } - - private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, - RewardActivityDO rewardActivity) { - // 获得最大匹配的满减送活动的规则 - RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); - if (rule == null) { - // 获取不到的情况下,记录不满足的优惠明细 - addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), - getRewardActivityNotMeetTip(rewardActivity)); - return; - } - - // 分摊金额 - List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, - true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); - } - } - - /** - * 获得最大匹配的满减送活动的规则 - * - * @param rewardActivity 满减送活动 - * @param orderItems 商品项 - * @return 匹配的活动规则 - */ - private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, - List orderItems) { - Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); - // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 - Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert count != null && price != null; - for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { - RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); - if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) - && price >= rule.getLimit()) { - return rule; - } - if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) - && count >= rule.getLimit()) { - return rule; - } - } - return null; - } - - /** - * 获得满减送活动部匹配时的提示 - * - * @param rewardActivity 满减送活动 - * @return 提示 - */ - private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { - return "TODO"; // TODO 芋艿:后面再想想 - } - - // ========== 计算优惠劵级别的价格 ========== - - private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { - // 校验优惠劵 - if (couponId == null) { - return; - } - CouponDO coupon = couponService.validCoupon(couponId, userId); - - // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); - if (CollUtil.isEmpty(orderItems)) { - throw exception(COUPON_NO_MATCH_SPU); - } - - // 计算是否满足优惠劵的使用金额 - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert originPrice != null; - if (originPrice < coupon.getUsePrice()) { - throw exception(COUPON_NO_MATCH_MIN_PRICE); - } - - // 计算可以优惠的金额 - priceCalculate.getOrder().setCouponId(couponId); - Integer couponPrice = getCouponPrice(coupon, originPrice); - // 分摊金额 - List couponPartPrices = dividePrice(orderItems, couponPrice); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(), - PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, - true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); - } - } - - private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, - CouponDO coupon) { - if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { - return priceCalculate.getOrder().getItems(); - } - return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); - } - - private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { - if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 - return coupon.getDiscountPrice(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 - int couponPrice = originPrice * coupon.getDiscountPercent() / 100; - return coupon.getDiscountLimitPrice() == null ? couponPrice - : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 - } - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); - } - - // ========== 其它相对通用的方法 ========== - - /** - * 添加单个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItem 单个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param newPayPrice 新的单实付金额(总) - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Long id, String name, Integer type, Integer level, - Integer newPayPrice, Boolean meet, String meetTip) { - // 创建营销明细 Item - // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice - PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) - .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 添加多个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, - List discountPrices, Boolean meet, String meetTip) { - // 创建营销明细 Item - List promotionItems = new ArrayList<>(discountPrices.size()); - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); - } - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) - .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) - .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, String meetTip) { - // 创建营销明细 Item - List promotionItems = CollectionUtils.convertList(orderItems, - orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); - // 创建营销明细 - Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setTotalPrice(originalPrice).setDiscountPrice(0) - .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 - * - * @param orderItem 订单商品 SKU - * @param newPayPrice 新的 payPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, - PriceCalculateRespDTO priceCalculate) { - // diffPayPrice 等于额外增加的商品级的优惠 - int diffPayPrice = orderItem.getPayPrice() - newPayPrice; - // 设置 OrderItem 价格相关字段 - orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); - orderItem.setPayPrice(newPayPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setPayPrice(order.getPayPrice() - diffPayPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 - * - * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 discountPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 - * - * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 couponPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - private List dividePrice(List orderItems, Integer price) { - List prices = new ArrayList<>(orderItems.size()); - Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert total != null; - int remainPrice = price; - // 遍历每一个,进行分摊 - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - int partPrice; - if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); - prices.add(partPrice); - } - return prices; - } - - private String formatPrice(Integer price) { - return String.format("%.2f", price / 100d); - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java index 40bcc2836..4dcdb0738 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.module.promotion.service.reward; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; import javax.validation.Valid; -import java.util.Map; -import java.util.Set; +import java.util.Collection; +import java.util.List; /** * 满减送活动 Service 接口 @@ -66,8 +67,8 @@ public interface RewardActivityService { * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 * * @param spuIds SPU 编号数组 - * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 + * @return 满减送活动列表 */ - Map> getMatchRewardActivities(Set spuIds); + List getMatchRewardActivityList(Collection spuIds); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java index 51d0ce626..cdb73853c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.promotion.service.reward; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.util.PromotionUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -18,15 +17,10 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.Set; -import static cn.hutool.core.collection.CollUtil.intersectionDistinct; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; import static java.util.Arrays.asList; -import static java.util.Collections.singleton; /** * 满减送活动 Service 实现类 @@ -105,6 +99,7 @@ public class RewardActivityServiceImpl implements RewardActivityService { return activity; } + // TODO @芋艿:逻辑有问题,需要优化;要分成全场、和指定来校验; /** * 校验商品参加的活动是否冲突 * @@ -151,19 +146,21 @@ public class RewardActivityServiceImpl implements RewardActivityService { } @Override - public Map> getMatchRewardActivities(Set spuIds) { - // 如果有全局活动,则直接选择它 - List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( - PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); - if (CollUtil.isNotEmpty(allActivities)) { - return MapUtil.builder(allActivities.get(0), spuIds).build(); - } - - // 查询某个活动参加的活动 - List productActivityList = getRewardActivityListBySpuIds(spuIds, - singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(productActivityList, activity -> activity, - rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 + public List getMatchRewardActivityList(Collection spuIds) { + // TODO 芋艿:待实现;先指定,然后再全局的; +// // 如果有全局活动,则直接选择它 +// List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( +// PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); +// if (CollUtil.isNotEmpty(allActivities)) { +// return MapUtil.builder(allActivities.get(0), spuIds).build(); +// } +// +// // 查询某个活动参加的活动 +// List productActivityList = getRewardActivityListBySpuIds(spuIds, +// singleton(PromotionActivityStatusEnum.RUN.getStatus())); +// return convertMap(productActivityList, activity -> activity, +// rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 + return null; } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 9e40ff67b..929727077 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -96,8 +96,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getDiscountPrice(), 20); - assertTrue(promotion.getMeet()); - assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); + assertTrue(promotion.getMatch()); + assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元"); PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); assertEquals(promotion.getItems().size(), 1); assertEquals(promotionItem.getSkuId(), 10L); @@ -122,7 +122,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) .setActivityName("活动 2000 号").setSkuId(20L) .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); - when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( + when(discountService.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn( MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); // 10L: 100 * 2 - 40 * 2 = 120 @@ -167,8 +167,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion01.getTotalPrice(), 200); assertEquals(promotion01.getDiscountPrice(), 80); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "限时折扣:省 0.80 元"); PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); assertEquals(promotion01.getItems().size(), 1); assertEquals(promotionItem01.getSkuId(), 10L); @@ -181,8 +181,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion02.getTotalPrice(), 150); assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); + assertTrue(promotion02.getMatch()); + assertEquals(promotion02.getDescription(), "限时折扣:省 0.60 元"); PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); assertEquals(promotion02.getItems().size(), 1); assertEquals(promotionItem02.getSkuId(), 20L); @@ -267,8 +267,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "满减送:省 0.70 元"); assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); @@ -286,8 +286,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); + assertTrue(promotion02.getMatch()); + assertEquals(promotion02.getDescription(), "满减送:省 0.60 元"); PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); assertEquals(promotion02.getItems().size(), 1); assertEquals(promotionItem02.getSkuId(), 30L); @@ -355,8 +355,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 0); - assertFalse(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 + assertFalse(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "TODO"); // TODO 芋艿:后面再想想 assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); @@ -437,8 +437,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); assertEquals(promotion01.getItems().size(), 2); PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); assertEquals(promotionItem011.getSkuId(), 10L); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index cb0ac8474..b887ae8c8 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -50,4 +50,8 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); + + // ========== Price 相关 1011004000 ============ + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index 5b3a84284..72b9e08d0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -4,7 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO; import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 3471b2233..fed5ee13c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -1,31 +1,25 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; -import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; -import javax.validation.*; -import javax.servlet.http.*; -import java.util.*; -import java.io.IOException; +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; - -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; - @Tag(name = "管理后台 - 快递运费模板") @RestController @@ -84,4 +78,5 @@ public class DeliveryExpressTemplateController { PageResult pageResult = deliveryExpressTemplateService.getDeliveryExpressTemplatePage(pageVO); return success(DeliveryExpressTemplateConvert.INSTANCE.convertPage(pageResult)); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java similarity index 98% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java index 538027c81..c4f629cf6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressCreateReqVO.java similarity index 84% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressCreateReqVO.java index 2ef4e8070..a9ba8a7cb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressCreateReqVO.java @@ -1,9 +1,7 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import lombok.*; -import java.util.*; import io.swagger.v3.oas.annotations.media.Schema; -import javax.validation.constraints.*; @Schema(description = "管理后台 - 快递公司创建 Request VO") @Data diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExcelVO.java similarity index 98% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExcelVO.java index 4df6c0d7d..c84a3a189 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExcelVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExcelVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExportReqVO.java similarity index 98% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExportReqVO.java index 6e44cc45f..c601721e8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressExportReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExportReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressPageReqVO.java similarity index 98% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressPageReqVO.java index 50826ea36..4a000f319 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressPageReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import lombok.*; import java.util.*; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressRespVO.java similarity index 97% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressRespVO.java index 55d5578ad..34fd06a53 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressRespVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressUpdateReqVO.java similarity index 77% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressUpdateReqVO.java index 633736e34..f8bf33f5c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressUpdateReqVO.java @@ -1,9 +1,11 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import javax.validation.constraints.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; @Schema(description = "管理后台 - 快递公司更新 Request VO") @Data diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateBaseVO.java similarity index 97% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateBaseVO.java index cedb70888..7e84f962e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java similarity index 77% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java index e575f1a91..ee51c5659 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java @@ -1,10 +1,13 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; -import lombok.*; -import java.util.*; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; import javax.validation.Valid; +import java.util.Collections; +import java.util.List; @Schema(description = "管理后台 - 快递运费模板创建 Request VO") @Data @@ -12,6 +15,8 @@ import javax.validation.Valid; @ToString(callSuper = true) public class DeliveryExpressTemplateCreateReqVO extends DeliveryExpressTemplateBaseVO { + // TODO @jason:不用给默认值哈 + @Schema(description = "区域运费列表") @Valid private List templateCharge = Collections.emptyList(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplatePageReqVO.java similarity index 90% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplatePageReqVO.java index c5fa5a6ca..ea1e4ab3e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplatePageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplatePageReqVO.java @@ -1,10 +1,12 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; -import lombok.*; -import java.util.*; -import io.swagger.v3.oas.annotations.media.Schema; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; + import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java similarity index 97% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java index 5e968f629..a03a8e61b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java similarity index 82% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java index 4cfc530ab..2f2c8280d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java @@ -1,9 +1,10 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; +// TODO @jason:simplae 是不是不用继承 DeliveryExpressTemplateBaseVO,直接 id name 属性就够了。 @Schema(description = "管理后台 - 快递运费模板 精简 Response VO") @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java similarity index 77% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java index 80ebee8b6..0f5c65221 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/DeliveryExpressTemplateUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java @@ -1,10 +1,14 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + import javax.validation.Valid; -import javax.validation.constraints.*; +import javax.validation.constraints.NotNull; +import java.util.Collections; +import java.util.List; @Schema(description = "管理后台 - 快递运费模板更新 Request VO") @Data @@ -16,6 +20,8 @@ public class DeliveryExpressTemplateUpdateReqVO extends DeliveryExpressTemplateB @NotNull(message = "编号不能为空") private Long id; + // TODO @jason:pojo 不给默认值哈 + @Schema(description = "区域运费列表") @Valid private List templateCharge = Collections.emptyList(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeBaseVO.java similarity index 98% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeBaseVO.java index 8bd2617b7..7fb1111d5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java similarity index 61% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java index 995ea4a18..e9fcb08f9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateChargeUpdateVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java @@ -1,18 +1,22 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; - +// TODO @jason:这个 vo 可以内嵌到 DeliveryExpressTemplateUpdateReqVO,避免 vo 过多,不好分辨 +@Schema(description = "管理后台 - 快递公司创建 Request VO") @Data public class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO { @Schema(description = "编号", example = "6592") private Long id; + // TODO @jason:这几个字段,应该不通过前端传递,而是后端查询后去赋值的 + @Schema(description = "配送模板编号", example = "1") private Long templateId; @Schema(description = "配送计费方式", example = "1") private Integer chargeMode; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeBaseVO.java similarity index 97% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeBaseVO.java index 7523b0f53..9334abf07 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -24,4 +24,5 @@ public class ExpressTemplateFreeBaseVO { @Schema(description = "包邮件数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") @NotNull(message = "包邮件数不能为空") private Integer freeCount; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java similarity index 72% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java index e0c7e47b0..e2c894456 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/ExpressTemplateFreeUpdateVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java @@ -1,8 +1,10 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo; +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +// TODO @jason:这个 vo 可以内嵌到 DeliveryExpressTemplateUpdateReqVO,避免 vo 过多,不好分辨 +// TODO @jason:swagger 缺失 /** * 快递运费模板包邮 更新 VO */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java index e896962a2..474881790 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java @@ -4,10 +4,10 @@ import java.util.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExcelVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExcelVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index 7e2a51cc1..20e94cb25 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -1,17 +1,14 @@ package cn.iocoder.yudao.module.trade.convert.delivery; -import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java index 24b0b50e6..f74318e56 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java index 734298042..c93346894 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateMapper.java @@ -4,7 +4,7 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressTemplatePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import org.apache.ibatis.annotations.Mapper; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java index ce4814dbd..b6fffa87a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java @@ -4,10 +4,10 @@ import java.util.*; import javax.validation.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java index dcbf08969..a396a389a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressExportReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressPageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.DeliveryExpressUpdateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO; import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressMapper; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 71721fec2..20a0a1b62 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -1,11 +1,16 @@ package cn.iocoder.yudao.module.trade.service.delivery; -import java.util.*; -import javax.validation.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + /** * 快递运费模板 Service 接口 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 2bda89a91..d7bf96978 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; @@ -18,8 +17,10 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NAME_DUPLICATE; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NOT_EXISTS; /** * 快递运费模板 Service 实现类 @@ -42,6 +43,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public Long createDeliveryExpressTemplate(DeliveryExpressTemplateCreateReqVO createReqVO) { // 校验模板名是否唯一 validateTemplateNameUnique(createReqVO.getName(), null); + // 插入 DeliveryExpressTemplateDO deliveryExpressTemplate = INSTANCE.convert(createReqVO); expressTemplateMapper.insert(deliveryExpressTemplate); @@ -67,6 +69,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla validateDeliveryExpressTemplateExists(updateReqVO.getId()); // 校验模板名是否唯一 validateTemplateNameUnique(updateReqVO.getName(), updateReqVO.getId()); + // 更新运费从表 updateExpressTemplateCharge(updateReqVO); // 更新包邮从表 @@ -77,12 +80,11 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } private void updateExpressTemplateFree(DeliveryExpressTemplateUpdateReqVO updateReqVO) { + // 1.1 获得新增/修改的区域列表 List oldFreeList = expressTemplateFreeMapper.selectListByTemplateId(updateReqVO.getId()); List newFreeList = updateReqVO.getTemplateFree(); - // 新增包邮区域列表 - List addFreeList = new ArrayList<>(newFreeList.size()); - // 更新包邮区域列表 - List updateFreeList = new ArrayList<>(newFreeList.size()); + List addFreeList = new ArrayList<>(newFreeList.size()); // 新增包邮区域列表 + List updateFreeList = new ArrayList<>(newFreeList.size()); // 更新包邮区域列表 for (ExpressTemplateFreeUpdateVO item : newFreeList) { if (Objects.nonNull(item.getId())) { updateFreeList.add(INSTANCE.convertTemplateFree(item)); @@ -91,30 +93,29 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla addFreeList.add(INSTANCE.convertTemplateFree(item)); } } - // 新增 + // 1.2 新增 if (CollUtil.isNotEmpty(addFreeList)) { expressTemplateFreeMapper.insertBatch(addFreeList); } - // 修改 + // 1.3 修改 if (CollUtil.isNotEmpty(updateFreeList)) { expressTemplateFreeMapper.updateBatch(updateFreeList); } - // 得到删除ids - Set deleteFreeIds = CollectionUtils.convertSet(oldFreeList, DeliveryExpressTemplateFreeDO::getId); - deleteFreeIds.removeAll(CollectionUtils.convertSet(updateFreeList, DeliveryExpressTemplateFreeDO::getId)); - //删除 + + // 2. 删除 + Set deleteFreeIds = convertSet(oldFreeList, DeliveryExpressTemplateFreeDO::getId); + deleteFreeIds.removeAll(convertSet(updateFreeList, DeliveryExpressTemplateFreeDO::getId)); if (CollUtil.isNotEmpty(deleteFreeIds)) { expressTemplateFreeMapper.deleteBatchIds(deleteFreeIds); } } private void updateExpressTemplateCharge(DeliveryExpressTemplateUpdateReqVO updateReqVO) { + // 1.1 获得新增/修改的区域列表 List oldChargeList = expressTemplateChargeMapper.selectListByTemplateId(updateReqVO.getId()); List newChargeList = updateReqVO.getTemplateCharge(); - // 新增运费区域列表 - List addList = new ArrayList<>(newChargeList.size()); - // 更新运费区域列表 - List updateList = new ArrayList<>(newChargeList.size()); + List addList = new ArrayList<>(newChargeList.size()); // 新增运费区域列表 + List updateList = new ArrayList<>(newChargeList.size()); // 更新运费区域列表 for (ExpressTemplateChargeUpdateVO item : newChargeList) { if (item.getId() != null) { // 计费模式以主表为准 @@ -126,18 +127,18 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla addList.add(INSTANCE.convertTemplateCharge(item)); } } - // 新增 + // 1.2 新增 if (CollUtil.isNotEmpty(addList)) { expressTemplateChargeMapper.insertBatch(addList); } - // 修改 + // 1.3 修改 if (CollUtil.isNotEmpty(updateList)) { expressTemplateChargeMapper.updateBatch(updateList); } - // 得到删除的ids - Set deleteChargeIds = CollectionUtils.convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId); - deleteChargeIds.removeAll(CollectionUtils.convertSet(updateList, DeliveryExpressTemplateChargeDO::getId)); - // 删除 + + // 2. 删除 + Set deleteChargeIds = convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId); + deleteChargeIds.removeAll(convertSet(updateList, DeliveryExpressTemplateChargeDO::getId)); if (CollUtil.isNotEmpty(deleteChargeIds)) { expressTemplateChargeMapper.deleteBatchIds(deleteChargeIds); } @@ -148,6 +149,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public void deleteDeliveryExpressTemplate(Long id) { // 校验存在 validateDeliveryExpressTemplateExists(id); + // 删除主表 expressTemplateMapper.deleteById(id); // 删除运费从表 @@ -199,4 +201,5 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla public PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO) { return expressTemplateMapper.selectPage(pageReqVO); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java new file mode 100644 index 000000000..2dd0c41ca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.service.price; + +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +/** + * 价格计算 Service 接口 + * + * @author 芋道源码 + */ +public interface TradePriceService { + + /** + * 价格计算 + * + * @param calculateReqDTO 计算信息 + * @return 计算结果 + */ + TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java new file mode 100644 index 000000000..f0ebce5ba --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java @@ -0,0 +1,73 @@ +package cn.iocoder.yudao.module.trade.service.price; + +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; + +/** + * 价格计算 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class TradePriceServiceImpl implements TradePriceService { + + @Resource + private ProductSkuApi productSkuApi; + @Resource + private List priceCalculators; + + @Override + public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) { + // 1. 获得商品 SKU 数组 + List skuList = checkSkus(calculateReqBO); + + // 2.1 计算价格 + TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper + .buildCalculateResp(calculateReqBO, skuList); + priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); + // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 + if (calculateRespBO.getPrice().getPayPrice() <= 0) { + log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", + calculateReqBO, calculateRespBO); + throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); + } + return calculateRespBO; + } + + private List checkSkus(TradePriceCalculateReqBO reqBO) { + // 获得商品 SKU 数组 + Map skuIdCountMap = convertMap(reqBO.getItems(), + TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount); + List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); + + // 校验商品 SKU + skus.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + if (count == null) { + throw exception(SKU_NOT_EXISTS); + } + if (count > sku.getStock()) { + throw exception(SKU_STOCK_NOT_ENOUGH); + } + }); + return skus; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java new file mode 100644 index 000000000..2a014c0e0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.trade.service.price.bo; + +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 价格计算 Request BO + * + * @author yudao源码 + */ +@Data +public class TradePriceCalculateReqBO { + + /** + * 订单类型 + * + * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer orderType; + + /** + * 用户编号 + * + * 对应 MemberUserDO 的 id 编号 + */ + private Long userId; + + /** + * 优惠劵编号 + * + * 对应 CouponDO 的 id 编号 + */ + private Long couponId; + + /** + * 收货地址编号 + * + * 对应 MemberAddressDO 的 id 编号 + */ + private Long addressId; + + /** + * 商品 SKU 数组 + */ + @NotNull(message = "商品数组不能为空") + private List items; + + /** + * 商品 SKU + */ + @Data + @Valid + public static class Item { + + /** + * SKU 编号 + */ + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + /** + * SKU 数量 + */ + @NotNull(message = "商品 SKU 数量不能为空") + @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") + private Integer count; + + /** + * 购物车项的编号 + */ + private Long cartId; + + /** + * 是否选中 + */ + @NotNull(message = "是否选中不能为空") + private Boolean selected; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java new file mode 100644 index 000000000..b30ba8855 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -0,0 +1,249 @@ +package cn.iocoder.yudao.module.trade.service.price.bo; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 价格计算 Response BO + * + * 整体设计,参考 taobao 的技术文档: + * 1. 订单管理 + * 2. 常用订单金额说明 + * + * @author 芋道源码 + */ +@Data +public class TradePriceCalculateRespBO { + + /** + * 订单类型 + * + * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer orderType; + + /** + * 订单价格 + */ + private Price price; + + /** + * 订单项数组 + */ + private List items; + + /** + * 营销活动数组 + * + * 只对应 {@link Price#items} 商品匹配的活动 + */ + private List promotions; + + /** + * 优惠劵编号 + */ + private Long couponId; + + /** + * 订单价格 + */ + @Data + public static class Price { + + /** + * 商品原价(总),单位:分 + * + * 基于 {@link OrderItem#getPrice()} * {@link OrderItem#getCount()} 求和 + * + * 对应 taobao 的 trade.total_fee 字段 + */ + private Integer totalPrice; + /** + * 订单优惠(总),单位:分 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 运费金额,单位:分 + */ + private Integer deliveryPrice; + /** + * 优惠劵减免金额(总),单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 最终购买金额(总),单位:分 + * + * = {@link #totalPrice} + * - {@link #couponPrice} + * - {@link #pointPrice} + * - {@link #discountPrice} + * + {@link #deliveryPrice} + */ + private Integer payPrice; + + } + + /** + * 订单商品 SKU + */ + @Data + public static class OrderItem { + + /** + * SPU 编号 + */ + private Long spuId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 购买数量 + */ + private Integer count; + /** + * 购物车项的编号 + */ + private Long cartId; + /** + * 是否选中 + */ + private Boolean selected; + + /** + * 商品原价(单),单位:分 + * + * 对应 ProductSkuDO 的 price 字段 + * 对应 taobao 的 order.price 字段 + */ + private Integer price; + /** + * 优惠金额(总),单位:分 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 运费金额(总),单位:分 + */ + private Integer deliveryPrice; + /** + * 优惠劵减免金额,单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 应付金额(总),单位:分 + * + * = {@link #price} * {@link #count} + * - {@link #couponPrice} + * - {@link #pointPrice} + * - {@link #discountPrice} + * + {@link #deliveryPrice} + */ + private Integer payPrice; + + // TODO 芋艿:这里补充下基本信息,简单一点。 + + } + + /** + * 营销明细 + */ + @Data + public static class Promotion { + + /** + * 营销编号 + * + * 例如说:营销活动的编号、优惠劵的编号 + */ + private Long id; + /** + * 营销名字 + */ + private String name; + /** + * 营销类型 + * + * 枚举 {@link PromotionTypeEnum} + */ + private Integer type; + /** + * 营销级别 + * + * 枚举 {@link PromotionLevelEnum} + */ + private Integer level; + /** + * 计算时的原价(总),单位:分 + */ + private Integer totalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + /** + * 匹配的商品 SKU 数组 + */ + private List items; + + // ========== 匹配情况 ========== + + /** + * 是否满足优惠条件 + */ + private Boolean match; + /** + * 满足条件的提示 + * + * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元” + */ + private String description; + + } + + /** + * 营销匹配的商品 SKU + */ + @Data + public static class PromotionItem { + + /** + * 商品 SKU 编号 + */ + private Long skuId; + /** + * 计算时的原价(总),单位:分 + */ + private Integer totalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java new file mode 100644 index 000000000..52ebf84a0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.function.Predicate; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU; + +/** + * 优惠劵的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_COUPON) +public class TradeCouponPriceCalculator implements TradePriceCalculator { + + @Resource + private CouponApi couponApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1.1 校验优惠劵 + if (param.getCouponId() == null) { + return; + } + CouponRespDTO coupon = couponApi.validateCoupon(new CouponValidReqDTO() + .setId(param.getCouponId()).setUserId(param.getUserId())); + Assert.notNull(coupon, "校验通过的优惠劵({}),不能为空", param.getCouponId()); + + // 2.1 获得匹配的商品 SKU 数组 + List orderItems = filterMatchCouponOrderItems(result, coupon); + if (CollUtil.isEmpty(orderItems)) { + throw exception(COUPON_NO_MATCH_SPU); + } + // 2.2 计算是否满足优惠劵的使用金额 + Integer totalPayPrice = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems); + if (totalPayPrice < coupon.getUsePrice()) { + throw exception(COUPON_NO_MATCH_MIN_PRICE); + } + + // 3.1 计算可以优惠的金额 + Integer couponPrice = getCouponPrice(coupon, totalPayPrice); + Assert.isTrue(couponPrice < totalPayPrice, + "优惠劵({}) 的优惠金额({}),不能大于订单总金额({})", coupon.getId(), couponPrice, totalPayPrice); + // 3.2 计算分摊的优惠金额 + List divideCouponPrices = TradePriceCalculatorHelper.dividePrice(orderItems, couponPrice); + + // 4.1 记录使用的优惠劵 + result.setCouponId(param.getCouponId()); + // 4.2 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItems, + param.getCouponId(), coupon.getName(), PromotionTypeEnum.COUPON.getType(), + StrUtil.format("优惠劵:省 {} 元", TradePriceCalculatorHelper.formatPrice(couponPrice)), + divideCouponPrices); + // 4.3 更新 SKU 优惠金额 + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + orderItem.setCouponPrice(divideCouponPrices.get(i)); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + } + TradePriceCalculatorHelper.recountAllPrice(result); + } + + private Integer getCouponPrice(CouponRespDTO coupon, Integer totalPayPrice) { + if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 + return coupon.getDiscountPrice(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 + int couponPrice = totalPayPrice * coupon.getDiscountPercent() / 100; + return coupon.getDiscountLimitPrice() == null ? couponPrice + : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 + } + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); + } + + /** + * 获得优惠劵可使用的订单项(商品)列表 + * + * @param result 计算结果 + * @param coupon 优惠劵 + * @return 订单项(商品)列表 + */ + private List filterMatchCouponOrderItems(TradePriceCalculateRespBO result, + CouponRespDTO coupon) { + Predicate matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; + if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { + matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()); + } + return filterList(result.getItems(), matchPredicate); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java new file mode 100644 index 000000000..7bcd8ffb7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi; +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice; + +/** + * 限时折扣的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY) +public class TradeDiscountActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private DiscountActivityApi discountActivityApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 获得 SKU 对应的限时折扣活动 + List discountProducts = discountActivityApi.getMatchDiscountProductList( + convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSkuId)); + if (CollUtil.isEmpty(discountProducts)) { + return; + } + Map discountProductMap = convertMap(discountProducts, DiscountProductRespDTO::getSkuId); + + // 处理每个 SKU 的限时折扣 + result.getItems().forEach(orderItem -> { + // 1. 获取该 SKU 的优惠信息 + DiscountProductRespDTO discountProduct = discountProductMap.get(orderItem.getSkuId()); + if (discountProduct == null) { + return; + } + // 2. 计算优惠金额 + Integer newPayPrice = calculatePayPrice(discountProduct, orderItem); + Integer newDiscountPrice = orderItem.getPayPrice() - newPayPrice; + + // 3.1 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItem, + discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), + StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)), + newDiscountPrice); + // 3.2 更新 SKU 优惠金额 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + newDiscountPrice); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + }); + TradePriceCalculatorHelper.recountAllPrice(result); + } + + private Integer calculatePayPrice(DiscountProductRespDTO discountProduct, + TradePriceCalculateRespBO.OrderItem orderItem) { + Integer price = orderItem.getPayPrice(); + if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 + price -= discountProduct.getDiscountPrice() * orderItem.getCount(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 + price = price * discountProduct.getDiscountPercent() / 100; + } else { + throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); + } + return price; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java new file mode 100644 index 000000000..1c9b4f988 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +/** + * 价格计算的计算器接口 + * + * @author 芋道源码 + */ +public interface TradePriceCalculator { + + int ORDER_DISCOUNT_ACTIVITY = 10; + int ORDER_REWARD_ACTIVITY = 20; + int ORDER_COUPON = 30; + + void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java new file mode 100644 index 000000000..9ed94b692 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -0,0 +1,221 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static java.util.Collections.singletonList; + +/** + * {@link TradePriceCalculator} 的工具类 + * + * 主要实现对 {@link TradePriceCalculateRespBO} 计算结果的操作 + * + * @author 芋道源码 + */ +public class TradePriceCalculatorHelper { + + public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, + List skuList) { + // 创建 PriceCalculateRespDTO 对象 + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); + result.setOrderType(param.getOrderType()); + // 创建它的 OrderItem 属性 + Map skuItemMap = convertMap(param.getItems(), + TradePriceCalculateReqBO.Item::getSkuId); + result.setItems(new ArrayList<>(skuItemMap.size())); + skuList.forEach(sku -> { + TradePriceCalculateReqBO.Item skuItem = skuItemMap.get(sku.getId()); + TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem() + // SKU 字段 + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()) + .setCount(skuItem.getCount()).setCartId(skuItem.getCartId()).setSelected(skuItem.getSelected()) + // 价格字段 + .setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * skuItem.getCount()) + .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); + result.getItems().add(orderItem); + }); + // 创建它的 Price 属性 + result.setPrice(new TradePriceCalculateRespBO.Price()); + recountAllPrice(result); + return result; + } + + /** + * 基于订单项,重新计算 price 总价 + * + * @param result 计算结果 + */ + public static void recountAllPrice(TradePriceCalculateRespBO result) { + // 先重置 + TradePriceCalculateRespBO.Price price = result.getPrice(); + price.setTotalPrice(0).setDiscountPrice(0).setDeliveryPrice(0) + .setCouponPrice(0).setPointPrice(0).setPayPrice(0); + // 再合计 item + result.getItems().forEach(item -> { + if (!item.getSelected()) { + return; + } + price.setTotalPrice(price.getTotalPrice() + item.getPrice() * item.getCount()); + price.setDiscountPrice(price.getDiscountPrice() + item.getDiscountPrice()); + price.setDeliveryPrice(price.getDeliveryPrice() + item.getDeliveryPrice()); + price.setCouponPrice(price.getCouponPrice() + item.getCouponPrice()); + price.setPointPrice(price.getPointPrice() + item.getPointPrice()); + price.setPayPrice(price.getPayPrice() + item.getPayPrice()); + }); + } + + /** + * 重新计算单个订单项的支付金额 + * + * @param orderItem 订单项 + */ + public static void recountPayPrice(TradePriceCalculateRespBO.OrderItem orderItem) { + orderItem.setPayPrice(orderItem.getPrice()* orderItem.getCount() + - orderItem.getDiscountPrice() + + orderItem.getDeliveryPrice() + - orderItem.getCouponPrice() + - orderItem.getPointPrice()); + } + + /** + * 计算已选中的订单项,总支付金额 + * + * @param orderItems 订单项数组 + * @return 总支付金额 + */ + public static Integer calculateTotalPayPrice(List orderItems) { + return getSumValue(orderItems, + orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 + Integer::sum); + } + + /** + * 计算已选中的订单项,总商品数 + * + * @param orderItems 订单项数组 + * @return 总商品数 + */ + public static Integer calculateTotalCount(List orderItems) { + return getSumValue(orderItems, + orderItem -> orderItem.getSelected() ? orderItem.getCount() : 0, // 未选中的情况下,不计算数量 + Integer::sum); + } + + /** + * 按照支付金额,返回每个订单项的分摊金额数组 + * + * @param orderItems 订单项数组 + * @param price 金额 + * @return 分摊金额数组,和传入的 orderItems 一一对应 + */ + public static List dividePrice(List orderItems, Integer price) { + Integer total = calculateTotalPayPrice(orderItems); + assert total != null; + // 遍历每一个,进行分摊 + List prices = new ArrayList<>(orderItems.size()); + int remainPrice = price; + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + // 1. 如果是未选中,则分摊为 0 + if (!orderItem.getSelected()) { + prices.add(0); + continue; + } + // 2. 如果选中,则按照百分比,进行分摊 + int partPrice; + if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 + partPrice = (int) (price * (1.0D * orderItem.getPayPrice() / total)); + remainPrice -= partPrice; + } else { + partPrice = remainPrice; + } + Assert.isTrue(partPrice >= 0, "分摊金额必须大于等于 0"); + prices.add(partPrice); + } + return prices; + } + + /** + * 添加【匹配】单个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItem 单个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + * @param discountPrice 单个订单商品 SKU 的优惠价格(总) + */ + public static void addPromotion(TradePriceCalculateRespBO result, TradePriceCalculateRespBO.OrderItem orderItem, + Long id, String name, Integer type, String description, Integer discountPrice) { + addPromotion(result, singletonList(orderItem), id, name, type, description, singletonList(discountPrice)); + } + + /** + * 添加【匹配】多个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 + */ + public static void addPromotion(TradePriceCalculateRespBO result, List orderItems, + Long id, String name, Integer type, String description, List discountPrices) { + // 创建营销明细 Item + List promotionItems = new ArrayList<>(discountPrices.size()); + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + promotionItems.add(new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); + } + // 创建营销明细 + TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() + .setId(id).setName(name).setType(type) + .setTotalPrice(calculateTotalPayPrice(orderItems)) + .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) + .setItems(promotionItems).setMatch(true).setDescription(description); + result.getPromotions().add(promotion); + } + + /** + * 添加【不匹配】多个 OrderItem 的营销明细 + * + * @param result 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param description 满足条件的提示 + * @param type 营销类型 + */ + public static void addNotMatchPromotion(TradePriceCalculateRespBO result, List orderItems, + Long id, String name, Integer type, String description) { + // 创建营销明细 Item + List promotionItems = CollectionUtils.convertList(orderItems, + orderItem -> new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(0)); + // 创建营销明细 + TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() + .setId(id).setName(name).setType(type) + .setTotalPrice(calculateTotalPayPrice(orderItems)) + .setDiscountPrice(0) + .setItems(promotionItems).setMatch(false).setDescription(description); + result.getPromotions().add(promotion); + } + + public static String formatPrice(Integer price) { + return String.format("%.2f", price / 100d); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java new file mode 100644 index 000000000..b0947fcc3 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice; + +/** + * 满减送活动的 {@link TradePriceCalculator} 实现类 + * + * @author 芋道源码 + */ +@Component +@Order(TradePriceCalculator.ORDER_REWARD_ACTIVITY) +public class TradeRewardActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private RewardActivityApi rewardActivityApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 获得 SKU 对应的满减送活动 + List rewardActivities = rewardActivityApi.getMatchRewardActivityList( + convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSpuId)); + if (CollUtil.isEmpty(rewardActivities)) { + return; + } + + // 处理每个满减送活动 + rewardActivities.forEach(rewardActivity -> calculate(param, result, rewardActivity)); + } + + private void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result, + RewardActivityMatchRespDTO rewardActivity) { + // 1.1 获得满减送的订单项(商品)列表 + List orderItems = filterMatchCouponOrderItems(result, rewardActivity); + if (CollUtil.isEmpty(orderItems)) { + return; + } + // 1.2 获得最大匹配的满减送活动的规则 + RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); + if (rule == null) { + return; + } + + // 2.1 计算可以优惠的金额 + Integer newDiscountPrice = rule.getDiscountPrice(); + // 2.2 计算分摊的优惠金额 + List divideDiscountPrices = TradePriceCalculatorHelper.dividePrice(orderItems, newDiscountPrice); + + // 3.1 记录使用的优惠劵 + result.setCouponId(param.getCouponId()); + // 3.2 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItems, + rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(), + StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice())), + divideDiscountPrices); + // 3.3 更新 SKU 优惠金额 + for (int i = 0; i < orderItems.size(); i++) { + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + divideDiscountPrices.get(i)); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + } + TradePriceCalculatorHelper.recountAllPrice(result); + } + + /** + * 获得满减送的订单项(商品)列表 + * + * @param result 计算结果 + * @param rewardActivity 满减送活动 + * @return 订单项(商品)列表 + */ + private List filterMatchCouponOrderItems(TradePriceCalculateRespBO result, + RewardActivityMatchRespDTO rewardActivity) { + return filterList(result.getItems(), + orderItem -> CollUtil.contains(rewardActivity.getSpuIds(), orderItem.getSpuId())); + } + + /** + * 获得最大匹配的满减送活动的规则 + * + * @param rewardActivity 满减送活动 + * @param orderItems 商品项 + * @return 匹配的活动规则 + */ + private RewardActivityMatchRespDTO.Rule getMaxMatchRewardActivityRule(RewardActivityMatchRespDTO rewardActivity, + List orderItems) { + // 1. 计算数量和价格 + Integer count = TradePriceCalculatorHelper.calculateTotalCount(orderItems); + Integer price = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems); + assert count != null && price != null; + + // 2. 倒序找一个最大优惠的规则 + for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { + RewardActivityMatchRespDTO.Rule rule = rewardActivity.getRules().get(i); + if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) + && price >= rule.getLimit()) { + return rule; + } + if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) + && count >= rule.getLimit()) { + return rule; + } + } + return null; + } + + /** + * 获得满减送活动部匹配时的提示 + * + * @param rewardActivity 满减送活动 + * @return 提示 + */ + private String getRewardActivityNotMeetTip(RewardActivityMatchRespDTO rewardActivity) { + // TODO 芋艿:后面再想想;应该找第一个规则,算下还差多少即可。 + return "TODO"; + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java index bd65bddfd..78f1c7902 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreate import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; import cn.iocoder.yudao.module.member.convert.address.AddressConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.service.address.AddressService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; @@ -54,21 +54,21 @@ public class AppAddressController { @Operation(summary = "获得用户收件地址") @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getAddress(@RequestParam("id") Long id) { - AddressDO address = addressService.getAddress(getLoginUserId(), id); + MemberAddressDO address = addressService.getAddress(getLoginUserId(), id); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/get-default") @Operation(summary = "获得默认的用户收件地址") public CommonResult getDefaultUserAddress() { - AddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); + MemberAddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/list") @Operation(summary = "获得用户收件地址列表") public CommonResult> getAddressList() { - List list = addressService.getAddressList(getLoginUserId()); + List list = addressService.getAddressList(getLoginUserId()); return success(AddressConvert.INSTANCE.convertList(list)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java index 49a01805d..a93d79ec1 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -21,16 +21,16 @@ public interface AddressConvert { AddressConvert INSTANCE = Mappers.getMapper(AddressConvert.class); - AddressDO convert(AppAddressCreateReqVO bean); + MemberAddressDO convert(AppAddressCreateReqVO bean); - AddressDO convert(AppAddressUpdateReqVO bean); + MemberAddressDO convert(AppAddressUpdateReqVO bean); - AppAddressRespVO convert(AddressDO bean); + AppAddressRespVO convert(MemberAddressDO bean); - List convertList(List list); + List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); - AddressRespDTO convert02(AddressDO bean); + AddressRespDTO convert02(MemberAddressDO bean); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java similarity index 95% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java index 7d8a96250..560edbba9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/AddressDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java @@ -17,7 +17,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class AddressDO extends BaseDO { +public class MemberAddressDO extends BaseDO { /** * 编号 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java index 80f78d41f..13ca89ef9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java @@ -2,21 +2,21 @@ package cn.iocoder.yudao.module.member.dal.mysql.address; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper -public interface AddressMapper extends BaseMapperX { +public interface AddressMapper extends BaseMapperX { - default AddressDO selectByIdAndUserId(Long id, Long userId) { - return selectOne(AddressDO::getId, id, AddressDO::getUserId, userId); + default MemberAddressDO selectByIdAndUserId(Long id, Long userId) { + return selectOne(MemberAddressDO::getId, id, MemberAddressDO::getUserId, userId); } - default List selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) { - return selectList(new LambdaQueryWrapperX().eq(AddressDO::getUserId, userId) - .eqIfPresent(AddressDO::getDefaulted, defaulted)); + default List selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) { + return selectList(new LambdaQueryWrapperX().eq(MemberAddressDO::getUserId, userId) + .eqIfPresent(MemberAddressDO::getDefaulted, defaulted)); } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java index 456a3d8ac..099c49c42 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressService.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.member.service.address; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import javax.validation.Valid; import java.util.List; @@ -46,7 +46,7 @@ public interface AddressService { * @param id 编号 * @return 用户收件地址 */ - AddressDO getAddress(Long userId, Long id); + MemberAddressDO getAddress(Long userId, Long id); /** * 获得用户收件地址列表 @@ -54,7 +54,7 @@ public interface AddressService { * @param userId 用户编号 * @return 用户收件地址列表 */ - List getAddressList(Long userId); + List getAddressList(Long userId); /** * 获得用户默认的收件地址 @@ -62,6 +62,6 @@ public interface AddressService { * @param userId 用户编号 * @return 用户收件地址 */ - AddressDO getDefaultUserAddress(Long userId); + MemberAddressDO getDefaultUserAddress(Long userId); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java index bbcbbe592..488e7d32c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; import cn.iocoder.yudao.module.member.convert.address.AddressConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,12 +33,12 @@ public class AddressServiceImpl implements AddressService { public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) { // 如果添加的是默认收件地址,则将原默认地址修改为非默认 if (Boolean.TRUE.equals(createReqVO.getDefaulted())) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); - addresses.forEach(address -> addressMapper.updateById(new AddressDO().setId(address.getId()).setDefaulted(false))); + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + addresses.forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false))); } // 插入 - AddressDO address = AddressConvert.INSTANCE.convert(createReqVO); + MemberAddressDO address = AddressConvert.INSTANCE.convert(createReqVO); address.setUserId(userId); addressMapper.insert(address); // 返回 @@ -53,13 +53,13 @@ public class AddressServiceImpl implements AddressService { // 如果修改的是默认收件地址,则将原默认地址修改为非默认 if (Boolean.TRUE.equals(updateReqVO.getDefaulted())) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己 - .forEach(address -> addressMapper.updateById(new AddressDO().setId(address.getId()).setDefaulted(false))); + .forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false))); } // 更新 - AddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO); + MemberAddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO); addressMapper.updateById(updateObj); } @@ -72,25 +72,25 @@ public class AddressServiceImpl implements AddressService { } private void validAddressExists(Long userId, Long id) { - AddressDO addressDO = getAddress(userId, id); + MemberAddressDO addressDO = getAddress(userId, id); if (addressDO == null) { throw exception(ADDRESS_NOT_EXISTS); } } @Override - public AddressDO getAddress(Long userId, Long id) { + public MemberAddressDO getAddress(Long userId, Long id) { return addressMapper.selectByIdAndUserId(id, userId); } @Override - public List getAddressList(Long userId) { + public List getAddressList(Long userId) { return addressMapper.selectListByUserIdAndDefaulted(userId, null); } @Override - public AddressDO getDefaultUserAddress(Long userId) { - List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); + public MemberAddressDO getDefaultUserAddress(Long userId) { + List addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); return CollUtil.getFirst(addresses); } diff --git a/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java b/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java index 6ddf80a0e..77b40705e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java +++ b/yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.service.address; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; +import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; @@ -42,14 +42,14 @@ public class AddressServiceImplTest extends BaseDbUnitTest { // 断言 assertNotNull(addressId); // 校验记录的属性是否正确 - AddressDO address = addressMapper.selectById(addressId); + MemberAddressDO address = addressMapper.selectById(addressId); assertPojoEquals(reqVO, address); } @Test public void testUpdateAddress_success() { // mock 数据 - AddressDO dbAddress = randomPojo(AddressDO.class); + MemberAddressDO dbAddress = randomPojo(MemberAddressDO.class); addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据 // 准备参数 AppAddressUpdateReqVO reqVO = randomPojo(AppAddressUpdateReqVO.class, o -> { @@ -59,7 +59,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest { // 调用 addressService.updateAddress(dbAddress.getUserId(), reqVO); // 校验是否更新正确 - AddressDO address = addressMapper.selectById(reqVO.getId()); // 获取最新的 + MemberAddressDO address = addressMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, address); } @@ -75,7 +75,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest { @Test public void testDeleteAddress_success() { // mock 数据 - AddressDO dbAddress = randomPojo(AddressDO.class); + MemberAddressDO dbAddress = randomPojo(MemberAddressDO.class); addressMapper.insert(dbAddress);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbAddress.getId(); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java index 05d193717..18609edb1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java @@ -23,7 +23,8 @@ public interface AreaConvert { @Mapping(source = "type", target = "leaf") AreaNodeSimpleRespVO convert(Area area); - default Boolean convertAreaType(Integer type){ - return Objects.equals(AreaTypeEnum.DISTRICT.getType(),type); + default Boolean convertAreaType(Integer type) { + return Objects.equals(AreaTypeEnum.DISTRICT.getType(), type); } + } From 35daee84e746d1aa625ae630f6bf45314ce1fa02 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 30 May 2023 10:26:42 +0800 Subject: [PATCH 065/232] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E4=BB=A3=E7=A0=81=E5=90=8E=E9=A1=B9=E7=9B=AE=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E9=97=AE=E9=A2=98=E5=B7=B2=E6=A0=87=E6=B3=A8?= =?UTF-8?q?=20TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/price/dto/PriceCalculateRespDTO.java | 3 +- .../promotion/api/price/PriceApiImpl.java | 4 +- .../service/price/PriceServiceTest.java | 54 ++++++++++--------- .../reward/RewardActivityServiceImplTest.java | 40 +++++++------- .../price/bo/TradePriceCalculateRespBO.java | 3 +- .../aftersale/TradeAfterSaleServiceTest.java | 3 +- 6 files changed, 57 insertions(+), 50 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java index 9a98029b7..9942c818e 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.api.price.dto; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import lombok.Data; @@ -197,7 +196,7 @@ public class PriceCalculateRespDTO { /** * 营销级别 * - * 枚举 {@link PromotionLevelEnum} + * 枚举 @link PromotionLevelEnum} TODO PromotionLevelEnum 没有这个枚举类 */ private Integer level; /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java index 3c415f1c4..31221147e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java @@ -20,7 +20,9 @@ public class PriceApiImpl implements PriceApi { @Override public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - return priceService.calculatePrice(calculateReqDTO); + //return priceService.calculatePrice(calculateReqDTO); TODO 没有 calculatePrice 这个方法 + + return null; } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 929727077..1aaf33e1e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -14,7 +14,6 @@ import cn.iocoder.yudao.module.promotion.enums.common.*; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -67,7 +66,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + //PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); TODO 没有这个方法 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); assertEquals(order.getTotalPrice(), 200); @@ -93,7 +93,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertNull(promotion.getId()); assertEquals(promotion.getName(), "会员折扣"); assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); - assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); + //assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); TODO 没有这个枚举类 assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getDiscountPrice(), 20); assertTrue(promotion.getMatch()); @@ -115,21 +115,22 @@ public class PriceServiceTest extends BaseMockitoUnitTest { ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) - .setActivityName("活动 1000 号").setSkuId(10L) - .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); - DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) - .setActivityName("活动 2000 号").setSkuId(20L) - .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); - when(discountService.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn( - MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); + // mock 方法(限时折扣 DiscountActivity 信息)TODO 没找到 DiscountProductDetailBO + //DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) + // .setActivityName("活动 1000 号").setSkuId(10L) + // .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); + //DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) + // .setActivityName("活动 2000 号").setSkuId(20L) + // .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); + //when(discountService.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn( + // MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); // 10L: 100 * 2 - 40 * 2 = 120 // 20L:50 * 3 - 50 * 3 * 0.4 = 90 // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + //PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); TODO 没有这个方法 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); assertEquals(order.getTotalPrice(), 350); @@ -164,7 +165,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); + //assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion01.getTotalPrice(), 200); assertEquals(promotion01.getDiscountPrice(), 80); assertTrue(promotion01.getMatch()); @@ -178,7 +179,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getId(), 2000L); assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); + //assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion02.getTotalPrice(), 150); assertEquals(promotion02.getDiscountPrice(), 60); assertTrue(promotion02.getMatch()); @@ -217,10 +218,12 @@ public class PriceServiceTest extends BaseMockitoUnitTest { Map> matchRewardActivities = new LinkedHashMap<>(); matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); matchRewardActivities.put(rewardActivity02, asSet(3L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); + // TODO getMatchRewardActivities 没有这个方法,但是找到了 getMatchRewardActivityList + //when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + //PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); TODO 没有这个方法 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); assertEquals(order.getTotalPrice(), 470); @@ -264,7 +267,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + //assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMatch()); @@ -283,7 +286,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getId(), 2000L); assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + //assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getDiscountPrice(), 60); assertTrue(promotion02.getMatch()); @@ -314,10 +317,12 @@ public class PriceServiceTest extends BaseMockitoUnitTest { .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); Map> matchRewardActivities = new LinkedHashMap<>(); matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); + //TODO getMatchRewardActivities 没有这个方法,但是找到了 getMatchRewardActivityList + //when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + //PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); TODO 没有这个方法 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); assertEquals(order.getTotalPrice(), 350); @@ -352,7 +357,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + //assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 0); assertFalse(promotion01.getMatch()); @@ -389,7 +394,8 @@ public class PriceServiceTest extends BaseMockitoUnitTest { when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + //PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); TODO 没有这个方法 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); // 断言 Order 部分 PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); assertEquals(order.getTotalPrice(), 470); @@ -434,7 +440,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1024L); assertEquals(promotion01.getName(), "程序员节"); assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); + //assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); TODO PromotionLevelEnum 没有这个枚举类 assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMatch()); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java index 9f9e28c07..f06104b22 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java @@ -177,13 +177,13 @@ public class RewardActivityServiceImplTest extends BaseDbUnitTest { // 准备参数 Set spuIds = asSet(1L, 2L); - // 调用 - Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); + // 调用 TODO getMatchRewardActivities 没有这个方法,但是找到了 getMatchRewardActivityList + //Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); // 断言 - assertEquals(matchRewardActivities.size(), 1); - Map.Entry> next = matchRewardActivities.entrySet().iterator().next(); - assertPojoEquals(next.getKey(), allActivity); - assertEquals(next.getValue(), spuIds); + //assertEquals(matchRewardActivities.size(), 1); + //Map.Entry> next = matchRewardActivities.entrySet().iterator().next(); + //assertPojoEquals(next.getKey(), allActivity); + //assertEquals(next.getValue(), spuIds); } @Test @@ -198,21 +198,21 @@ public class RewardActivityServiceImplTest extends BaseDbUnitTest { // 准备参数 Set spuIds = asSet(1L, 2L, 3L); - // 调用 - Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); + // 调用 TODO getMatchRewardActivities 没有这个方法,但是找到了 getMatchRewardActivityList + //Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); // 断言 - assertEquals(matchRewardActivities.size(), 2); - matchRewardActivities.forEach((activity, activitySpuIds) -> { - if (activity.getId().equals(productActivity01.getId())) { - assertPojoEquals(activity, productActivity01); - assertEquals(activitySpuIds, asSet(1L, 2L)); - } else if (activity.getId().equals(productActivity02.getId())) { - assertPojoEquals(activity, productActivity02); - assertEquals(activitySpuIds, asSet(3L)); - } else { - fail(); - } - }); + //assertEquals(matchRewardActivities.size(), 2); + //matchRewardActivities.forEach((activity, activitySpuIds) -> { + // if (activity.getId().equals(productActivity01.getId())) { + // assertPojoEquals(activity, productActivity01); + // assertEquals(activitySpuIds, asSet(1L, 2L)); + // } else if (activity.getId().equals(productActivity02.getId())) { + // assertPojoEquals(activity, productActivity02); + // assertEquals(activitySpuIds, asSet(3L)); + // } else { + // fail(); + // } + //}); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index b30ba8855..897080399 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.service.price.bo; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; @@ -193,7 +192,7 @@ public class TradePriceCalculateRespBO { /** * 营销级别 * - * 枚举 {@link PromotionLevelEnum} + * 枚举 @link PromotionLevelEnum} TODO PromotionLevelEnum 没有这个枚举类 */ private Integer level; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java index f628cef4a..af1a9597a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java @@ -69,7 +69,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest { .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); // mock 方法(交易订单项) TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { - o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); + //o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); TODO DO 中没有 orderDividePrice 属性 + o.setOrderId(111L).setUserId(userId); o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); }); when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) From f8db53896f3467a2943a20d08d2588f63c41eb10 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Tue, 30 May 2023 21:17:51 +0800 Subject: [PATCH 066/232] =?UTF-8?q?review=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 1 + .../delivery/DeliveryExpressController.java | 2 -- .../DeliveryExpressTemplateController.java | 1 - .../vo/express/DeliveryExpressBaseVO.java | 4 +-- .../DeliveryExpressTemplateCreateReqVO.java | 6 ++-- .../DeliveryExpressTemplateSimpleRespVO.java | 1 + .../DeliveryExpressTemplateUpdateReqVO.java | 33 ++++++++++++++++--- .../ExpressTemplateChargeUpdateVO.java | 22 ------------- .../ExpressTemplateFreeUpdateVO.java | 19 ----------- .../delivery/DeliveryExpressConvert.java | 6 ---- .../DeliveryExpressTemplateConvert.java | 9 ++--- .../DeliveryExpressTemplateServiceImpl.java | 8 ++--- 12 files changed, 40 insertions(+), 72 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index b887ae8c8..0ace583e7 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -50,6 +50,7 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003003, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java index 72b9e08d0..cff98a558 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java @@ -75,7 +75,6 @@ public class DeliveryExpressController { return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); } - // TODO @jason:运费模版,@芋艿 你的意思是运费模板导出没有必要吧。已经去掉了。这个是快递公司导出 @GetMapping("/export-excel") @Operation(summary = "导出快递公司 Excel") @PreAuthorize("@ss.hasPermission('trade:delivery:express:export')") @@ -87,5 +86,4 @@ public class DeliveryExpressController { List dataList = DeliveryExpressConvert.INSTANCE.convertList02(list); ExcelUtils.write(response, "快递公司.xls", "数据", DeliveryExpressExcelVO.class, dataList); } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index fed5ee13c..1dcab4055 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -20,7 +20,6 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - @Tag(name = "管理后台 - 快递运费模板") @RestController @RequestMapping("/trade/delivery/express-template") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java index c4f629cf6..b92faccdb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressBaseVO.java @@ -27,8 +27,8 @@ public class DeliveryExpressBaseVO { @NotNull(message = "排序不能为空") private Integer sort; - @Schema(description = "状态(0正常 1停用)", required = true, example = "1") - @NotNull(message = "状态(0正常 1停用)不能为空") + @Schema(description = "状态", required = true, example = "1") + @NotNull(message = "状态不能为空") private Integer status; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java index ee51c5659..26173a977 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java @@ -15,14 +15,12 @@ import java.util.List; @ToString(callSuper = true) public class DeliveryExpressTemplateCreateReqVO extends DeliveryExpressTemplateBaseVO { - // TODO @jason:不用给默认值哈 - @Schema(description = "区域运费列表") @Valid - private List templateCharge = Collections.emptyList(); + private List templateCharge; @Schema(description = "包邮区域列表") @Valid - private List templateFree = Collections.emptyList(); + private List templateFree; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java index 2f2c8280d..957ce3c08 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java @@ -5,6 +5,7 @@ import lombok.*; import java.time.LocalDateTime; // TODO @jason:simplae 是不是不用继承 DeliveryExpressTemplateBaseVO,直接 id name 属性就够了。 +// @芋艿 这里给列表显示用的。 需要显示计费方式和排序, 所以继承 DeliveryExpressTemplateBaseVO。 这是去掉了包邮区域和 区域运费列表 @Schema(description = "管理后台 - 快递运费模板 精简 Response VO") @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java index 0f5c65221..d059e3200 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java @@ -7,7 +7,6 @@ import lombok.ToString; import javax.validation.Valid; import javax.validation.constraints.NotNull; -import java.util.Collections; import java.util.List; @Schema(description = "管理后台 - 快递运费模板更新 Request VO") @@ -20,14 +19,38 @@ public class DeliveryExpressTemplateUpdateReqVO extends DeliveryExpressTemplateB @NotNull(message = "编号不能为空") private Long id; - // TODO @jason:pojo 不给默认值哈 - @Schema(description = "区域运费列表") @Valid - private List templateCharge = Collections.emptyList(); + private List templateCharge; @Schema(description = "包邮区域列表") @Valid - private List templateFree = Collections.emptyList(); + private List templateFree; + @Schema(description = "管理后台 - 快递运费模板区域运费更新 Request VO") + @Data + public static class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO { + + @Schema(description = "编号", example = "6592") + private Long id; + + // TODO @jason:这几个字段,应该不通过前端传递,而是后端查询后去赋值的 + @Schema(description = "配送模板编号", example = "1") + private Long templateId; + + @Schema(description = "配送计费方式", example = "1") + private Integer chargeMode; + + } + + @Schema(description = "管理后台 - 快递运费模板包邮区域更新 Request VO") + @Data + public static class ExpressTemplateFreeUpdateVO extends ExpressTemplateFreeBaseVO { + + @Schema(description = "编号", example = "6592") + private Long id; + + @Schema(description = "配送模板编号", example = "1") + private Long templateId; + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java deleted file mode 100644 index e9fcb08f9..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeUpdateVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -// TODO @jason:这个 vo 可以内嵌到 DeliveryExpressTemplateUpdateReqVO,避免 vo 过多,不好分辨 -@Schema(description = "管理后台 - 快递公司创建 Request VO") -@Data -public class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO { - - @Schema(description = "编号", example = "6592") - private Long id; - - // TODO @jason:这几个字段,应该不通过前端传递,而是后端查询后去赋值的 - - @Schema(description = "配送模板编号", example = "1") - private Long templateId; - - @Schema(description = "配送计费方式", example = "1") - private Integer chargeMode; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java deleted file mode 100644 index e2c894456..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeUpdateVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -// TODO @jason:这个 vo 可以内嵌到 DeliveryExpressTemplateUpdateReqVO,避免 vo 过多,不好分辨 -// TODO @jason:swagger 缺失 -/** - * 快递运费模板包邮 更新 VO - */ -@Data -public class ExpressTemplateFreeUpdateVO extends ExpressTemplateFreeBaseVO { - - @Schema(description = "编号", example = "6592") - private Long id; - - @Schema(description = "配送模板编号", example = "1") - private Long templateId; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java index 474881790..c4529ba89 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java @@ -12,12 +12,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; - -/** - * 快递公司 Convert - * - * @author jason - */ @Mapper public interface DeliveryExpressConvert { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index 20e94cb25..424c7e132 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -11,11 +11,6 @@ import org.mapstruct.factory.Mappers; import java.util.List; -/** - * 快递运费模板 Convert - * - * @author jason - */ @Mapper public interface DeliveryExpressTemplateConvert { @@ -48,7 +43,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(Long templateId, Integer chargeMode, ExpressTemplateChargeBaseVO vo); - DeliveryExpressTemplateChargeDO convertTemplateCharge(ExpressTemplateChargeUpdateVO vo); + DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo); default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); @@ -58,7 +53,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateFreeDO convertTemplateFree(Long templateId, ExpressTemplateFreeBaseVO vo); - DeliveryExpressTemplateFreeDO convertTemplateFree(ExpressTemplateFreeUpdateVO vo); + DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo); List convertTemplateChargeList(List list); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index d7bf96978..d77bb78c2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -82,10 +82,10 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private void updateExpressTemplateFree(DeliveryExpressTemplateUpdateReqVO updateReqVO) { // 1.1 获得新增/修改的区域列表 List oldFreeList = expressTemplateFreeMapper.selectListByTemplateId(updateReqVO.getId()); - List newFreeList = updateReqVO.getTemplateFree(); + List newFreeList = updateReqVO.getTemplateFree(); List addFreeList = new ArrayList<>(newFreeList.size()); // 新增包邮区域列表 List updateFreeList = new ArrayList<>(newFreeList.size()); // 更新包邮区域列表 - for (ExpressTemplateFreeUpdateVO item : newFreeList) { + for (DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO item : newFreeList) { if (Objects.nonNull(item.getId())) { updateFreeList.add(INSTANCE.convertTemplateFree(item)); } else { @@ -113,10 +113,10 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private void updateExpressTemplateCharge(DeliveryExpressTemplateUpdateReqVO updateReqVO) { // 1.1 获得新增/修改的区域列表 List oldChargeList = expressTemplateChargeMapper.selectListByTemplateId(updateReqVO.getId()); - List newChargeList = updateReqVO.getTemplateCharge(); + List newChargeList = updateReqVO.getTemplateCharge(); List addList = new ArrayList<>(newChargeList.size()); // 新增运费区域列表 List updateList = new ArrayList<>(newChargeList.size()); // 更新运费区域列表 - for (ExpressTemplateChargeUpdateVO item : newChargeList) { + for (DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO item : newChargeList) { if (item.getId() != null) { // 计费模式以主表为准 item.setChargeMode(updateReqVO.getChargeMode()); From 894b19b8ec1526b8d8cfb3a6b64889a1f948733c Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Tue, 30 May 2023 21:18:30 +0800 Subject: [PATCH 067/232] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E6=8F=90?= =?UTF-8?q?=E9=97=A8=E5=BA=97=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optional/mall.sql | 43 ++++---- .../DeliveryPickUpStoreController.java | 98 +++++++++++++++++++ .../vo/pickup/DeliveryPickUpStoreBaseVO.java | 68 +++++++++++++ .../DeliveryPickUpStoreCreateReqVO.java | 14 +++ .../vo/pickup/DeliveryPickUpStoreExcelVO.java | 57 +++++++++++ .../DeliveryPickUpStoreExportReqVO.java | 34 +++++++ .../pickup/DeliveryPickUpStorePageReqVO.java | 40 ++++++++ .../vo/pickup/DeliveryPickUpStoreRespVO.java | 19 ++++ .../DeliveryPickUpStoreUpdateReqVO.java | 18 ++++ .../delivery/DeliveryPickUpStoreConvert.java | 43 ++++++++ .../delivery/DeliveryPickUpStoreDO.java | 10 +- .../delivery/DeliveryPickUpStoreMapper.java | 26 +++++ .../delivery/DeliveryPickUpStoreService.java | 72 ++++++++++++++ .../DeliveryPickUpStoreServiceImpl.java | 84 ++++++++++++++++ 14 files changed, 596 insertions(+), 30 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreServiceImpl.java diff --git a/sql/mysql/optional/mall.sql b/sql/mysql/optional/mall.sql index 1cfda1722..9bad4993a 100644 --- a/sql/mysql/optional/mall.sql +++ b/sql/mysql/optional/mall.sql @@ -389,18 +389,18 @@ CREATE TABLE `trade_delivery_express_template_charge` ( -- ---------------------------- DROP TABLE IF EXISTS `trade_delivery_pick_up_store`; CREATE TABLE `trade_delivery_pick_up_store` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(64) NOT NULL COMMENT '门店名称', `introduction` varchar(256) COMMENT '门店简介', `phone` varchar(16) NOT NULL COMMENT '门店手机', - `area_id` int NOT NULL COMMENT '区域id', + `area_id` int NOT NULL COMMENT '区域编号', `detail_address` varchar(256) NOT NULL COMMENT '门店详细地址', - `logo` varchar(256) NOT NULL COMMENT '门店logo', + `logo` varchar(256) NOT NULL COMMENT '门店 logo', `opening_time` time NOT NULL COMMENT '营业开始时间', `closing_time` time NOT NULL COMMENT '营业结束时间', - `latitude` varchar(128) NOT NULL COMMENT '纬度', - `longitude` varchar(128) NOT NULL COMMENT '经度', - `status` tinyint NOT NULL DEFAULT 0 COMMENT '门店状态(0正常 1停用)', + `latitude` double NOT NULL COMMENT '纬度', + `longitude` double NOT NULL COMMENT '经度', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '门店状态', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -427,25 +427,6 @@ CREATE TABLE `trade_delivery_pick_up_store_staff` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB COMMENT='自提门店店员'; --- ---------------------------- --- Table structure for trade_delivery_pick_up_store_staff --- ---------------------------- -DROP TABLE IF EXISTS `trade_delivery_pick_up_store_staff`; -CREATE TABLE `trade_delivery_pick_up_store_staff` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,自增', - `admin_user_id` bigint NOT NULL COMMENT '管理员用户id', - store_id bigint NOT NULL COMMENT '自提门店编号', - `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='自提门店店员'; - - -- ---------------------------- -- Table structure for trade_delivery_express -- ---------------------------- @@ -541,3 +522,15 @@ INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0'); INSERT INTO `ruoyi-vue-pro`.`system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0'); COMMIT; + +-- ---------------------------- +-- 门店管理 菜单 +-- ---------------------------- +BEGIN; +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2179, '门店管理', '', 2, 1, 2166, 'pick-up-store', '', 'mall/trade/delivery/pickUpStore/index', 'PickUpStore', 0, b'1', b'1', b'1', '1', '2023-05-25 10:50:00', '1', '2023-05-25 10:50:00', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2180, '自提门店查询', 'trade:delivery:pick-up-store:query', 3, 1, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2181, '自提门店创建', 'trade:delivery:pick-up-store:create', 3, 2, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2182, '自提门店更新', 'trade:delivery:pick-up-store:update', 3, 3, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2183, '自提门店删除', 'trade:delivery:pick-up-store:delete', 3, 4, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); +INSERT INTO `ruoyi-vue-pro`.`system_menu`(`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2184, '自提门店导出', 'trade:delivery:pick-up-store:export', 3, 5, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); +COMMIT; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java new file mode 100644 index 000000000..e8c7eb5c4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java @@ -0,0 +1,98 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.*; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryPickUpStoreConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Tag(name = "管理后台 - 自提门店") +@RestController +@RequestMapping("/trade/delivery/pick-up-store") +@Validated +public class DeliveryPickUpStoreController { + + @Resource + private DeliveryPickUpStoreService deliveryPickUpStoreService; + + @PostMapping("/create") + @Operation(summary = "创建自提门店") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:create')") + public CommonResult createDeliveryPickUpStore(@Valid @RequestBody DeliveryPickUpStoreCreateReqVO createReqVO) { + return success(deliveryPickUpStoreService.createDeliveryPickUpStore(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新自提门店") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:update')") + public CommonResult updateDeliveryPickUpStore(@Valid @RequestBody DeliveryPickUpStoreUpdateReqVO updateReqVO) { + deliveryPickUpStoreService.updateDeliveryPickUpStore(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除自提门店") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:delete')") + public CommonResult deleteDeliveryPickUpStore(@RequestParam("id") Long id) { + deliveryPickUpStoreService.deleteDeliveryPickUpStore(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得自提门店") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:query')") + public CommonResult getDeliveryPickUpStore(@RequestParam("id") Long id) { + DeliveryPickUpStoreDO deliveryPickUpStore = deliveryPickUpStoreService.getDeliveryPickUpStore(id); + return success(DeliveryPickUpStoreConvert.INSTANCE.convert(deliveryPickUpStore)); + } + + @GetMapping("/list") + @Operation(summary = "获得自提门店列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:query')") + public CommonResult> getDeliveryPickUpStoreList(@RequestParam("ids") Collection ids) { + List list = deliveryPickUpStoreService.getDeliveryPickUpStoreList(ids); + return success(DeliveryPickUpStoreConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得自提门店分页") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:query')") + public CommonResult> getDeliveryPickUpStorePage(@Valid DeliveryPickUpStorePageReqVO pageVO) { + PageResult pageResult = deliveryPickUpStoreService.getDeliveryPickUpStorePage(pageVO); + return success(DeliveryPickUpStoreConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出自提门店 Excel") + @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:export')") + @OperateLog(type = EXPORT) + public void exportDeliveryPickUpStoreExcel(@Valid DeliveryPickUpStoreExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = deliveryPickUpStoreService.getDeliveryPickUpStoreList(exportReqVO); + // 导出 Excel + List datas = DeliveryPickUpStoreConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "自提门店.xls", "数据", DeliveryPickUpStoreExcelVO.class, datas); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java new file mode 100644 index 000000000..b1eaf3fb3 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalTime; + +/** +* 自提门店 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class DeliveryPickUpStoreBaseVO { + + @Schema(description = "门店名称", required = true, example = "李四") + @NotBlank(message = "门店名称不能为空") + private String name; + + @Schema(description = "门店简介") + private String introduction; + + @Schema(description = "门店手机", required = true) + @NotBlank(message = "门店手机不能为空") + @Mobile + private String phone; + + @Schema(description = "区域编号", required = true, example = "18733") + @NotNull(message = "区域编号不能为空") + private Integer areaId; + + @Schema(description = "门店详细地址", required = true) + @NotBlank(message = "门店详细地址不能为空") + private String detailAddress; + + @Schema(description = "门店 logo", required = true) + @NotBlank(message = "门店 logo 不能为空") + private String logo; + + @Schema(description = "营业开始时间", required = true) + @NotNull(message = "营业开始时间不能为空") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm") + private LocalTime openingTime; + + @Schema(description = "营业结束时间", required = true) + @NotNull(message = "营业结束时间不能为空") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm") + private LocalTime closingTime; + + @Schema(description = "纬度", required = true) + @NotNull(message = "纬度不能为空") + private Double latitude; + + @Schema(description = "经度", required = true) + @NotNull(message = "经度不能为空") + private Double longitude; + + @Schema(description = "门店状态", required = true, example = "1") + @NotNull(message = "门店状态不能为空") + @InEnum(CommonStatusEnum.class) + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreCreateReqVO.java new file mode 100644 index 000000000..2185a2a55 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 自提门店创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryPickUpStoreCreateReqVO extends DeliveryPickUpStoreBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java new file mode 100644 index 000000000..bc96ca622 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.system.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class DeliveryPickUpStoreExcelVO { + + @ExcelProperty("编号") + private Long id; + + @ExcelProperty("门店名称") + private String name; + + @ExcelProperty("门店简介") + private String introduction; + + @ExcelProperty("门店手机") + private String phone; + + @ExcelProperty("门店所在区域") + private String areaName; + + @ExcelProperty("门店详细地址") + private String detailAddress; + + @ExcelProperty("门店logo") + private String logo; + + /** + * easy-excel 好像暂时不支持 LocalTime. 转成string + */ + @ExcelProperty("营业开始时间") + private String openingTime; + + @ExcelProperty("营业结束时间") + private String closingTime; + + @ExcelProperty("纬度") + private String latitude; + + @ExcelProperty("经度") + private String longitude; + + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.COMMON_STATUS) + private Integer status; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExportReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExportReqVO.java new file mode 100644 index 000000000..05546de77 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExportReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 自提门店 Excel 导出 Request VO,参数和 DeliveryPickUpStorePageReqVO 是一致的") +@Data +public class DeliveryPickUpStoreExportReqVO { + + @Schema(description = "门店名称", example = "李四") + private String name; + + @Schema(description = "门店手机") + private String phone; + + @Schema(description = "区域id", example = "18733") + private Integer areaId; + + @Schema(description = "门店状态", example = "1") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java new file mode 100644 index 000000000..45f0c87b9 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import lombok.*; + +import java.time.LocalTime; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 自提门店分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryPickUpStorePageReqVO extends PageParam { + + @Schema(description = "门店名称", example = "李四") + private String name; + + @Schema(description = "门店手机") + private String phone; + + @Schema(description = "区域编号", example = "18733") + private Integer areaId; + + @Schema(description = "门店状态", example = "1") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreRespVO.java new file mode 100644 index 000000000..db0ffc0e8 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 自提门店 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryPickUpStoreRespVO extends DeliveryPickUpStoreBaseVO { + + @Schema(description = "编号", required = true, example = "23128") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreUpdateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreUpdateReqVO.java new file mode 100644 index 000000000..21a750075 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 自提门店更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryPickUpStoreUpdateReqVO extends DeliveryPickUpStoreBaseVO { + + @Schema(description = "编号", required = true, example = "23128") + @NotNull(message = "编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java new file mode 100644 index 000000000..03f219567 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.trade.convert.delivery; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreExcelVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DeliveryPickUpStoreConvert { + + DeliveryPickUpStoreConvert INSTANCE = Mappers.getMapper(DeliveryPickUpStoreConvert.class); + + DeliveryPickUpStoreDO convert(DeliveryPickUpStoreCreateReqVO bean); + + DeliveryPickUpStoreDO convert(DeliveryPickUpStoreUpdateReqVO bean); + + DeliveryPickUpStoreRespVO convert(DeliveryPickUpStoreDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + + @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToName") + DeliveryPickUpStoreExcelVO convert2(DeliveryPickUpStoreDO bean); + + @Named("convertAreaIdToName") + default String convertAreaIdToName(Integer areaId) { + return AreaUtils.format(areaId); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java index f347c7912..21ff99374 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java @@ -20,7 +20,7 @@ import java.time.LocalTime; public class DeliveryPickUpStoreDO extends BaseDO { /** - * 编号,自增 + * 编号 */ @TableId private Long id; @@ -41,7 +41,7 @@ public class DeliveryPickUpStoreDO extends BaseDO { private String phone; /** - * 区域 id + * 区域编号 */ private Integer areaId; @@ -59,20 +59,20 @@ public class DeliveryPickUpStoreDO extends BaseDO { * 营业开始时间 */ private LocalTime openingTime; + /** * 营业结束时间 */ private LocalTime closingTime; - // TODO @Jason:应该是 double? /** * 纬度 */ - private String latitude; + private Double latitude; /** * 经度 */ - private String longitude; + private Double longitude; /** * 门店状态 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java index d68924047..7ccf6ad98 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryPickUpStoreMapper.java @@ -1,11 +1,37 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStorePageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface DeliveryPickUpStoreMapper extends BaseMapperX { + + default PageResult selectPage(DeliveryPickUpStorePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(DeliveryPickUpStoreDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryPickUpStoreDO::getPhone, reqVO.getPhone()) + .eqIfPresent(DeliveryPickUpStoreDO::getAreaId, reqVO.getAreaId()) + .eqIfPresent(DeliveryPickUpStoreDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(DeliveryPickUpStoreDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(DeliveryPickUpStoreDO::getId)); + } + + default List selectList(DeliveryPickUpStoreExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(DeliveryPickUpStoreDO::getName, reqVO.getName()) + .eqIfPresent(DeliveryPickUpStoreDO::getPhone, reqVO.getPhone()) + .eqIfPresent(DeliveryPickUpStoreDO::getAreaId, reqVO.getAreaId()) + .eqIfPresent(DeliveryPickUpStoreDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(DeliveryPickUpStoreDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(DeliveryPickUpStoreDO::getId)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreService.java new file mode 100644 index 000000000..82d7548e1 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreService.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStorePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; + +/** + * 自提门店 Service 接口 + * + * @author jason + */ +public interface DeliveryPickUpStoreService { + + /** + * 创建自提门店 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDeliveryPickUpStore(@Valid DeliveryPickUpStoreCreateReqVO createReqVO); + + /** + * 更新自提门店 + * + * @param updateReqVO 更新信息 + */ + void updateDeliveryPickUpStore(@Valid DeliveryPickUpStoreUpdateReqVO updateReqVO); + + /** + * 删除自提门店 + * + * @param id 编号 + */ + void deleteDeliveryPickUpStore(Long id); + + /** + * 获得自提门店 + * + * @param id 编号 + * @return 自提门店 + */ + DeliveryPickUpStoreDO getDeliveryPickUpStore(Long id); + + /** + * 获得自提门店列表 + * + * @param ids 编号 + * @return 自提门店列表 + */ + List getDeliveryPickUpStoreList(Collection ids); + + /** + * 获得自提门店分页 + * + * @param pageReqVO 分页查询 + * @return 自提门店分页 + */ + PageResult getDeliveryPickUpStorePage(DeliveryPickUpStorePageReqVO pageReqVO); + + /** + * 获得自提门店列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 自提门店列表 + */ + List getDeliveryPickUpStoreList(DeliveryPickUpStoreExportReqVO exportReqVO); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreServiceImpl.java new file mode 100644 index 000000000..ac5eaa3a5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryPickUpStoreServiceImpl.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.trade.service.delivery; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreExportReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStorePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryPickUpStoreConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryPickUpStoreMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; + + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; + +/** + * 自提门店 Service 实现类 + * + * @author jason + */ +@Service +@Validated +public class DeliveryPickUpStoreServiceImpl implements DeliveryPickUpStoreService { + + @Resource + private DeliveryPickUpStoreMapper deliveryPickUpStoreMapper; + + @Override + public Long createDeliveryPickUpStore(DeliveryPickUpStoreCreateReqVO createReqVO) { + // 插入 + DeliveryPickUpStoreDO deliveryPickUpStore = DeliveryPickUpStoreConvert.INSTANCE.convert(createReqVO); + deliveryPickUpStoreMapper.insert(deliveryPickUpStore); + // 返回 + return deliveryPickUpStore.getId(); + } + + @Override + public void updateDeliveryPickUpStore(DeliveryPickUpStoreUpdateReqVO updateReqVO) { + // 校验存在 + validateDeliveryPickUpStoreExists(updateReqVO.getId()); + // 更新 + DeliveryPickUpStoreDO updateObj = DeliveryPickUpStoreConvert.INSTANCE.convert(updateReqVO); + deliveryPickUpStoreMapper.updateById(updateObj); + } + + @Override + public void deleteDeliveryPickUpStore(Long id) { + // 校验存在 + validateDeliveryPickUpStoreExists(id); + // 删除 + deliveryPickUpStoreMapper.deleteById(id); + } + + private void validateDeliveryPickUpStoreExists(Long id) { + if (deliveryPickUpStoreMapper.selectById(id) == null) { + throw exception(PICK_UP_STORE_NOT_EXISTS); + } + } + + @Override + public DeliveryPickUpStoreDO getDeliveryPickUpStore(Long id) { + return deliveryPickUpStoreMapper.selectById(id); + } + + @Override + public List getDeliveryPickUpStoreList(Collection ids) { + return deliveryPickUpStoreMapper.selectBatchIds(ids); + } + + @Override + public PageResult getDeliveryPickUpStorePage(DeliveryPickUpStorePageReqVO pageReqVO) { + return deliveryPickUpStoreMapper.selectPage(pageReqVO); + } + + @Override + public List getDeliveryPickUpStoreList(DeliveryPickUpStoreExportReqVO exportReqVO) { + return deliveryPickUpStoreMapper.selectList(exportReqVO); + } +} From e34eddc3865bc5314a950fbc767404805e138ae4 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 31 May 2023 09:18:24 +0800 Subject: [PATCH 068/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E8=87=AA=E6=8F=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/trade/enums/ErrorCodeConstants.java | 1 + .../delivery/DeliveryPickUpStoreController.java | 1 + .../vo/pickup/DeliveryPickUpStoreBaseVO.java | 12 ++++++------ .../vo/pickup/DeliveryPickUpStoreExcelVO.java | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 0ace583e7..37306465f 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -47,6 +47,7 @@ public interface ErrorCodeConstants { // ========== 物流配送模块 1011003000 ========== ErrorCode DELIVERY_EXPRESS_NOT_EXISTS = new ErrorCode(1011003000, "快递公司不存在"); + // TODO @jason:最好每个模块一段哈。express 一个;exmpresstemplate 一个;pickup 一个 ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java index e8c7eb5c4..3b7421aa4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java @@ -84,6 +84,7 @@ public class DeliveryPickUpStoreController { return success(DeliveryPickUpStoreConvert.INSTANCE.convertPage(pageResult)); } + // TODO @jason:导出去掉好列;简化下,一般用不到哈。 @GetMapping("/export-excel") @Operation(summary = "导出自提门店 Excel") @PreAuthorize("@ss.hasPermission('trade:delivery:pick-up-store:export')") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java index b1eaf3fb3..45c07177d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreBaseVO.java @@ -22,10 +22,10 @@ public class DeliveryPickUpStoreBaseVO { @NotBlank(message = "门店名称不能为空") private String name; - @Schema(description = "门店简介") + @Schema(description = "门店简介", example = "我是门店简介") private String introduction; - @Schema(description = "门店手机", required = true) + @Schema(description = "门店手机", required = true, example = "15601892312") @NotBlank(message = "门店手机不能为空") @Mobile private String phone; @@ -34,11 +34,11 @@ public class DeliveryPickUpStoreBaseVO { @NotNull(message = "区域编号不能为空") private Integer areaId; - @Schema(description = "门店详细地址", required = true) + @Schema(description = "门店详细地址", required = true, example = "复旦大学路 188 号") @NotBlank(message = "门店详细地址不能为空") private String detailAddress; - @Schema(description = "门店 logo", required = true) + @Schema(description = "门店 logo", required = true, example = "https://www.iocoder.cn/1.png") @NotBlank(message = "门店 logo 不能为空") private String logo; @@ -52,11 +52,11 @@ public class DeliveryPickUpStoreBaseVO { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm") private LocalTime closingTime; - @Schema(description = "纬度", required = true) + @Schema(description = "纬度", required = true, example = "5.88") @NotNull(message = "纬度不能为空") private Double latitude; - @Schema(description = "经度", required = true) + @Schema(description = "经度", required = true, example = "6.99") @NotNull(message = "经度不能为空") private Double longitude; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java index bc96ca622..a50b0ce75 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreExcelVO.java @@ -32,6 +32,7 @@ public class DeliveryPickUpStoreExcelVO { @ExcelProperty("门店logo") private String logo; + // TODO @jason:是不是可以加个 convert? /** * easy-excel 好像暂时不支持 LocalTime. 转成string */ From e86214015d6bdfe199e0daecb3c74538713bfe8b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 31 May 2023 16:39:43 +0800 Subject: [PATCH 069/232] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E5=95=86?= =?UTF-8?q?=E5=93=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ProductConstants.java | 16 -------- .../enums/spu/ProductSpuPageTabEnum.java | 40 ------------------- .../admin/spu/vo/ProductSpuExportReqVO.java | 8 ++-- .../admin/spu/vo/ProductSpuPageReqVO.java | 28 +++++++++++-- .../admin/spu/vo/ProductSpuRespVO.java | 2 +- .../category/ProductCategoryDO.java | 10 +++++ .../dal/mysql/spu/ProductSpuMapper.java | 11 +++-- .../category/ProductCategoryServiceImpl.java | 14 +++---- .../service/spu/ProductSpuServiceImpl.java | 16 ++++---- .../ProductCategoryServiceImplTest.java | 3 +- .../spu/ProductSpuServiceImplTest.java | 15 ++++--- .../DeliveryExpressTemplateController.java | 10 +++++ .../DeliveryExpressTemplateSimpleRespVO.java | 10 ++--- .../DeliveryExpressTemplateService.java | 7 ++++ .../DeliveryExpressTemplateServiceImpl.java | 5 +++ 15 files changed, 96 insertions(+), 99 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java index 50d43bb97..117285071 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java @@ -7,22 +7,6 @@ package cn.iocoder.yudao.module.product.enums; */ public interface ProductConstants { - // TODO @puhui999:这个变量,可以放到 CategoryDO 的实体里 - /** - * 父分类编号 - 根分类 - */ - Long PARENT_ID_NULL = 0L; - /** - * 限定分类层级 - */ - int CATEGORY_LEVEL = 2; - - // TODO @puhui999:这个变量,必要项不大哈 - /** - * SPU 分页 tab 个数 - */ - int SPU_TAB_COUNTS = 5; - /** * 警戒库存 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换 */ diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java deleted file mode 100644 index c79c55a97..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuPageTabEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.spu; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -// TODO @puhui999:这种非关键的枚举,要不直接写在 ProductSpuPageReqVO 里。类似 public static final Integer TAB_TYPE_FOR_SALE = 0; // 出售中商品 -/** - * 商品 spu Tabs 标签枚举类型 - * - * @author HUIHUI - */ -@Getter -@AllArgsConstructor -public enum ProductSpuPageTabEnum implements IntArrayValuable { - - FOR_SALE(0,"出售中商品"), - IN_WAREHOUSE(1,"仓库中商品"), - SOLD_OUT(2,"已售空商品"), - ALERT_STOCK(3,"警戒库存"), - RECYCLE_BIN(4,"商品回收站"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuPageTabEnum::getType).toArray(); - /** - * 状态 - */ - private final Integer type; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java index 11260c1b2..f1da656d1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; @@ -12,6 +10,11 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +/** + * 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的 + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的") @Data @NoArgsConstructor @@ -22,7 +25,6 @@ public class ProductSpuExportReqVO { private String name; @Schema(description = "前端请求的tab类型", example = "1") - @InEnum(ProductSpuPageTabEnum.class) private Integer tabType; @Schema(description = "商品分类编号", example = "100") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 9dca61d69..cff3bf17c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -2,14 +2,12 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; -import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -25,11 +23,35 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class ProductSpuPageReqVO extends PageParam { + /** + * 出售中商品 + */ + public static final Integer FOR_SALE = 0; + + /** + * 仓库中商品 + */ + public static final Integer IN_WAREHOUSE = 1; + + /** + * 已售空商品 + */ + public static final Integer SOLD_OUT = 2; + + /** + * 警戒库存 + */ + public static final Integer ALERT_STOCK = 3; + + /** + * 商品回收站 + */ + public static final Integer RECYCLE_BIN = 4; + @Schema(description = "商品名称", example = "清凉小短袖") private String name; @Schema(description = "前端请求的tab类型", required = true, example = "1") - @InEnum(ProductSpuPageTabEnum.class) private Integer tabType; @Schema(description = "商品分类编号", example = "1") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index 39b35ae68..45736563c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -9,7 +9,7 @@ import java.time.LocalDateTime; /** * 商品 SPU Response VO - * TODO 移除ProductSpuPageRespVO相关应用跟换为ProductSpuRespVO已继承ProductSpuBaseVO 补全表格展示所需属性 + * * @author HUIHUI */ @Schema(description = "管理后台 - 商品 SPU Response VO") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index b8444a31f..bf69e0028 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -19,6 +19,16 @@ import lombok.*; @NoArgsConstructor @AllArgsConstructor public class ProductCategoryDO extends BaseDO { + + /** + * 父分类编号 - 根分类 + */ + public static final Long PARENT_ID_NULL = 0L; + /** + * 限定分类层级 + */ + public static final int CATEGORY_LEVEL = 2; + /** * 分类编号 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index abf357c24..27a393ee6 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.enums.ProductConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -119,25 +118,25 @@ public interface ProductSpuMapper extends BaseMapperX { */ static void appendTabQuery(Integer tabType, LambdaQueryWrapperX queryWrapper) { // 出售中商品 - if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) { + if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) { queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); } // 仓储中商品 - if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) { + if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) { queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); } // 已售空商品 - if (ObjectUtil.equals(ProductSpuPageTabEnum.SOLD_OUT.getType(), tabType)) { + if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) { queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0); } // 警戒库存 - if (ObjectUtil.equals(ProductSpuPageTabEnum.ALERT_STOCK.getType(), tabType)) { + if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) { queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示 .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } // 回收站 - if (ObjectUtil.equals(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), tabType)) { + if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) { queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 534fd7131..47e395424 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; /** @@ -69,7 +70,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { private void validateParentProductCategory(Long id) { // 如果是根分类,无需验证 - if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) { + if (Objects.equals(id, PARENT_ID_NULL)) { return; } // 父分类不存在 @@ -78,7 +79,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { throw exception(CATEGORY_PARENT_NOT_EXISTS); } // 父分类不能是二级分类 - if (!Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) { + if (!Objects.equals(category.getParentId(), PARENT_ID_NULL)) { throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL); } } @@ -108,17 +109,16 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @Override public Integer getCategoryLevel(Long id) { - if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) { + if (Objects.equals(id, PARENT_ID_NULL)) { return 0; } - // TODO @puhui999:for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈 int level = 1; - // fix: 循环次数不确定改为while循环 - while (true){ + // for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈 + for (int i = 0; i < 100; i++) { ProductCategoryDO category = productCategoryMapper.selectById(id); // 如果没有父节点,break 结束 if (category == null - || Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) { + || Objects.equals(category.getParentId(), PARENT_ID_NULL)) { break; } // 继续递归父节点 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 859450510..4adc08e18 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -14,7 +14,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.ProductConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; @@ -29,6 +28,7 @@ import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; /** @@ -129,7 +129,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { private void validateCategory(Long id) { categoryService.validateCategory(id); // 校验层级 - if (categoryService.getCategoryLevel(id) != ProductConstants.CATEGORY_LEVEL) { + if (categoryService.getCategoryLevel(id) < CATEGORY_LEVEL) { throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR); } } @@ -237,17 +237,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public Map getTabsCount() { - Map counts = new HashMap<>(ProductConstants.SPU_TAB_COUNTS); + Map counts = new HashMap<>(5); // 查询销售中的商品数量 - counts.put(ProductSpuPageTabEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); + counts.put(ProductSpuPageReqVO.FOR_SALE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); // 查询仓库中的商品数量 - counts.put(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); + counts.put(ProductSpuPageReqVO.IN_WAREHOUSE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); // 查询售空的商品数量 - counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); + counts.put(ProductSpuPageReqVO.SOLD_OUT, productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); // 查询触发警戒库存的商品数量 - counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCount()); + counts.put(ProductSpuPageReqVO.ALERT_STOCK, productSpuMapper.selectCount()); // 查询回收站中的商品数量 - counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + counts.put(ProductSpuPageReqVO.RECYCLE_BIN, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); return counts; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 0ba5633cd..37e262d9a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -18,9 +18,8 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; - +import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ProductConstants.PARENT_ID_NULL; import static org.junit.jupiter.api.Assertions.*; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 06053b261..30f6c293b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -14,7 +14,6 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateR import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl; import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl; @@ -318,7 +317,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { productSpuMapper.insertBatch(createReqVOs); // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); + productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); @@ -366,7 +365,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { productSpuMapper.insertBatch(createReqVOs); // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); + productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK); PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); assertEquals(createReqVOs.size(), spuPage.getTotal()); } @@ -407,11 +406,11 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); // 查询条件 按需打开 - //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType()); - //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.RECYCLE_BIN.getType()); - //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.FOR_SALE.getType()); - //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.IN_WAREHOUSE.getType()); - //productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.SOLD_OUT.getType()); + //productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK); + //productSpuPageReqVO.setTabType(ProductSpuPageReqVO.RECYCLE_BIN); + //productSpuPageReqVO.setTabType(ProductSpuPageReqVO.FOR_SALE); + //productSpuPageReqVO.setTabType(ProductSpuPageReqVO.IN_WAREHOUSE); + //productSpuPageReqVO.setTabType(ProductSpuPageReqVO.SOLD_OUT); //productSpuPageReqVO.setName(createReqVO.getName()); //productSpuPageReqVO.setCategoryId(createReqVO.getCategoryId()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index fed5ee13c..eafc03366 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; @@ -71,6 +72,15 @@ public class DeliveryExpressTemplateController { return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); } + @GetMapping("/list-all-simple") + @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项") + public CommonResult> getSimpleTemplateList() { + // 获取运费模版列表,只要开启状态的 + List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(); + // 排序后,返回给前端 + return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); + } + @GetMapping("/page") @Operation(summary = "获得快递运费模板分页") @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java index 2f2c8280d..fe9a10d4b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java @@ -2,19 +2,19 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstempla import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; + +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -// TODO @jason:simplae 是不是不用继承 DeliveryExpressTemplateBaseVO,直接 id name 属性就够了。 @Schema(description = "管理后台 - 快递运费模板 精简 Response VO") @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class DeliveryExpressTemplateSimpleRespVO extends DeliveryExpressTemplateBaseVO { +public class DeliveryExpressTemplateSimpleRespVO { @Schema(description = "编号,自增", required = true, example = "371") private Long id; - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; + @Schema(description = "模板名称", required = true, example = "王五") + private String name; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 20a0a1b62..7f5f8d8d3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -56,6 +56,13 @@ public interface DeliveryExpressTemplateService { */ List getDeliveryExpressTemplateList(Collection ids); + /** + * 获得快递运费模板列表 + * + * @return 快递运费模板列表 + */ + List getDeliveryExpressTemplateList(); + /** * 获得快递运费模板分页 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index d7bf96978..1f53a1425 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -197,6 +197,11 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla return expressTemplateMapper.selectBatchIds(ids); } + @Override + public List getDeliveryExpressTemplateList() { + return expressTemplateMapper.selectList(); + } + @Override public PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO) { return expressTemplateMapper.selectPage(pageReqVO); From 5de8fa2e42f157004d4f951d3599462f7e07946e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 31 May 2023 21:17:35 +0800 Subject: [PATCH 070/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/price/dto/PriceCalculateRespDTO.java | 1 - .../module/promotion/api/price/PriceApiImpl.java | 2 +- .../controller/app/order/AppTradeOrderController.java | 3 +++ .../app/order/vo/AppTradeOrderSettlementRespVO.java | 2 +- .../module/trade/service/order/TradeOrderService.java | 11 +++++++++++ .../trade/service/order/TradeOrderServiceImpl.java | 7 +++++++ .../service/price/bo/TradePriceCalculateRespBO.java | 1 - 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java index 9a98029b7..0c1bd4586 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.api.price.dto; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java index 3c415f1c4..d77c38b58 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java @@ -20,7 +20,7 @@ public class PriceApiImpl implements PriceApi { @Override public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - return priceService.calculatePrice(calculateReqDTO); + return null; } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index d0c224bbd..738741f6e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -55,6 +55,9 @@ public class AppTradeOrderController { @PreAuthenticated public CommonResult settlementOrder( @Valid AppTradeOrderSettlementReqVO settlementReqVO) { + if (true) { + return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO)); + } // return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java index b76b3733c..b2d4e4108 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java @@ -77,7 +77,7 @@ public class AppTradeOrderSettlementRespVO { } - @Schema(description = "费用(合计)") + @Schema(description = "地址信息") @Data public static class Address { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java index b8a002791..97e548521 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliver import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -23,6 +25,15 @@ public interface TradeOrderService { // =================== Order =================== + /** + * 获得订单结算信息 + * + * @param userId 登录用户 + * @param settlementReqVO 订单结算请求 + * @return 订单结算结果 + */ + AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO); + /** * 【会员】创建交易订单 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 45e5e490b..c4760b4b1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -31,6 +31,8 @@ import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliver import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -88,6 +90,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { // =================== Order =================== + @Override + public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { + return null; + } + @Override @Transactional(rollbackFor = Exception.class) public Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index b30ba8855..1c347a532 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.service.price.bo; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; From 8d2bcc57aabc55b9f4c9ca6152b3317d2a520e32 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 1 Jun 2023 11:41:26 +0800 Subject: [PATCH 071/232] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E5=95=86?= =?UTF-8?q?=E5=93=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 1 + .../admin/brand/ProductBrandController.java | 2 +- .../vo/property/ProductPropertyListReqVO.java | 4 - .../convert/sku/ProductSkuConvert.java | 1 - .../dal/mysql/sku/ProductSkuMapper.java | 21 +++++ .../category/ProductCategoryServiceImpl.java | 16 +++- .../property/ProductPropertyServiceImpl.java | 11 +-- .../ProductPropertyValueServiceImpl.java | 8 +- .../service/sku/ProductSkuService.java | 17 ++++ .../service/sku/ProductSkuServiceImpl.java | 81 +++++++++++++++++++ .../service/spu/ProductSpuService.java | 9 +++ .../service/spu/ProductSpuServiceImpl.java | 5 ++ .../service/sku/ProductSkuServiceTest.java | 42 +++++++--- .../spu/ProductSpuServiceImplTest.java | 4 +- 14 files changed, 197 insertions(+), 25 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index 7e9a59df2..d97a2613f 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -15,6 +15,7 @@ public interface ErrorCodeConstants { ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类"); ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除"); ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用"); + ErrorCode CATEGORY_HAVE_BIND_SPU = new ErrorCode(1008001005, "类别下存在商品,无法删除"); // ========== 商品品牌相关编号 1008002000 ========== ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index 9cc398169..a7c954124 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -65,7 +65,7 @@ public class ProductBrandController { @GetMapping("/list-all-simple") @Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项") - public CommonResult> getSimpleUserList() { + public CommonResult> getSimpleBrandList() { // 获取品牌列表,只要开启状态的 List list = brandService.getBrandListByStatus(CommonStatusEnum.ENABLE.getStatus()); // 排序后,返回给前端 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java index e366864eb..3ff46484f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -14,8 +14,4 @@ public class ProductPropertyListReqVO { @Schema(description = "属性名称", example = "颜色") private String name; - // TODO @puhui999:这个查询条件的作用是啥呀? - @Schema(description = "属性编号的数组", example = "1,2") - private List propertyIds; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index 96cd7e41b..abb93c911 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 75963e3e1..da05951ab 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.product.dal.mysql.sku; import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -70,4 +73,22 @@ public interface ProductSkuMapper extends BaseMapperX { return selectList(new QueryWrapper().apply("stock <= warn_stock")); } + /** + * 更新 sku 属性值时使用的分页查询 + * + * @param pageParam 页面参数 + * @return {@link PageResult}<{@link ProductSkuDO}> + */ + default PageResult selectPage(PageParam pageParam) { + return selectPage(pageParam, new LambdaQueryWrapper().isNotNull(ProductSkuDO::getProperties)); + } + + /** + * 查询 sku properties 不等于 null 的数量 + * + * @return {@link Long} + */ + default Long selectCountByPropertyNotNull() { + return selectCount(new LambdaQueryWrapper().isNotNull(ProductSkuDO::getProperties)); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 47e395424..29133219f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -7,7 +7,8 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; -import cn.iocoder.yudao.module.product.enums.ProductConstants; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -30,6 +31,9 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @Resource private ProductCategoryMapper productCategoryMapper; + @Resource + @Lazy // 循环依赖,避免报错 + private ProductSpuService productSpuService; @Override public Long createCategory(ProductCategoryCreateReqVO createReqVO) { @@ -63,7 +67,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { if (productCategoryMapper.selectCountByParentId(id) > 0) { throw exception(CATEGORY_EXISTS_CHILDREN); } - // TODO 芋艿 补充只有不存在商品才可以删除 + // 校验分类是否绑定了 SPU + validateProductCategoryIsHaveBindSpu(id); // 删除 productCategoryMapper.deleteById(id); } @@ -91,6 +96,13 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } } + private void validateProductCategoryIsHaveBindSpu(Long id) { + Long count = productSpuService.getSpuCountByCategoryId(id); + if (0 != count) { + throw exception(CATEGORY_HAVE_BIND_SPU); + } + } + @Override public ProductCategoryDO getCategory(Long id) { return productCategoryMapper.selectById(id); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index d33d4df15..6c3ec8938 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.Pro import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyMapper; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,6 +39,9 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Lazy // 延迟加载,解决循环依赖问题 private ProductPropertyValueService productPropertyValueService; + @Resource + private ProductSkuService productSkuService; + @Override @Transactional(rollbackFor = Exception.class) public Long createProperty(ProductPropertyCreateReqVO createReqVO) { @@ -68,7 +72,8 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { // 更新 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); productPropertyMapper.updateById(updateObj); - // TODO 芋艿:更新时,需要看看 sku 表 + // TODO 芋艿:更新时,需要看看 sku 表 fix + productSkuService.updateSkuProperty(updateObj); } @Override @@ -94,10 +99,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Override public List getPropertyList(ProductPropertyListReqVO listReqVO) { - // 增加使用属性 id 查询 - if (CollUtil.isNotEmpty(listReqVO.getPropertyIds())){ - return productPropertyMapper.selectBatchIds(listReqVO.getPropertyIds()); - } return productPropertyMapper.selectList(listReqVO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index 231b79b68..f76f8f493 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -40,6 +41,10 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ @Lazy // 延迟加载,避免循环依赖 private ProductPropertyService productPropertyService; + @Resource + @Lazy // 延迟加载,避免循环依赖 + private ProductSkuService productSkuService; + @Override public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { // 如果已经添加过该属性值,直接返回 @@ -68,7 +73,8 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ // 更新 ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); productPropertyValueMapper.updateById(updateObj); - // TODO 芋艿:更新时,需要看看 sku 表 + // TODO 芋艿:更新时,需要看看 sku 表 fix + productSkuService.updateSkuPropertyValue(updateObj); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index 8438db684..a46c4fd30 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import org.springframework.lang.Nullable; @@ -115,4 +117,19 @@ public interface ProductSkuService { */ List getSkuListByAlarmStock(); + /** + * 更新 sku 属性 + * + * @param updateObj 属性对象 + * @return int 影响的行数 + */ + int updateSkuProperty(ProductPropertyDO updateObj); + + /** + * 更新 sku 属性值 + * + * @param updateObj 属性值对象 + * @return int 影响的行数 + */ + int updateSkuPropertyValue(ProductPropertyValueDO updateObj); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 1bb129876..ee8266467 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; @@ -42,6 +44,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Lazy // 循环依赖,避免报错 private ProductSpuService productSpuService; @Resource + @Lazy // 循环依赖,避免报错 private ProductPropertyService productPropertyService; @Resource private ProductPropertyValueService productPropertyValueService; @@ -157,6 +160,84 @@ public class ProductSkuServiceImpl implements ProductSkuService { return productSkuMapper.selectListByAlarmStock(); } + @Override + public int updateSkuProperty(ProductPropertyDO updateObj) { + // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 + Long count = productSkuMapper.selectCountByPropertyNotNull(); + int currentPage = 1; + List skuDOs = new ArrayList<>(); + if (count == 0) { + return 0; + } + int pageSize = 100; + for (int i = 0; i <= count / 100; i++) { + PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize); + // 分页查找出 sku 属性不为 null 的 + PageResult skuPage = productSkuMapper.selectPage(pageParam); + List records = skuPage.getList(); + if (CollUtil.isEmpty(records)) { + break; + } + records.stream() + .filter(sku -> sku.getProperties() != null) + .forEach(sku -> sku.getProperties().forEach(property -> { + if (property.getPropertyId().equals(updateObj.getId())) { + property.setPropertyName(updateObj.getName()); + skuDOs.add(sku); + } + })); + } + if (CollUtil.isEmpty(skuDOs)) { + return 0; + } + // 每批处理的大小 + int batchSize = 1000; + for (int i = 0; i < skuDOs.size(); i += batchSize) { + List batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size())); + productSkuMapper.updateBatch(batchSkuDOs, batchSize); + } + return skuDOs.size(); + } + + @Override + public int updateSkuPropertyValue(ProductPropertyValueDO updateObj) { + // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 + Long count = productSkuMapper.selectCountByPropertyNotNull(); + int currentPage = 1; + List skuDOs = new ArrayList<>(); + if (count == 0) { + return 0; + } + int pageSize = 100; + for (int i = 0; i <= count / 100; i++) { + PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize); + // 分页查找出 sku 属性不为 null 的 + PageResult skuPage = productSkuMapper.selectPage(pageParam); + List records = skuPage.getList(); + if (CollUtil.isEmpty(records)) { + break; + } + records.stream() + .filter(sku -> sku.getProperties() != null) + .forEach(sku -> sku.getProperties().forEach(property -> { + if (property.getValueId().equals(updateObj.getId())) { + property.setValueName(updateObj.getName()); + skuDOs.add(sku); + } + })); + } + if (CollUtil.isEmpty(skuDOs)) { + return 0; + } + // 每批处理的大小 + int batchSize = 1000; + for (int i = 0; i < skuDOs.size(); i += batchSize) { + List batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size())); + productSkuMapper.updateBatch(batchSkuDOs, batchSize); + } + return skuDOs.size(); + } + @Override @Transactional(rollbackFor = Exception.class) public void updateSkuList(Long spuId, List skus) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index a5dc3b821..5eeca1adb 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -126,4 +126,13 @@ public interface ProductSpuService { * @return {@link Map}<{@link Integer}, {@link Integer}> */ Map getTabsCount(); + + /** + * 通过分类 id 查询 spu 个数 + * + * @param id 分类 id + * @return spu + */ + Long getSpuCountByCategoryId(Long id); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 4adc08e18..ed40a281b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -251,4 +251,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { return counts; } + @Override + public Long getSpuCountByCategoryId(Long id) { + return productSpuMapper.selectCount(ProductSpuDO::getCategoryId, id); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java index 9c4d6601d..9df947b43 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -49,13 +49,10 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { @MockBean private ProductPropertyValueService productPropertyValueService; - // TODO @puhui999:是不是可以删除这 2 方法 public Long generateId() { return RandomUtil.randomLong(100000, 999999); } - public int generaInt(){return RandomUtil.randomInt(1,9999999);} - @Test public void testUpdateSkuList() { // mock 数据 @@ -109,7 +106,14 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(10))); // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> { + o.setId(1L).setSpuId(10L).setStock(20); + o.getProperties().forEach(p -> { + // 指定 id 范围 解决 Value too long + p.setPropertyId(generateId()); + p.setValueId(generateId()); + }); + })); // 调用 productSkuService.updateSkuStock(updateStockReqDTO); @@ -129,7 +133,14 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-10))); // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> { + o.setId(1L).setSpuId(10L).setStock(20); + o.getProperties().forEach(p -> { + // 指定 id 范围 解决 Value too long + p.setPropertyId(generateId()); + p.setValueId(generateId()); + }); + })); // 调用 productSkuService.updateSkuStock(updateStockReqDTO); @@ -149,8 +160,14 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-30))); // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); - + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> { + o.setId(1L).setSpuId(10L).setStock(20); + o.getProperties().forEach(p -> { + // 指定 id 范围 解决 Value too long + p.setPropertyId(generateId()); + p.setValueId(generateId()); + }); + })); // 调用并断言 AssertUtils.assertServiceException(() -> productSkuService.updateSkuStock(updateStockReqDTO), SKU_STOCK_NOT_ENOUGH); @@ -158,9 +175,16 @@ public class ProductSkuServiceTest extends BaseDbUnitTest { @Test public void testDeleteSku_success() { + ProductSkuDO dbSku = randomPojo(ProductSkuDO.class, o -> { + o.setId(generateId()).setSpuId(generateId()); + o.getProperties().forEach(p -> { + // 指定 id 范围 解决 Value too long + p.setPropertyId(generateId()); + p.setValueId(generateId()); + }); + }); // mock 数据 - ProductSkuDO dbSku = randomPojo(ProductSkuDO.class); - productSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据 + productSkuMapper.insert(dbSku); // 准备参数 Long id = dbSku.getId(); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 30f6c293b..e57540292 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -455,7 +455,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { public void testUpdateSpuStock() { // 准备参数 Map stockIncrCounts = MapUtil.builder(1L, 10).put(2L, -20).build(); - // mock 方法(数据) // TODO ProductSpuDO中已没有相关属性 + // mock 方法(数据) productSpuMapper.insert(randomPojo(ProductSpuDO.class, o ->{ o.setCategoryId(generateId()); o.setBrandId(generateId()); @@ -495,7 +495,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { // 调用 productSpuService.updateSpuStock(stockIncrCounts); - // 断言 // TODO ProductSpuDO中已没有相关属性 + // 断言 assertEquals(productSpuService.getSpu(1L).getStock(), 30); assertEquals(productSpuService.getSpu(2L).getStock(), 10); } From 2a9a869e01083b87efcdea0135823f02db4f38e9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 00:46:56 +0800 Subject: [PATCH 072/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E8=8E=B7?= =?UTF-8?q?=E5=BE=97=E8=AE=A2=E5=8D=95=E7=BB=93=E7=AE=97=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=8C=E6=8E=A5=E5=85=A5=E6=94=AF=E4=BB=98=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/sku/dto/ProductSkuRespDTO.java | 29 +------ .../app/spu/vo/AppProductSpuDetailRespVO.java | 3 + .../service/price/PriceServiceTest.java | 5 -- .../app/order/AppTradeOrderController.http | 9 ++- .../app/order/AppTradeOrderController.java | 76 +----------------- .../vo/AppTradeOrderSettlementReqVO.java | 45 ++++++++++- .../vo/AppTradeOrderSettlementRespVO.java | 6 +- .../convert/order/TradeOrderConvert.java | 49 +++++++++++- .../trade/dal/mysql/cart/TradeCartMapper.java | 7 ++ .../trade/service/cart/TradeCartService.java | 12 +++ .../service/cart/TradeCartServiceImpl.java | 13 ++- .../service/order/TradeOrderServiceImpl.java | 79 +++++++++++++------ .../service/price/TradePriceService.java | 4 +- .../service/price/TradePriceServiceImpl.java | 38 +++++++-- .../price/bo/TradePriceCalculateReqBO.java | 2 +- .../price/bo/TradePriceCalculateRespBO.java | 30 +++++-- .../TradePriceCalculatorHelper.java | 48 +++++++---- .../aftersale/TradeAfterSaleServiceTest.java | 2 +- .../module/member/api/address/AddressApi.java | 8 ++ .../api/address/dto/AddressRespDTO.java | 2 +- .../member/api/address/AddressApiImpl.java | 5 ++ 21 files changed, 292 insertions(+), 180 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index 7f5e7aed8..1875518c3 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.api.sku.dto; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import lombok.Data; import java.util.List; @@ -25,7 +26,7 @@ public class ProductSkuRespDTO { /** * 属性数组 */ - private List properties; + private List properties; /** * 销售价格,单位:分 */ @@ -63,30 +64,4 @@ public class ProductSkuRespDTO { */ private Double volume; - /** - * 商品属性 - */ - @Data - public static class Property { - - /** - * 属性编号 - */ - private Long propertyId; - /** - * 属性名字 - */ - private String propertyName; - - /** - * 属性值编号 - */ - private Long valueId; - /** - * 属性值名字 - */ - private String valueName; - - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index 6992d83b7..41e36fb98 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -18,6 +18,9 @@ public class AppProductSpuDetailRespVO { @Schema(description = "商品名称", required = true, example = "芋道") private String name; + @Schema(description = "商品简介", required = true, example = "我是一个快乐简介") + private String introduction; + @Schema(description = "商品详情", required = true, example = "我是商品描述") private String description; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 929727077..ef2d57631 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -93,7 +93,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertNull(promotion.getId()); assertEquals(promotion.getName(), "会员折扣"); assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); - assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getDiscountPrice(), 20); assertTrue(promotion.getMatch()); @@ -264,7 +263,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMatch()); @@ -283,7 +281,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion02.getId(), 2000L); assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getDiscountPrice(), 60); assertTrue(promotion02.getMatch()); @@ -352,7 +349,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 0); assertFalse(promotion01.getMatch()); @@ -434,7 +430,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotion01.getId(), 1024L); assertEquals(promotion01.getName(), "程序员节"); assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getDiscountPrice(), 70); assertTrue(promotion01.getMatch()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http index 8a3ed4867..8d2af766f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -1,5 +1,10 @@ -### /trade-order/settlement 获得订单结算信息 -GET {{appApi}}/trade/order/settlement?cartIds=1 +### /trade-order/settlement 获得订单结算信息(基于商品) +GET {{appApi}}/trade/order/settlement?type=0&items[0].skuId=1&items[0].count=2&items[1].skuId=2&items[1].count=3&couponId=1 +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + +### /trade-order/settlement 获得订单结算信息(基于购物车) +GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 738741f6e..a6eb579a5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -53,78 +51,8 @@ public class AppTradeOrderController { @GetMapping("/settlement") @Operation(summary = "获得订单结算信息") @PreAuthenticated - public CommonResult settlementOrder( - @Valid AppTradeOrderSettlementReqVO settlementReqVO) { - if (true) { - return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO)); - } -// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); - AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO(); - - AppTradeOrderSettlementRespVO.Price price = new AppTradeOrderSettlementRespVO.Price(); - price.setTotalPrice(1000); - price.setDeliveryPrice(200); - price.setCouponPrice(100); - price.setPointPrice(50); - price.setPayPrice(950); - - List skus = new ArrayList<>(); - - AppTradeOrderSettlementRespVO.Item item1 = new AppTradeOrderSettlementRespVO.Item(); - item1.setCartId(1L); - item1.setSpuId(2048L); - item1.setSpuName("Apple iPhone 12"); - item1.setSkuId(1024); - item1.setPrice(500); - item1.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); - item1.setCount(2); - List properties1 = new ArrayList<>(); - AppProductPropertyValueDetailRespVO property1 = new AppProductPropertyValueDetailRespVO(); - property1.setPropertyId(1L); - property1.setPropertyName("尺寸"); - property1.setValueId(2L); - property1.setValueName("大"); - properties1.add(property1); - item1.setProperties(properties1); - - AppTradeOrderSettlementRespVO.Item item2 = new AppTradeOrderSettlementRespVO.Item(); - item2.setCartId(2L); - item2.setSpuId(3072L); - item2.setSpuName("Samsung Galaxy S21"); - item2.setSkuId(2048); - item2.setPrice(800); - item2.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); - item2.setCount(1); - List properties2 = new ArrayList<>(); - AppProductPropertyValueDetailRespVO property2 = new AppProductPropertyValueDetailRespVO(); - property2.setPropertyId(10L); - property2.setPropertyName("颜色"); - property2.setValueId(20L); - property2.setValueName("白色"); - properties2.add(property2); - item2.setProperties(properties2); - - skus.add(item1); - skus.add(item2); - - settlement.setItems(skus); - settlement.setPrice(price); - - AppTradeOrderSettlementRespVO.Address address = new AppTradeOrderSettlementRespVO.Address(); - address.setId(1L); - address.setName("John"); - address.setMobile("18888888888"); - address.setProvinceId(1L); - address.setProvinceName("Beijing"); - address.setCityId(1L); - address.setCityName("Beijing"); - address.setDistrictId(1L); - address.setDistrictName("Chaoyang Distripct"); - address.setDetailAddress("No. 10, Xinzhong Street, Chaoyang District"); - address.setDefaulted(true); - settlement.setAddress(address); - - return success(settlement); + public CommonResult settlementOrder(@Valid AppTradeOrderSettlementReqVO settlementReqVO) { + return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO)); } @PostMapping("/create") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index 973db183e..0324b492b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -1,23 +1,60 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotEmpty; +import javax.validation.Valid; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import java.util.List; @Schema(description = "用户 App - 交易订单结算 Request VO") @Data public class AppTradeOrderSettlementReqVO { + @NotNull(message = "交易类型不能为空") + @InEnum(value = TradeOrderTypeEnum.class, message = "交易类型必须是 {value}") + private Integer type; + + @Schema(description = "商品项数组", required = true) + @NotNull(message = "商品不能为空") + private List items; + @Schema(description = "收件地址编号", example = "1") private Long addressId; @Schema(description = "优惠劵编号", example = "1024") private Long couponId; - @Schema(description = "购物车项的编号数组", required = true, example = "true") - @NotEmpty(message = "购物车项不能为空") - private List cartIds; + @Data + @Schema(description = "用户 App - 商品项") + @Valid + public static class Item { + + @Schema(description = "商品 SKU 编号", example = "2048") + private Long skuId; + @Schema(description = "购买数量", example = "1") + @Min(value = 1, message = "购买数量最小值为 {value}") + private Integer count; + + @Schema(description = "购物车项的编号", example = "1024") + private Long cartId; + + @AssertTrue(message = "商品不正确") + @JsonIgnore + public boolean isValid() { + // 组合一:skuId + count 使用商品 SKU + if (skuId != null && count != null) { + return true; + } + // 组合二:cartId 使用购物车项 + return cartId != null; + } + + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java index b2d4e4108..aaa059ef1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java @@ -91,17 +91,17 @@ public class AppTradeOrderSettlementRespVO { private String mobile; @Schema(description = "省份编号", required = true, example = "1") - private Long provinceId; + private Integer provinceId; @Schema(description = "省份名字", required = true, example = "北京") private String provinceName; @Schema(description = "城市编号", required = true, example = "1") - private Long cityId; + private Integer cityId; @Schema(description = "城市名字", required = true, example = "北京") private String cityName; @Schema(description = "地区编号", required = true, example = "1") - private Long districtId; + private Integer districtId; @Schema(description = "地区名字", required = true, example = "朝阳区") private String districtName; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 38860943c..3ea449f6c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.convert.order; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; @@ -18,14 +19,15 @@ import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.Prod import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -241,4 +243,45 @@ public interface TradeOrderConvert { AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); + default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, + List cartList) { + TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); + reqBO.setUserId(userId).setType(settlementReqVO.getType()) + .setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) + .setItems(new ArrayList<>(settlementReqVO.getItems().size())); + // 商品项的构建 + Map cartMap = convertMap(cartList, TradeCartDO::getId); + for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { + // 情况一:skuId + count + if (item.getSkuId() != null) { + reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(item.getSkuId()).setCount(item.getCount()) + .setSelected(true)); // true 的原因,下单一定选中 + continue; + } + // 情况二:cartId + TradeCartDO cart = cartMap.get(item.getCartId()); + if (cart == null) { + continue; + } + reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(cart.getSkuId()).setCount(cart.getCount()) + .setCartId(item.getCartId()).setSelected(true)); // true 的原因,下单一定选中 + } + return reqBO; + } + + default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, AddressRespDTO address) { + AppTradeOrderSettlementRespVO respVO = convert0(calculate, address); + if (address != null) { + Area area = AreaUtils.getArea(address.getAreaId()); + respVO.getAddress().setDistrictId(area.getId()); + respVO.getAddress().setDistrictName(area.getName()); + respVO.getAddress().setCityId(area.getParent().getId()); + respVO.getAddress().setCityName(area.getParent().getName()); + respVO.getAddress().setProvinceId(area.getParent().getParent().getId()); + respVO.getAddress().setProvinceName(area.getParent().getParent().getName()); + } + return respVO; + } + AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java index 564a4f0bc..b4727117e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; @Mapper public interface TradeCartMapper extends BaseMapperX { @@ -70,4 +71,10 @@ public interface TradeCartMapper extends BaseMapperX { update(updateObject, new LambdaQueryWrapper().in(TradeCartDO::getId, ids)); } + default List selectListByUserId(Long userId, Set ids) { + return selectList(new LambdaQueryWrapper() + .eq(TradeCartDO::getUserId, userId) + .in(TradeCartDO::getId, ids)); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java index 9a009860d..93152a633 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java @@ -4,10 +4,13 @@ import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import javax.validation.Valid; import java.util.Collection; +import java.util.List; import java.util.Map; +import java.util.Set; /** * 购物车 Service 接口 @@ -67,6 +70,15 @@ public interface TradeCartService { */ AppTradeCartListRespVO getCartList(Long userId); + /** + * 查询用户的购物车列表 + * + * @param userId 用户编号 + * @param ids 购物项的编号 + * @return 购物车列表 + */ + List getCartList(Long userId, Set ids); + /** * 获得用户的购物车商品 SPU 数量的 Map * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index c6fb3e0ec..6696de319 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -17,10 +17,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -166,6 +163,14 @@ public class TradeCartServiceImpl implements TradeCartService { return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); } + @Override + public List getCartList(Long userId, Set ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + return cartMapper.selectListByUserId(userId, ids); + } + private void deleteCartIfSpuDeleted(List carts, List spus) { // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 carts.removeIf(cart -> { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index c4760b4b1..f60b95899 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -34,6 +34,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageRe import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; @@ -41,6 +42,10 @@ import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; +import cn.iocoder.yudao.module.trade.service.price.TradePriceService; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -50,8 +55,7 @@ import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; @@ -70,6 +74,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { @Resource private TradeOrderItemMapper tradeOrderItemMapper; + @Resource + private TradeCartService tradeCartService; + @Resource + private TradePriceService tradePriceService; + @Resource private PriceApi priceApi; @Resource @@ -92,7 +101,48 @@ public class TradeOrderServiceImpl implements TradeOrderService { @Override public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { - return null; + // 1. 获得收货地址 + AddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId()); + if (address != null) { + settlementReqVO.setAddressId(address.getId()); + } + + // 2. 计算价格 + TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, settlementReqVO); + + // 3. 拼接返回 + return TradeOrderConvert.INSTANCE.convert(calculateRespBO, address); + } + + /** + * 获得用户地址 + * + * @param userId 用户编号 + * @param addressId 地址编号 + * @return 地址 + */ + private AddressRespDTO getAddress(Long userId, Long addressId) { + if (addressId != null) { + return addressApi.getAddress(addressId, userId); + } + return addressApi.getDefaultAddress(userId); + } + + /** + * 计算订单价格 + * + * @param userId 用户编号 + * @param settlementReqVO 结算信息 + * @return 订单价格 + */ + private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { + // 1. 如果来自购物车,则获得购物车的商品 + List cartList = tradeCartService.getCartList(userId, + convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId)); + + // 2. 计算价格 + TradePriceCalculateReqBO calculateReqBO = TradeOrderConvert.INSTANCE.convert(userId, settlementReqVO, cartList); + return tradePriceService.calculatePrice(calculateReqBO); } @Override @@ -120,29 +170,6 @@ public class TradeOrderServiceImpl implements TradeOrderService { return tradeOrderDO.getId(); } -// /** -// * 校验商品 SKU 是否可出售 -// * -// * @param items 商品 SKU -// * @return 商品 SKU 数组 -// */ -// private List validateSkuSaleable(List items) { -// List skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); -// // SKU 不存在 -// if (items.size() != skus.size()) { -// throw exception(ORDER_CREATE_SKU_NOT_FOUND); -// } -// // 校验库存不足 -// Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); -// items.forEach(item -> { -// ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); -// if (item.getCount() > sku.getStock()) { -// throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); -// } -// }); -// return skus; -// } - /** * 校验商品 SPU 是否可出售 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java index 2dd0c41ca..d12451b22 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.price; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import javax.validation.Valid; + /** * 价格计算 Service 接口 * @@ -16,6 +18,6 @@ public interface TradePriceService { * @param calculateReqDTO 计算信息 * @return 计算结果 */ - TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqDTO); + TradePriceCalculateRespBO calculatePrice(@Valid TradePriceCalculateReqBO calculateReqDTO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java index f0ebce5ba..0e9dc32c2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java @@ -2,12 +2,16 @@ package cn.iocoder.yudao.module.trade.service.price; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.List; @@ -15,8 +19,8 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; /** @@ -25,22 +29,28 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_C * @author 芋道源码 */ @Service +@Validated @Slf4j public class TradePriceServiceImpl implements TradePriceService { @Resource private ProductSkuApi productSkuApi; + @Resource + private ProductSpuApi productSpuApi; + @Resource private List priceCalculators; @Override public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) { - // 1. 获得商品 SKU 数组 - List skuList = checkSkus(calculateReqBO); + // 1.1 获得商品 SKU 数组 + List skuList = checkSkuList(calculateReqBO); + // 1.2 获得商品 SPU 数组 + List spuList = checkSpuList(skuList); // 2.1 计算价格 TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper - .buildCalculateResp(calculateReqBO, skuList); + .buildCalculateResp(calculateReqBO, spuList, skuList); priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 if (calculateRespBO.getPrice().getPayPrice() <= 0) { @@ -51,7 +61,7 @@ public class TradePriceServiceImpl implements TradePriceService { return calculateRespBO; } - private List checkSkus(TradePriceCalculateReqBO reqBO) { + private List checkSkuList(TradePriceCalculateReqBO reqBO) { // 获得商品 SKU 数组 Map skuIdCountMap = convertMap(reqBO.getItems(), TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount); @@ -70,4 +80,20 @@ public class TradePriceServiceImpl implements TradePriceService { return skus; } + private List checkSpuList(List skuList) { + // 获得商品 SPU 数组 + List spus = productSpuApi.getSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId)); + + // 校验商品 SPU + spus.forEach(spu -> { + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { + throw exception(SPU_NOT_ENABLE); + } + }); + return spus; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index 2a014c0e0..931940793 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -21,7 +21,7 @@ public class TradePriceCalculateReqBO { * * 枚举 {@link TradeOrderTypeEnum} */ - private Integer orderType; + private Integer type; /** * 用户编号 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index 1c347a532..fb006b44b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.service.price.bo; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; @@ -23,7 +24,7 @@ public class TradePriceCalculateRespBO { * * 枚举 {@link TradeOrderTypeEnum} */ - private Integer orderType; + private Integer type; /** * 订单价格 @@ -163,7 +164,26 @@ public class TradePriceCalculateRespBO { */ private Integer payPrice; - // TODO 芋艿:这里补充下基本信息,简单一点。 + // ========== 商品信息 ========== + /** + * 商品名 + */ + private String spuName; + /** + * 商品图片 + * + * 优先级:SKU.picUrl > SPU.picUrl + */ + private String picUrl; + /** + * 分类编号 + */ + private Long categoryId; + + /** + * 商品属性数组 + */ + private List properties; } @@ -189,12 +209,6 @@ public class TradePriceCalculateRespBO { * 枚举 {@link PromotionTypeEnum} */ private Integer type; - /** - * 营销级别 - * - * 枚举 {@link PromotionLevelEnum} - */ - private Integer level; /** * 计算时的原价(总),单位:分 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index 9ed94b692..47a73c0d8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; @@ -14,6 +15,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static java.util.Collections.singletonList; +// TODO 芋艿:改成父类 + /** * {@link TradePriceCalculator} 的工具类 * @@ -24,25 +27,42 @@ import static java.util.Collections.singletonList; public class TradePriceCalculatorHelper { public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, - List skuList) { + List spuList, List skuList) { // 创建 PriceCalculateRespDTO 对象 TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); - result.setOrderType(param.getOrderType()); + result.setType(param.getType()); + result.setPromotions(new ArrayList<>()); + // 创建它的 OrderItem 属性 - Map skuItemMap = convertMap(param.getItems(), - TradePriceCalculateReqBO.Item::getSkuId); - result.setItems(new ArrayList<>(skuItemMap.size())); - skuList.forEach(sku -> { - TradePriceCalculateReqBO.Item skuItem = skuItemMap.get(sku.getId()); - TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem() - // SKU 字段 - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()) - .setCount(skuItem.getCount()).setCartId(skuItem.getCartId()).setSelected(skuItem.getSelected()) - // 价格字段 - .setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * skuItem.getCount()) - .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); + result.setItems(new ArrayList<>(param.getItems().size())); + Map spuMap = convertMap(spuList, ProductSpuRespDTO::getId); + Map skuMap = convertMap(skuList, ProductSkuRespDTO::getId); + param.getItems().forEach(item -> { + ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); + if (sku == null) { + return; + } + ProductSpuRespDTO spu = spuMap.get(sku.getSpuId()); + if (spu == null) { + return; + } + // 商品项 + TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem(); result.getItems().add(orderItem); + orderItem.setSpuId(sku.getSpuId()).setSkuId(sku.getId()) + .setCount(item.getCount()).setCartId(item.getCartId()).setSelected(item.getSelected()); + // sku 价格 + orderItem.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * item.getCount()) + .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); + // sku 信息 + orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()); + // spu 信息 + orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()); + if (orderItem.getPicUrl() == null) { + orderItem.setPicUrl(spu.getPicUrl()); + } }); + // 创建它的 Price 属性 result.setPrice(new TradePriceCalculateRespBO.Price()); recountAllPrice(result); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java index f628cef4a..0602c6649 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java @@ -69,7 +69,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest { .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); // mock 方法(交易订单项) TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { - o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); + o.setOrderId(111L).setUserId(userId).setPayPrice(200); o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); }); when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java index 75ba02563..658748819 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java @@ -18,4 +18,12 @@ public interface AddressApi { */ AddressRespDTO getAddress(Long id, Long userId); + /** + * 获得用户默认收件地址 + * + * @param userId 用户编号 + * @return 用户收件地址 + */ + AddressRespDTO getDefaultAddress(Long userId); + } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java index cc8eb4701..3fbb70f80 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java @@ -29,7 +29,7 @@ public class AddressRespDTO { /** * 地区编号 */ - private Long areaId; + private Integer areaId; /** * 邮编 */ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java index fd0f4843d..b8088a455 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java @@ -25,4 +25,9 @@ public class AddressApiImpl implements AddressApi { return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); } + @Override + public AddressRespDTO getDefaultAddress(Long userId) { + return AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId)); + } + } From 636b14cccec2b8f5d30db81e18817d23c31aaf73 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 09:14:51 +0800 Subject: [PATCH 073/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=AE=A2=E5=8D=95=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E6=96=B0=E7=9A=84=E4=BB=B7=E6=A0=BC=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/order/AppTradeOrderController.http | 17 +-- .../app/order/AppTradeOrderController.java | 14 +-- .../order/vo/AppTradeOrderCreateReqVO.java | 19 +-- .../convert/order/TradeOrderConvert.java | 55 ++++---- .../dataobject/order/TradeOrderItemDO.java | 13 ++ .../service/order/TradeOrderServiceImpl.java | 118 +++++++----------- 6 files changed, 96 insertions(+), 140 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http index 8d2af766f..1a11d4eed 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -8,27 +8,22 @@ GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} -### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单 -GET {{shop-api-base-url}}/trade-order/confirm-create-order-info-from-cart -Content-Type: application/x-www-form-urlencoded -Authorization: Bearer {{user-access-token}} - -### /trade-order/create 基于商品,创建订单 +### /trade-order/create 创建订单(基于商品) POST {{appApi}}/trade/order/create Content-Type: application/json Authorization: Bearer {{appToken}} tenant-id: {{appTenentId}} { + "type": 0, "addressId": 21, - "remark": "我是备注", - "fromCart": false, "items": [ { - "skuId": 29, - "count": 1 + "skuId": 1, + "count": 2 } - ] + ], + "remark": "我是备注" } ### 获得订单交易的分页 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index a6eb579a5..e3008fdd6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -22,7 +22,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.HashMap; import java.util.List; @@ -30,6 +29,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 交易订单") @@ -58,15 +58,9 @@ public class AppTradeOrderController { @PostMapping("/create") @Operation(summary = "创建订单") @PreAuthenticated - public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, - HttpServletRequest servletRequest) { - return success(1L); -// // 获取登录用户、用户 IP 地址 -// Long loginUserId = getLoginUserId(); -// String clientIp = ServletUtils.getClientIP(servletRequest); -// // 创建交易订单,预支付记录 -// Long orderId = tradeOrderService.createOrder(loginUserId, clientIp, createReqVO); -// return success(orderId); + public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) { + Long orderId = tradeOrderService.createOrder(getLoginUserId(), getClientIP(), createReqVO); + return success(orderId); } @PostMapping("/update-paid") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java index 26c48954c..11031a884 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -3,26 +3,9 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - @Schema(description = "用户 App - 交易订单创建 Request VO") @Data -public class AppTradeOrderCreateReqVO { - - @Schema(description = "收件地址编号", required = true, example = "1") - @NotNull(message = "收件地址不能为空") - private Long addressId; - - @Schema(description = "优惠劵编号", example = "1024") - private Long couponId; - - @Schema(description = "购物车项的编号数组", required = true, example = "true") - @NotEmpty(message = "购物车项不能为空") - private List cartIds; - - // ========== 非 AppTradeOrderSettlementReqVO 字段 ========== +public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { @Schema(description = "备注", example = "这个是我的订单哟") private String remark; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 3ea449f6c..c53ae4d0a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -9,11 +9,8 @@ import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; @@ -50,32 +47,32 @@ public interface TradeOrderConvert { @Mapping(source = "createReqVO.couponId", target = "couponId"), @Mapping(target = "remark", ignore = true), @Mapping(source = "createReqVO.remark", target = "userRemark"), + @Mapping(source = "createReqVO.type", target = "type"), + @Mapping(source = "calculateRespBO.price.totalPrice", target = "totalPrice"), + @Mapping(source = "calculateRespBO.price.discountPrice", target = "discountPrice"), + @Mapping(source = "calculateRespBO.price.deliveryPrice", target = "deliveryPrice"), + @Mapping(source = "calculateRespBO.price.couponPrice", target = "couponPrice"), + @Mapping(source = "calculateRespBO.price.pointPrice", target = "pointPrice"), + @Mapping(source = "calculateRespBO.price.payPrice", target = "payPrice"), @Mapping(source = "address.name", target = "receiverName"), @Mapping(source = "address.mobile", target = "receiverMobile"), @Mapping(source = "address.areaId", target = "receiverAreaId"), @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"), }) TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, - PriceCalculateRespDTO.Order order, AddressRespDTO address); + TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address); - @Mappings({ - @Mapping(target = "id", ignore = true), - @Mapping(source = "sku.spuId", target = "spuId"), - }) - TradeOrderItemDO convert(PriceCalculateRespDTO.OrderItem orderItem, ProductSkuRespDTO sku); - - default List convertList(TradeOrderDO tradeOrderDO, - List orderItems, List skus) { - Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); - return CollectionUtils.convertList(orderItems, orderItem -> { - TradeOrderItemDO tradeOrderItemDO = convert(orderItem, skuMap.get(orderItem.getSkuId())); - tradeOrderItemDO.setOrderId(tradeOrderDO.getId()); - tradeOrderItemDO.setUserId(tradeOrderDO.getUserId()); - tradeOrderItemDO.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); // 退款信息 -// tradeOrderItemDO.setCommented(false); - return tradeOrderItemDO; + default List convertList(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { + return CollectionUtils.convertList(calculateRespBO.getItems(), item -> { + TradeOrderItemDO orderItem = convert(item); + orderItem.setOrderId(tradeOrderDO.getId()); + orderItem.setUserId(tradeOrderDO.getUserId()); + orderItem.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); + orderItem.setCommentStatus(false); + return orderItem; }); } + TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); @Mapping(source = "userId" , target = "userId") PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId); @@ -87,19 +84,20 @@ public interface TradeOrderConvert { ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); List convertList(List list); - default PayOrderCreateReqDTO convert(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus, TradeOrderProperties tradeOrderProperties) { + default PayOrderCreateReqDTO convert(TradeOrderDO order, List orderItems, + TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() - .setAppId(tradeOrderProperties.getAppId()).setUserIp(tradeOrderDO.getUserIp()); + .setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp()); // 商户相关字段 - createReqDTO.setMerchantOrderId(String.valueOf(tradeOrderDO.getId())); - String subject = spus.get(0).getName(); - if (spus.size() > 1) { + createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); + String subject = calculateRespBO.getItems().get(0).getSpuName(); + if (calculateRespBO.getItems().size() > 1) { subject += " 等多件"; } createReqDTO.setSubject(subject); + createReqDTO.setBody(subject); // TODO 芋艿:临时写死 // 订单相关字段 - createReqDTO.setAmount(tradeOrderDO.getPayPrice()).setExpireTime(addTime(tradeOrderProperties.getExpireTime())); + createReqDTO.setAmount(order.getPayPrice()).setExpireTime(addTime(orderProperties.getExpireTime())); return createReqDTO; } @@ -113,6 +111,7 @@ public interface TradeOrderConvert { .collect(Collectors.toSet()); } + // TODO 芋艿:可简化 default PageResult convertPage(PageResult pageResult, List orderItems, List propertyValueDetails) { Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); @@ -149,6 +148,7 @@ public interface TradeOrderConvert { TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); + // TODO 芋艿:可简化 default TradeOrderDetailRespVO convert(TradeOrderDO order, List orderItems, List propertyValueDetails, MemberUserRespDTO user) { TradeOrderDetailRespVO orderVO = convert2(order, orderItems); @@ -179,6 +179,7 @@ public interface TradeOrderConvert { TradeOrderDetailRespVO convert2(TradeOrderDO order, List items); MemberUserRespVO convert(MemberUserRespDTO bean); + // TODO 芋艿:可简化 default PageResult convertPage02(PageResult pageResult, List orderItems, List propertyValueDetails) { Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index 323389c94..3f071ae2f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -166,12 +166,25 @@ public class TradeOrderItemDO extends BaseDO { * 关联 ProductPropertyDO 的 id 编号 */ private Long propertyId; + /** + * 属性名字 + * + * 关联 ProductPropertyDO 的 name 字段 + */ + private String propertyName; + /** * 属性值编号 * * 关联 ProductPropertyValueDO 的 id 编号 */ private Long valueId; + /** + * 属性值名字 + * + * 关联 ProductPropertyValueDO 的 name 字段 + */ + private String valueName; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index f60b95899..8e75dd985 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; @@ -18,15 +18,9 @@ import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; @@ -40,6 +34,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; @@ -55,7 +50,8 @@ import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; @@ -79,13 +75,9 @@ public class TradeOrderServiceImpl implements TradeOrderService { @Resource private TradePriceService tradePriceService; - @Resource - private PriceApi priceApi; @Resource private ProductSkuApi productSkuApi; @Resource - private ProductSpuApi productSpuApi; - @Resource private PayOrderApi payOrderApi; @Resource private AddressApi addressApi; @@ -142,53 +134,29 @@ public class TradeOrderServiceImpl implements TradeOrderService { // 2. 计算价格 TradePriceCalculateReqBO calculateReqBO = TradeOrderConvert.INSTANCE.convert(userId, settlementReqVO, cartList); + calculateReqBO.getItems().forEach(item -> Assert.isTrue(item.getSelected(), // 防御性编程,保证都是选中的 + "商品({}) 未设置为选中", item.getSkuId())); return tradePriceService.calculatePrice(calculateReqBO); } @Override @Transactional(rollbackFor = Exception.class) public Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { - // 商品 SKU 检查:可售状态、库存 -// List skus = validateSkuSaleable(createReqVO.getItems()); // TODO 芋艿,临时关闭。 - List skus = null; - // 商品 SPU 检查:可售状态 - List spus = validateSpuSaleable(convertSet(skus, ProductSkuRespDTO::getSpuId)); - // 用户收件地址的校验 + // 1. 用户收件地址的校验 AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId()); - // 价格计算 - PriceCalculateRespDTO priceResp = priceApi.calculatePrice(TradeOrderConvert.INSTANCE.convert(createReqVO, userId)); + // 2. 价格计算 + TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); - // 插入 TradeOrderDO 订单 - TradeOrderDO tradeOrderDO = createTradeOrder(userId, userIp, createReqVO, priceResp.getOrder(), address); - // 插入 TradeOrderItemDO 订单项 - List tradeOrderItems = createTradeOrderItems(tradeOrderDO, priceResp.getOrder().getItems(), skus); + // 3.1 插入 TradeOrderDO 订单 + TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO, address); + // 3.2 插入 TradeOrderItemDO 订单项 + List orderItems = createTradeOrderItems(order, calculateRespBO); // 订单创建完后的逻辑 - afterCreateTradeOrder(userId, createReqVO, tradeOrderDO, tradeOrderItems, spus); + afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! - return tradeOrderDO.getId(); - } - - /** - * 校验商品 SPU 是否可出售 - * - * @param spuIds 商品 SPU 编号数组 - * @return 商品 SPU 数组 - */ - private List validateSpuSaleable(Set spuIds) { - List spus = productSpuApi.getSpuList(spuIds); - // SPU 不存在 - if (spus.size() != spuIds.size()) { - throw exception(ORDER_CREATE_SPU_NOT_FOUND); - } - // 校验是否存在禁用的 SPU - ProductSpuRespDTO spu = CollectionUtils.findFirst(spus, - spuDTO -> ObjectUtil.notEqual(ProductSpuStatusEnum.ENABLE.getStatus(), spuDTO.getStatus())); - if (spu != null) { - throw exception(ErrorCodeConstants.ORDER_CREATE_SPU_NOT_SALE); - } - return spus; + return order.getId(); } /** @@ -200,33 +168,35 @@ public class TradeOrderServiceImpl implements TradeOrderService { */ private AddressRespDTO validateAddress(Long userId, Long addressId) { AddressRespDTO address = addressApi.getAddress(addressId, userId); - if (Objects.isNull(address)) { + if (address == null) { throw exception(ErrorCodeConstants.ORDER_CREATE_ADDRESS_NOT_FOUND); } return address; } private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, - PriceCalculateRespDTO.Order order, AddressRespDTO address) { - TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, order, address); - tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; - tradeOrderDO.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); - tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType()); - tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); - tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum)); - tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? - tradeOrderDO.setAdjustPrice(0).setPayed(false); // 支付信息 - tradeOrderDO.setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); // 物流信息 - tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 - tradeOrderMapper.insert(tradeOrderDO); - return tradeOrderDO; + TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address) { + TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address); + order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; + order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); + order.setType(TradeOrderTypeEnum.NORMAL.getType()); + order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); + order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); + order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? + // 支付信息 + order.setAdjustPrice(0).setPayed(false); + // 物流信息 TODO 芋艿:暂时写死物流方式;应该是前端选择的 + order.setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); + // 退款信息 + order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); + tradeOrderMapper.insert(order); + return order; } - private List createTradeOrderItems(TradeOrderDO tradeOrderDO, - List orderItems, List skus) { - List tradeOrderItemDOs = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, orderItems, skus); - tradeOrderItemMapper.insertBatch(tradeOrderItemDOs); - return tradeOrderItemDOs; + private List createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { + List orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); + tradeOrderItemMapper.insertBatch(orderItems); + return orderItems; } /** @@ -237,12 +207,13 @@ public class TradeOrderServiceImpl implements TradeOrderService { * @param userId 用户编号 * @param createReqVO 创建订单请求 * @param tradeOrderDO 交易订单 + * @param calculateRespBO 订单价格计算结果 */ private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, - TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus) { + TradeOrderDO tradeOrderDO, List orderItems, + TradePriceCalculateRespBO calculateRespBO) { // 下单时扣减商品库存 - productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOs))); + productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems))); // 删除购物车商品 TODO 芋艿:待实现 @@ -255,20 +226,19 @@ public class TradeOrderServiceImpl implements TradeOrderService { } // 生成预支付 - createPayOrder(tradeOrderDO, tradeOrderItemDOs, spus); + createPayOrder(tradeOrderDO, orderItems, calculateRespBO); // 增加订单日志 TODO 芋艿:待实现 } - private void createPayOrder(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus) { + private void createPayOrder(TradeOrderDO order, List orderItems, TradePriceCalculateRespBO calculateRespBO) { // 创建支付单,用于后续的支付 PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( - tradeOrderDO, tradeOrderItemDOs, spus, tradeOrderProperties); + order, orderItems, calculateRespBO, tradeOrderProperties); Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO); // 更新到交易单上 - tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayOrderId(payOrderId)); + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setPayOrderId(payOrderId)); } @Override From 1452f6b231bff6fd1977085de6762c59ef01d52d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 11:53:40 +0800 Subject: [PATCH 074/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E8=82=8C=E7=88=B1=20TradeCouponPriceCalculator=20=E7=9A=84?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/sku/dto/ProductSkuRespDTO.java | 4 - .../api/price/dto/PriceCalculateReqDTO.java | 1 + .../service/price/PriceServiceTest.java | 129 ---------------- .../TradeCouponPriceCalculator.java | 3 +- .../TradePriceCalculatorHelper.java | 29 +++- .../TradeRewardActivityPriceCalculator.java | 3 + .../service/order/TradeOrderServiceTest.java | 7 +- .../price/TradePriceServiceImplTest.java | 135 +++++++++++++++++ .../TradeCouponPriceCalculatorTest.java | 143 ++++++++++++++++++ 9 files changed, 314 insertions(+), 140 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index 1875518c3..20f84f87c 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -51,10 +51,6 @@ public class ProductSkuRespDTO { * 库存 */ private Integer stock; - /** - * 预警预存 - */ - private Integer warnStock; /** * 商品重量,单位:kg 千克 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java index ce53de50e..4c43ffa81 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java @@ -12,6 +12,7 @@ import java.util.List; * @author 芋道源码 */ @Data +@Deprecated public class PriceCalculateReqDTO { /** diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index ef2d57631..79690000a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -56,54 +56,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { @Mock private ProductSkuApi productSkuApi; - @Test - public void testCalculatePrice_memberDiscount() { - // 准备参数 - // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getTotalPrice(), 200); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 180); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 1); - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); - assertEquals(orderItem.getSkuId(), 10L); - assertEquals(orderItem.getCount(), 2); - assertEquals(orderItem.getOriginalPrice(), 200); - assertEquals(orderItem.getOriginalUnitPrice(), 100); - assertEquals(orderItem.getDiscountPrice(), 20); - assertEquals(orderItem.getPayPrice(), 180); - assertEquals(orderItem.getOrderPartPrice(), 0); - assertEquals(orderItem.getOrderDividePrice(), 180); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); - assertNull(promotion.getId()); - assertEquals(promotion.getName(), "会员折扣"); - assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); - assertEquals(promotion.getTotalPrice(), 200); - assertEquals(promotion.getDiscountPrice(), 20); - assertTrue(promotion.getMatch()); - assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元"); - PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); - assertEquals(promotion.getItems().size(), 1); - assertEquals(promotionItem.getSkuId(), 10L); - assertEquals(promotionItem.getOriginalPrice(), 200); - assertEquals(promotionItem.getDiscountPrice(), 20); - } - @Test public void testCalculatePrice_discountActivity() { // 准备参数 @@ -364,87 +316,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { assertEquals(promotionItem012.getDiscountPrice(), 0); } - @Test - public void testCalculatePrice_coupon() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) - .setCouponId(1024L); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(优惠劵 Coupon 信息) - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) - .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) - .setDiscountPercent(50).setDiscountLimitPrice(70)); - when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getTotalPrice(), 470); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 400); - assertEquals(order.getCouponId(), 1024L); - assertEquals(order.getCouponPrice(), 70); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 0); - assertEquals(orderItem03.getOrderDividePrice(), 120); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1024L); - assertEquals(promotion01.getName(), "程序员节"); - assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); - assertEquals(promotion01.getTotalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMatch()); - assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - } - @Test public void testGetMeetCouponList() { // 准备参数 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java index 52ebf84a0..f00b04b12 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java @@ -101,7 +101,8 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator { CouponRespDTO coupon) { Predicate matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { - matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()); + matchPredicate = matchPredicate // 额外加如下条件 + .and(orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); } return filterList(result.getItems(), matchPredicate); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index 47a73c0d8..d171e50cf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -15,8 +15,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static java.util.Collections.singletonList; -// TODO 芋艿:改成父类 - /** * {@link TradePriceCalculator} 的工具类 * @@ -106,6 +104,31 @@ public class TradePriceCalculatorHelper { - orderItem.getPointPrice()); } + /** + * 重新计算每个订单项的支付金额 + * + * 【目前主要是单测使用】 + * + * @param orderItems 订单项数组 + */ + public static void recountPayPrice(List orderItems) { + orderItems.forEach(orderItem -> { + if (orderItem.getDiscountPrice() == null) { + orderItem.setDiscountPrice(0); + } + if (orderItem.getDeliveryPrice() == null) { + orderItem.setDeliveryPrice(0); + } + if (orderItem.getCouponPrice() == null) { + orderItem.setCouponPrice(0); + } + if (orderItem.getPointPrice() == null) { + orderItem.setPointPrice(0); + } + recountPayPrice(orderItem); + }); + } + /** * 计算已选中的订单项,总支付金额 * @@ -114,7 +137,7 @@ public class TradePriceCalculatorHelper { */ public static Integer calculateTotalPayPrice(List orderItems) { return getSumValue(orderItems, - orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 + orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 Integer::sum); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java index b0947fcc3..f2cfe71cd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java @@ -53,6 +53,9 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator // 1.2 获得最大匹配的满减送活动的规则 RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); if (rule == null) { + TradePriceCalculatorHelper.addNotMatchPromotion(result, orderItems, + rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(), + getRewardActivityNotMeetTip(rewardActivity)); return; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 064ec336e..15a55726d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; @@ -101,10 +102,10 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { // mock 方法(商品 SKU 检查) ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) .setPrice(50).setStock(100) - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L)))); + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L)))); ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) .setPrice(20).setStock(50)) - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L))); + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L))); when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); // mock 方法(商品 SPU 检查) ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) @@ -114,7 +115,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); // mock 方法(用户收件地址的校验) AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") - .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村"); + .setMobile("15601691300").setAreaId(3306).setPostCode("85757").setDetailAddress("土豆村"); when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); // mock 方法(价格计算) PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java new file mode 100644 index 000000000..473e3920e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java @@ -0,0 +1,135 @@ +package cn.iocoder.yudao.module.trade.service.price; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; + +import java.util.Arrays; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +/** + * {@link TradePriceServiceImpl} 的单元测试 + * + * @author 芋道源码 + */ +public class TradePriceServiceImplTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradePriceServiceImpl tradePriceService; + + @Mock + private ProductSkuApi productSkuApi; + @Mock + private ProductSpuApi productSpuApi; + @Mock + private List priceCalculators; + + @Test + public void testCalculatePrice() { + // 准备参数 + TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L) + .setCouponId(20L).setAddressId(30L) + .setItems(Arrays.asList( + new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(200L).setCount(3).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(300L).setCount(6).setCartId(233L).setSelected(false) + )); + // mock 方法 + List skuList = Arrays.asList( + new ProductSkuRespDTO().setId(100L).setStock(500).setPrice(1000).setPicUrl("https://t.cn/1.png").setSpuId(1001L) + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") + .setValueId(2L).setValueName("红色"))), + new ProductSkuRespDTO().setId(200L).setStock(400).setPrice(2000).setPicUrl("https://t.cn/2.png").setSpuId(1001L) + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") + .setValueId(3L).setValueName("黄色"))), + new ProductSkuRespDTO().setId(300L).setStock(600).setPrice(3000).setPicUrl("https://t.cn/3.png").setSpuId(1001L) + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") + .setValueId(4L).setValueName("黑色"))) + ); + when(productSkuApi.getSkuList(Mockito.eq(asSet(100L, 200L, 300L)))).thenReturn(skuList); + when(productSpuApi.getSpuList(Mockito.eq(asSet(1001L)))) + .thenReturn(singletonList(new ProductSpuRespDTO().setId(1001L).setName("小菜").setCategoryId(666L) + .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()))); + + // 调用 + TradePriceCalculateRespBO calculateRespBO = tradePriceService.calculatePrice(calculateReqBO); + // 断言 + assertEquals(TradeOrderTypeEnum.NORMAL.getType(), calculateRespBO.getType()); + assertEquals(0, calculateRespBO.getPromotions().size()); + assertNull(calculateRespBO.getCouponId()); + // 断言:订单价格 + assertEquals(7000, calculateRespBO.getPrice().getTotalPrice()); + assertEquals(0, calculateRespBO.getPrice().getDiscountPrice()); + assertEquals(0, calculateRespBO.getPrice().getDeliveryPrice()); + assertEquals(0, calculateRespBO.getPrice().getCouponPrice()); + assertEquals(0, calculateRespBO.getPrice().getPointPrice()); + assertEquals(7000, calculateRespBO.getPrice().getPayPrice()); + // 断言:SKU 1 + assertEquals(1001L, calculateRespBO.getItems().get(0).getSpuId()); + assertEquals(100L, calculateRespBO.getItems().get(0).getSkuId()); + assertEquals(1, calculateRespBO.getItems().get(0).getCount()); + assertNull(calculateRespBO.getItems().get(0).getCartId()); + assertTrue(calculateRespBO.getItems().get(0).getSelected()); + assertEquals(1000, calculateRespBO.getItems().get(0).getPrice()); + assertEquals(0, calculateRespBO.getItems().get(0).getDiscountPrice()); + assertEquals(0, calculateRespBO.getItems().get(0).getDeliveryPrice()); + assertEquals(0, calculateRespBO.getItems().get(0).getCouponPrice()); + assertEquals(0, calculateRespBO.getItems().get(0).getPointPrice()); + assertEquals(1000, calculateRespBO.getItems().get(0).getPayPrice()); + assertEquals("小菜", calculateRespBO.getItems().get(0).getSpuName()); + assertEquals("https://t.cn/1.png", calculateRespBO.getItems().get(0).getPicUrl()); + assertEquals(666L, calculateRespBO.getItems().get(0).getCategoryId()); + assertEquals(skuList.get(0).getProperties(), calculateRespBO.getItems().get(0).getProperties()); + // 断言:SKU 2 + assertEquals(1001L, calculateRespBO.getItems().get(1).getSpuId()); + assertEquals(200L, calculateRespBO.getItems().get(1).getSkuId()); + assertEquals(3, calculateRespBO.getItems().get(1).getCount()); + assertNull(calculateRespBO.getItems().get(1).getCartId()); + assertTrue(calculateRespBO.getItems().get(1).getSelected()); + assertEquals(2000, calculateRespBO.getItems().get(1).getPrice()); + assertEquals(0, calculateRespBO.getItems().get(1).getDiscountPrice()); + assertEquals(0, calculateRespBO.getItems().get(1).getDeliveryPrice()); + assertEquals(0, calculateRespBO.getItems().get(1).getCouponPrice()); + assertEquals(0, calculateRespBO.getItems().get(1).getPointPrice()); + assertEquals(6000, calculateRespBO.getItems().get(1).getPayPrice()); + assertEquals("小菜", calculateRespBO.getItems().get(1).getSpuName()); + assertEquals("https://t.cn/2.png", calculateRespBO.getItems().get(1).getPicUrl()); + assertEquals(666L, calculateRespBO.getItems().get(1).getCategoryId()); + assertEquals(skuList.get(1).getProperties(), calculateRespBO.getItems().get(1).getProperties()); + // 断言:SKU 3 + assertEquals(1001L, calculateRespBO.getItems().get(2).getSpuId()); + assertEquals(300L, calculateRespBO.getItems().get(2).getSkuId()); + assertEquals(6, calculateRespBO.getItems().get(2).getCount()); + assertEquals(233L, calculateRespBO.getItems().get(2).getCartId()); + assertFalse(calculateRespBO.getItems().get(2).getSelected()); + assertEquals(3000, calculateRespBO.getItems().get(2).getPrice()); + assertEquals(0, calculateRespBO.getItems().get(2).getDiscountPrice()); + assertEquals(0, calculateRespBO.getItems().get(2).getDeliveryPrice()); + assertEquals(0, calculateRespBO.getItems().get(2).getCouponPrice()); + assertEquals(0, calculateRespBO.getItems().get(2).getPointPrice()); + assertEquals(18000, calculateRespBO.getItems().get(2).getPayPrice()); + assertEquals("小菜", calculateRespBO.getItems().get(2).getSpuName()); + assertEquals("https://t.cn/3.png", calculateRespBO.getItems().get(2).getPicUrl()); + assertEquals(666L, calculateRespBO.getItems().get(2).getCategoryId()); + assertEquals(skuList.get(2).getProperties(), calculateRespBO.getItems().get(2).getProperties()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java new file mode 100644 index 000000000..238d80e0c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java @@ -0,0 +1,143 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link TradeCouponPriceCalculator} 的单元测试类 + * + * @author 芋道源码 + */ +class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradeCouponPriceCalculator tradeCouponPriceCalculator; + + @Mock + private CouponApi couponApi; + + @Test + void calculate() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setCouponId(1024L) + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配优惠劵 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 匹配优惠劵 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true), // 不匹配优惠劵 + new TradePriceCalculateReqBO.Item().setSkuId(40L).setCount(5).setSelected(false) // 匹配优惠劵,但是未选中 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(true) + .setPrice(30).setSpuId(3L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(40L).setCount(5).setSelected(false) + .setPrice(60).setSpuId(1L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(优惠劵 Coupon 信息) + CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节") + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) + .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) + .setDiscountPercent(50).setDiscountLimitPrice(70)); + when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon); + + // 调用 + tradeCouponPriceCalculator.calculate(param, result); + // 断言 + assertEquals(result.getCouponId(), 1024L); + // 断言:Price 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 470); + assertEquals(price.getDiscountPrice(), 0); + assertEquals(price.getPointPrice(), 0); + assertEquals(price.getDeliveryPrice(), 0); + assertEquals(price.getCouponPrice(), 70); + assertEquals(price.getPayPrice(), 400); + // 断言:SKU 1 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getDeliveryPrice(), 0); + assertEquals(orderItem01.getCouponPrice(), 40); + assertEquals(orderItem01.getPointPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 160); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getDeliveryPrice(), 0); + assertEquals(orderItem02.getCouponPrice(), 30); + assertEquals(orderItem02.getPointPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 120); + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 0); + assertEquals(orderItem03.getCouponPrice(), 0); + assertEquals(orderItem03.getPointPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 120); + // 断言:SKU 4 + TradePriceCalculateRespBO.OrderItem orderItem04 = result.getItems().get(3); + assertEquals(orderItem04.getSkuId(), 40L); + assertEquals(orderItem04.getCount(), 5); + assertEquals(orderItem04.getPrice(), 60); + assertEquals(orderItem04.getDiscountPrice(), 0); + assertEquals(orderItem04.getCouponPrice(), 0); + assertEquals(orderItem04.getPointPrice(), 0); + assertEquals(orderItem04.getPayPrice(), 300); + // 断言 Promotion 部分 + assertEquals(result.getPromotions().size(), 1); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), 1024L); + assertEquals(promotion01.getName(), "程序员节"); + assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); + assertEquals(promotion01.getTotalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getTotalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getTotalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + } +} From 0d08c814ec8ad6d367d0dd4b767bccbd3de89b2d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 13:14:47 +0800 Subject: [PATCH 075/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20TradeDiscountActivityPriceCalculator=20=E7=9A=84?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/price/PriceServiceTest.java | 87 ------------- .../TradeDiscountActivityPriceCalculator.java | 11 +- .../TradeCouponPriceCalculatorTest.java | 5 +- ...deDiscountActivityPriceCalculatorTest.java | 118 ++++++++++++++++++ 4 files changed, 128 insertions(+), 93 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 79690000a..5b43d2372 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -47,8 +47,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { @InjectMocks private PriceServiceImpl priceService; - @Mock - private DiscountActivityService discountService; @Mock private RewardActivityService rewardActivityService; @Mock @@ -56,91 +54,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { @Mock private ProductSkuApi productSkuApi; - @Test - public void testCalculatePrice_discountActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) - .setActivityName("活动 1000 号").setSkuId(10L) - .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); - DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) - .setActivityName("活动 2000 号").setSkuId(20L) - .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); - when(discountService.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn( - MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); - - // 10L: 100 * 2 - 40 * 2 = 120 - // 20L:50 * 3 - 50 * 3 * 0.4 = 90 - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getTotalPrice(), 350); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 210); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 80); - assertEquals(orderItem01.getPayPrice(), 120); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 60); - assertEquals(orderItem02.getPayPrice(), 90); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 90); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion01.getTotalPrice(), 200); - assertEquals(promotion01.getDiscountPrice(), 80); - assertTrue(promotion01.getMatch()); - assertEquals(promotion01.getDescription(), "限时折扣:省 0.80 元"); - PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); - assertEquals(promotion01.getItems().size(), 1); - assertEquals(promotionItem01.getSkuId(), 10L); - assertEquals(promotionItem01.getOriginalPrice(), 200); - assertEquals(promotionItem01.getDiscountPrice(), 80); - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion02.getTotalPrice(), 150); - assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMatch()); - assertEquals(promotion02.getDescription(), "限时折扣:省 0.60 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 20L); - assertEquals(promotionItem02.getOriginalPrice(), 150); - assertEquals(promotionItem02.getDiscountPrice(), 60); - } - /** * 测试满减送活动,匹配的情况 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java index 7bcd8ffb7..fe465f37d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java @@ -53,10 +53,13 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato Integer newDiscountPrice = orderItem.getPayPrice() - newPayPrice; // 3.1 记录优惠明细 - TradePriceCalculatorHelper.addPromotion(result, orderItem, - discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), - StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)), - newDiscountPrice); + if (orderItem.getSelected()) { + // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示 + TradePriceCalculatorHelper.addPromotion(result, orderItem, + discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), + StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)), + newDiscountPrice); + } // 3.2 更新 SKU 优惠金额 orderItem.setDiscountPrice(orderItem.getDiscountPrice() + newDiscountPrice); TradePriceCalculatorHelper.recountPayPrice(orderItem); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java index 238d80e0c..6d5a5c390 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java @@ -36,7 +36,7 @@ class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { private CouponApi couponApi; @Test - void calculate() { + public void testCalculate() { // 准备参数 TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() .setUserId(233L).setCouponId(1024L) @@ -120,7 +120,7 @@ class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { assertEquals(orderItem04.getCouponPrice(), 0); assertEquals(orderItem04.getPointPrice(), 0); assertEquals(orderItem04.getPayPrice(), 300); - // 断言 Promotion 部分 + // 断言:Promotion 部分 assertEquals(result.getPromotions().size(), 1); TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); assertEquals(promotion01.getId(), 1024L); @@ -140,4 +140,5 @@ class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { assertEquals(promotionItem012.getTotalPrice(), 150); assertEquals(promotionItem012.getDiscountPrice(), 30); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculatorTest.java new file mode 100644 index 000000000..9175e1643 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculatorTest.java @@ -0,0 +1,118 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi; +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link TradeDiscountActivityPriceCalculator} 的单元测试类 + * + * @author 芋道源码 + */ +public class TradeDiscountActivityPriceCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradeDiscountActivityPriceCalculator tradeDiscountActivityPriceCalculator; + + @Mock + private DiscountActivityApi discountActivityApi; + + @Test + public void testCalculate() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配活动,且已选中 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(false) // 匹配活动,但未选中 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(false) + .setPrice(50) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(限时折扣活动) + when(discountActivityApi.getMatchDiscountProductList(eq(asSet(10L, 20L)))).thenReturn(asList( + randomPojo(DiscountProductRespDTO.class, o -> o.setActivityId(1000L) + .setActivityName("活动 1000 号").setSkuId(10L) + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)), + randomPojo(DiscountProductRespDTO.class, o -> o.setActivityId(2000L) + .setActivityName("活动 2000 号").setSkuId(20L) + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)) + )); + // 10L: 100 * 2 - 40 * 2 = 120 + // 20L:50 * 3 - 50 * 3 * 0.4 = 90 + + // 调用 + tradeDiscountActivityPriceCalculator.calculate(param, result); + // 断言:Price 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 200); + assertEquals(price.getDiscountPrice(), 80); + assertEquals(price.getPointPrice(), 0); + assertEquals(price.getDeliveryPrice(), 0); + assertEquals(price.getCouponPrice(), 0); + assertEquals(price.getPayPrice(), 120); + assertNull(result.getCouponId()); + // 断言:SKU 1 + assertEquals(result.getItems().size(), 2); + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 80); + assertEquals(orderItem01.getDeliveryPrice(), 0); + assertEquals(orderItem01.getCouponPrice(), 0); + assertEquals(orderItem01.getPointPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 120); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 60); + assertEquals(orderItem02.getDeliveryPrice(), 0); + assertEquals(orderItem02.getCouponPrice(), 0); + assertEquals(orderItem02.getPointPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 90); + // 断言:Promotion 部分 + assertEquals(result.getPromotions().size(), 1); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); + assertEquals(promotion01.getTotalPrice(), 200); + assertEquals(promotion01.getDiscountPrice(), 80); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "限时折扣:省 0.80 元"); + TradePriceCalculateRespBO.PromotionItem promotionItem01 = promotion01.getItems().get(0); + assertEquals(promotion01.getItems().size(), 1); + assertEquals(promotionItem01.getSkuId(), 10L); + assertEquals(promotionItem01.getTotalPrice(), 200); + assertEquals(promotionItem01.getDiscountPrice(), 80); + } + +} From 73a781cbbe42373184d82503aeac8767225d8d0e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 13:36:07 +0800 Subject: [PATCH 076/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20TradeRewardActivityPriceCalculatorTest=20=E7=9A=84?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/price/PriceServiceTest.java | 178 +------------- .../TradeCouponPriceCalculatorTest.java | 2 +- ...radeRewardActivityPriceCalculatorTest.java | 232 ++++++++++++++++++ 3 files changed, 234 insertions(+), 178 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java index 5b43d2372..f2817b8fc 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -1,33 +1,24 @@ package cn.iocoder.yudao.module.promotion.service.price; -import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.enums.common.*; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.Set; import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; import static java.util.Arrays.asList; @@ -54,179 +45,12 @@ public class PriceServiceTest extends BaseMockitoUnitTest { @Mock private ProductSkuApi productSkuApi; - /** - * 测试满减送活动,匹配的情况 - */ - @Test - public void testCalculatePrice_rewardActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(200).setDiscountPrice(70)))); - RewardActivityDO rewardActivity02 = randomPojo(RewardActivityDO.class, o -> o.setId(2000L).setName("活动 2000 号") - .setProductSpuIds(singletonList(30L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) - .setRules(asList(new RewardActivityDO.Rule().setLimit(1).setDiscountPrice(10), - new RewardActivityDO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 - new RewardActivityDO.Rule().setLimit(10).setDiscountPrice(100)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - matchRewardActivities.put(rewardActivity02, asSet(3L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getTotalPrice(), 470); - assertEquals(order.getDiscountPrice(), 130); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 340); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 60); - assertEquals(orderItem03.getOrderDividePrice(), 60); - // 断言 Promotion 部分(第一个) - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getTotalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMatch()); - assertEquals(promotion01.getDescription(), "满减送:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - // 断言 Promotion 部分(第二个) - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion02.getTotalPrice(), 120); - assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMatch()); - assertEquals(promotion02.getDescription(), "满减送:省 0.60 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 30L); - assertEquals(promotionItem02.getOriginalPrice(), 120); - assertEquals(promotionItem02.getDiscountPrice(), 60); - } - /** * 测试满减送活动,不匹配的情况 */ @Test public void testCalculatePrice_rewardActivityNotMeet() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getTotalPrice(), 350); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 350); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 200); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 150); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getTotalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 0); - assertFalse(promotion01.getMatch()); - assertEquals(promotion01.getDescription(), "TODO"); // TODO 芋艿:后面再想想 - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 0); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 0); } @Test diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java index 6d5a5c390..ac4872c86 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java @@ -27,7 +27,7 @@ import static org.mockito.Mockito.when; * * @author 芋道源码 */ -class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { +public class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { @InjectMocks private TradeCouponPriceCalculator tradeCouponPriceCalculator; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculatorTest.java new file mode 100644 index 000000000..30107d5b4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculatorTest.java @@ -0,0 +1,232 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi; +import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link TradeRewardActivityPriceCalculator} 的单元测试类 + * + * @author 芋道源码 + */ +public class TradeRewardActivityPriceCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradeRewardActivityPriceCalculator tradeRewardActivityPriceCalculator; + + @Mock + private RewardActivityApi rewardActivityApi; + + @Test + public void testCalculate_match() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配活动 1 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 匹配活动 1 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true) // 匹配活动 2 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(true) + .setPrice(30).setSpuId(3L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(限时折扣 DiscountActivity 信息) + when(rewardActivityApi.getMatchRewardActivityList(eq(asSet(1L, 2L, 3L)))).thenReturn(asList( + randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setSpuIds(asList(1L, 2L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityMatchRespDTO.Rule().setLimit(200).setDiscountPrice(70)))), + randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(2000L).setName("活动 2000 号") + .setSpuIds(singletonList(3L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) + .setRules(asList(new RewardActivityMatchRespDTO.Rule().setLimit(1).setDiscountPrice(10), + new RewardActivityMatchRespDTO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 + new RewardActivityMatchRespDTO.Rule().setLimit(10).setDiscountPrice(100)))) + )); + + // 调用 + tradeRewardActivityPriceCalculator.calculate(param, result); + // 断言 Order 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 470); + assertEquals(price.getDiscountPrice(), 130); + assertEquals(price.getPointPrice(), 0); + assertEquals(price.getDeliveryPrice(), 0); + assertEquals(price.getCouponPrice(), 0); + assertEquals(price.getPayPrice(), 340); + assertNull(result.getCouponId()); + // 断言:SKU 1 + assertEquals(result.getItems().size(), 3); + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 40); + assertEquals(orderItem01.getDeliveryPrice(), 0); + assertEquals(orderItem01.getCouponPrice(), 0); + assertEquals(orderItem01.getPointPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 160); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 30); + assertEquals(orderItem02.getDeliveryPrice(), 0); + assertEquals(orderItem02.getCouponPrice(), 0); + assertEquals(orderItem02.getPointPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 120); + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 60); + assertEquals(orderItem03.getDeliveryPrice(), 0); + assertEquals(orderItem03.getCouponPrice(), 0); + assertEquals(orderItem03.getPointPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 60); + // 断言:Promotion 部分(第一个) + assertEquals(result.getPromotions().size(), 2); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getTotalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "满减送:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getTotalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getTotalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + // 断言:Promotion 部分(第二个) + TradePriceCalculateRespBO.Promotion promotion02 = result.getPromotions().get(1); + assertEquals(promotion02.getId(), 2000L); + assertEquals(promotion02.getName(), "活动 2000 号"); + assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion02.getTotalPrice(), 120); + assertEquals(promotion02.getDiscountPrice(), 60); + assertTrue(promotion02.getMatch()); + assertEquals(promotion02.getDescription(), "满减送:省 0.60 元"); + TradePriceCalculateRespBO.PromotionItem promotionItem02 = promotion02.getItems().get(0); + assertEquals(promotion02.getItems().size(), 1); + assertEquals(promotionItem02.getSkuId(), 30L); + assertEquals(promotionItem02.getTotalPrice(), 120); + assertEquals(promotionItem02.getDiscountPrice(), 60); + } + + @Test + public void testCalculate_notMatch() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true) + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(限时折扣 DiscountActivity 信息) + when(rewardActivityApi.getMatchRewardActivityList(eq(asSet(1L, 2L)))).thenReturn(singletonList( + randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setSpuIds(asList(1L, 2L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityMatchRespDTO.Rule().setLimit(351).setDiscountPrice(70)))) + )); + + // 调用 + tradeRewardActivityPriceCalculator.calculate(param, result); + // 断言 Order 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 350); + assertEquals(price.getDiscountPrice(), 0); + assertEquals(price.getPointPrice(), 0); + assertEquals(price.getDeliveryPrice(), 0); + assertEquals(price.getCouponPrice(), 0); + assertEquals(price.getPayPrice(), 350); + assertNull(result.getCouponId()); + // 断言:SKU 1 + assertEquals(result.getItems().size(), 2); + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getDeliveryPrice(), 0); + assertEquals(orderItem01.getCouponPrice(), 0); + assertEquals(orderItem01.getPointPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getDeliveryPrice(), 0); + assertEquals(orderItem02.getCouponPrice(), 0); + assertEquals(orderItem02.getPointPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + // 断言 Promotion 部分 + assertEquals(result.getPromotions().size(), 1); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getTotalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 0); + assertFalse(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "TODO"); // TODO 芋艿:后面再想想 + assertEquals(promotion01.getItems().size(), 2); + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getTotalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 0); + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getTotalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 0); + } + +} From f1fa8eadd23d04327ec50a3c34435078eb33ae59 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 3 Jun 2023 17:16:18 +0800 Subject: [PATCH 077/232] =?UTF-8?q?mall=20-=20trade=20-=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20TradeDeliveryPriceCalculator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/dataobject/spu/ProductSpuDO.java | 2 +- .../DeliveryExpressChargeModeEnum.java | 5 + .../DeliveryExpressTemplateService.java | 7 + .../DeliveryExpressTemplateServiceImpl.java | 9 + .../price/bo/TradePriceCalculateReqBO.java | 17 +- .../TradeDeliveryPriceCalculator.java | 228 ++++++++++++++++++ .../calculator/TradePriceCalculator.java | 4 + .../dataobject/address/MemberAddressDO.java | 2 +- 8 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 29cfe3a27..5ee4f1d28 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -141,7 +141,7 @@ public class ProductSpuDO extends BaseDO { /** * 物流配置模板编号 * - * 关联 { TradeDeliveryExpressTemplateDO#getId()} + * 对应 { TradeDeliveryExpressTemplateDO 的 id 编号} */ private Long deliveryTemplateId; diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java index 8ac37e382..a4b5252ee 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryExpressChargeModeEnum.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.enums.delivery; +import cn.hutool.core.util.ArrayUtil; import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -35,4 +36,8 @@ public enum DeliveryExpressChargeModeEnum implements IntArrayValuable { return ARRAYS; } + public static DeliveryExpressChargeModeEnum valueOf(Integer value) { + return ArrayUtil.firstMatch(chargeMode -> chargeMode.getType().equals(value), DeliveryExpressChargeModeEnum.values()); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 20a0a1b62..2b69c6147 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -63,4 +63,11 @@ public interface DeliveryExpressTemplateService { * @return 快递运费模板分页 */ PageResult getDeliveryExpressTemplatePage(DeliveryExpressTemplatePageReqVO pageReqVO); + + /** + * 校验快递运费模板 + * @param templateId 模板编号 + * @return DeliveryExpressTemplateDO 非空 + */ + DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index d77bb78c2..50a24e3bf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -202,4 +202,13 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla return expressTemplateMapper.selectPage(pageReqVO); } + @Override + public DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId) { + DeliveryExpressTemplateDO template = expressTemplateMapper.selectById(templateId); + if (template == null) { + throw exception(EXPRESS_TEMPLATE_NOT_EXISTS); + } + return template; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index 931940793..eb59f22e0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.trade.service.price.bo; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; @@ -44,6 +46,20 @@ public class TradePriceCalculateReqBO { */ private Long addressId; + /** + * 配送方式 + * + * 枚举 {@link DeliveryTypeEnum} + */ + private Integer deliveryType; + + /** + * 配送模板编号 + * + * 关联 {@link DeliveryExpressTemplateDO#getId()} + */ + private Long templateId; + /** * 商品 SKU 数组 */ @@ -82,5 +98,4 @@ public class TradePriceCalculateReqBO { private Boolean selected; } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java new file mode 100644 index 000000000..aaefc76c5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -0,0 +1,228 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.module.member.api.address.AddressApi; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; + +/** + * 运费的 {@link TradePriceCalculator} 实现类 + * + * @author jason + */ +@Component +@Order(TradePriceCalculator.ORDER_DELIVERY) +public class TradeDeliveryPriceCalculator implements TradePriceCalculator { + @Resource + private AddressApi addressApi; + @Resource + private ProductSkuApi productSkuApi; + @Resource + private DeliveryExpressTemplateService deliveryExpressTemplateService; + @Resource + private DeliveryExpressTemplateChargeMapper templateChargeMapper; + @Resource + private DeliveryExpressTemplateFreeMapper templateFreeMapper; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1.1 判断配送方式 + if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { + return; + } + + if (param.getTemplateId() == null || param.getAddressId() == null) { + return; + } + // 1.2 校验运费模板是否存在 + DeliveryExpressTemplateDO template = deliveryExpressTemplateService.validateDeliveryExpressTemplate(param.getTemplateId()); + + // 得到包邮配置 + List expressTemplateFreeList = templateFreeMapper.selectListByTemplateId(template.getId()); + Map areaTemplateFreeMap = new HashMap<>(); + expressTemplateFreeList.forEach(item -> { + for (Integer areaId : item.getAreaIds()) { + // TODO 需要保证 areaId 不能重复 + if (!areaTemplateFreeMap.containsKey(areaId)) { + areaTemplateFreeMap.put(areaId, item); + } + } + }); + // 得到快递运费配置 + List expressTemplateChargeList = templateChargeMapper.selectListByTemplateId(template.getId()); + Map areaTemplateChargeMap = new HashMap<>(); + expressTemplateChargeList.forEach(item -> { + for (Integer areaId : item.getAreaIds()) { + // areaId 不能重复 + if (!areaTemplateChargeMap.containsKey(areaId)) { + areaTemplateChargeMap.put(areaId, item); + } + } + }); + // 得到收件地址区域 + AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); + // 1.3 计算快递费用 + calculateDeliveryPrice(address.getAreaId(), template.getChargeMode(), + areaTemplateFreeMap, areaTemplateChargeMap, result); + } + + /** + * 校验订单是否满足包邮条件 + * + * @param receiverAreaId 收件人地区的区域编号 + * @param chargeMode 配送计费方式 + * @param areaTemplateFreeMap 运费模板包邮区域设置 Map + * @param areaTemplateChargeMap 运费模板快递费用设置 Map + */ + private void calculateDeliveryPrice(Integer receiverAreaId, + Integer chargeMode, + Map areaTemplateFreeMap, + Map areaTemplateChargeMap, + TradePriceCalculateRespBO result) { + // 过滤出已选中的商品SKU + List selectedItem = filterList(result.getItems(), OrderItem::getSelected); + Set skuIds = convertSet(selectedItem, OrderItem::getSkuId); + // 得到SKU 详情。得到 重量体积 + Map skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId); + // 一个 spuId 可能对应多条订单商品 SKU + Map> spuIdItemMap = convertMultiMap(selectedItem, OrderItem::getSpuId); + // 依次计算每个 SPU 的快递运费 + for (Map.Entry> entry : spuIdItemMap.entrySet()) { + List orderItems = entry.getValue(); + // 总件数, 总金额, 总重量, 总体积 + int totalCount = 0, totalPrice = 0; + double totalWeight = 0; + double totalVolume = 0; + for (OrderItem orderItem : orderItems) { + totalCount += orderItem.getCount(); + totalPrice += orderItem.getPrice(); + ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId()); + if (skuResp != null) { + totalWeight = totalWeight + skuResp.getWeight(); + totalVolume = totalVolume + skuResp.getVolume(); + } + } + // 优先判断是否包邮. 如果包邮不计算快递运费 + if (areaTemplateFreeMap.containsKey(receiverAreaId) && + checkExpressFree(chargeMode, totalCount, totalWeight, + totalVolume, totalPrice, areaTemplateFreeMap.get(receiverAreaId))) { + continue; + } + // 计算快递运费 + if (areaTemplateChargeMap.containsKey(receiverAreaId)) { + DeliveryExpressTemplateChargeDO templateCharge = areaTemplateChargeMap.get(receiverAreaId); + DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); + switch (chargeModeEnum) { + case PIECE: { + calculateExpressFeeBySpu(totalCount, templateCharge, orderItems); + break; + } + case WEIGHT: { + calculateExpressFeeBySpu(totalWeight, templateCharge, orderItems); + break; + } + case VOLUME: { + calculateExpressFeeBySpu(totalVolume, templateCharge, orderItems); + break; + } + } + } + } + TradePriceCalculatorHelper.recountAllPrice(result); + } + + /** + * 按 spu 来计算快递费用 + * + * @param total 总件数/总重量/总体积 + * @param templateCharge 快递运费配置 + * @param orderItems SKU 商品项目 + */ + private void calculateExpressFeeBySpu(double total, DeliveryExpressTemplateChargeDO templateCharge, List orderItems) { + int deliveryPrice; + if (total <= templateCharge.getStartCount()) { + deliveryPrice = templateCharge.getStartPrice(); + } else { + double remainWeight = total - templateCharge.getStartCount(); + // 剩余重量/ 续件 = 续件的次数. 向上取整 + int extraNum = (int) Math.ceil(remainWeight / templateCharge.getExtraCount()); + int extraPrice = templateCharge.getExtraPrice() * extraNum; + deliveryPrice = templateCharge.getStartPrice() + extraPrice; + } + // + // TODO @芋艿 分摊快递费用到 SKU. 是不是搞复杂了 + divideDeliveryPrice(deliveryPrice, orderItems); + } + + /** + * 快递运费分摊到每个 SKU 商品上 + * + * @param deliveryPrice 快递运费 + * @param orderItems SKU 商品 + */ + private void divideDeliveryPrice(int deliveryPrice, List orderItems) { + int dividePrice = deliveryPrice / orderItems.size(); + for (OrderItem item : orderItems) { + // 更新快递运费 + item.setDeliveryPrice(dividePrice); + } + } + + /** + * 检查是否包邮 + * + * @param chargeMode 配送计费方式 + * @param totalCount 总件数 + * @param totalWeight 总重量 + * @param totalVolume 总体积 + * @param totalPrice 总金额 + * @param templateFree 包邮配置 + */ + private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight, + double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) { + DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); + switch (chargeModeEnum) { + case PIECE: + // 两个条件都满足才包邮 + if (totalCount >= templateFree.getFreeCount() && totalPrice >= templateFree.getFreePrice()) { + return true; + } + break; + case WEIGHT: + // freeCount 是不是应该是 double ?? + if (totalWeight >= templateFree.getFreeCount() + && totalPrice >= templateFree.getFreePrice()) { + return true; + } + break; + case VOLUME: + if (totalVolume >= templateFree.getFreeCount() + && totalPrice >= templateFree.getFreePrice()) { + return true; + } + break; + } + return false; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java index 1c9b4f988..ba7fd6c8e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -11,6 +11,10 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; public interface TradePriceCalculator { int ORDER_DISCOUNT_ACTIVITY = 10; + /** + * TODO @芋艿 快递运费的计算在满减之前。 例如有满多少包邮 + */ + int ORDER_DELIVERY = 15; int ORDER_REWARD_ACTIVITY = 20; int ORDER_COUPON = 30; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java index 560edbba9..743849421 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java @@ -39,7 +39,7 @@ public class MemberAddressDO extends BaseDO { /** * 地区编号 */ - private Long areaId; + private Integer areaId; /** * 收件详细地址 */ From 36ce968893dfc218c6b5946ccb7305af58250ed0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 18:08:59 +0800 Subject: [PATCH 078/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E8=BF=90=E8=B4=B9=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/dal/dataobject/spu/ProductSpuDO.java | 2 +- .../delivery/DeliveryExpressTemplateService.java | 5 ++++- .../price/bo/TradePriceCalculateReqBO.java | 1 + .../calculator/TradeDeliveryPriceCalculator.java | 16 +++++++++++----- .../price/calculator/TradePriceCalculator.java | 10 ++++++---- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 5ee4f1d28..905bb890b 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -141,7 +141,7 @@ public class ProductSpuDO extends BaseDO { /** * 物流配置模板编号 * - * 对应 { TradeDeliveryExpressTemplateDO 的 id 编号} + * 对应 TradeDeliveryExpressTemplateDO 的 id 编号 */ private Long deliveryTemplateId; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 2b69c6147..e4fb5e69a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -66,8 +66,11 @@ public interface DeliveryExpressTemplateService { /** * 校验快递运费模板 + * + * 如果校验不通过,抛出 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 异常 + * * @param templateId 模板编号 - * @return DeliveryExpressTemplateDO 非空 + * @return 快递运费模板 */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index eb59f22e0..7f9d333ae 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -58,6 +58,7 @@ public class TradePriceCalculateReqBO { * * 关联 {@link DeliveryExpressTemplateDO#getId()} */ + // TODO @jason:运费模版,是不是每个 SKU 传入哈 private Long templateId; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index aaefc76c5..1f53bf8cc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -34,12 +34,15 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @Component @Order(TradePriceCalculator.ORDER_DELIVERY) public class TradeDeliveryPriceCalculator implements TradePriceCalculator { + @Resource private AddressApi addressApi; @Resource private ProductSkuApi productSkuApi; + @Resource private DeliveryExpressTemplateService deliveryExpressTemplateService; + // TODO @jason:走 Service 哈。Mapper 只允许自己的 Service 调用,保护好数据结构; @Resource private DeliveryExpressTemplateChargeMapper templateChargeMapper; @Resource @@ -106,20 +109,22 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { // 得到SKU 详情。得到 重量体积 Map skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId); // 一个 spuId 可能对应多条订单商品 SKU + // TODO @jason:得确认下,按照 sku 算,还是 spu 算; Map> spuIdItemMap = convertMultiMap(selectedItem, OrderItem::getSpuId); // 依次计算每个 SPU 的快递运费 for (Map.Entry> entry : spuIdItemMap.entrySet()) { List orderItems = entry.getValue(); // 总件数, 总金额, 总重量, 总体积 - int totalCount = 0, totalPrice = 0; + int totalCount = 0; + int totalPrice = 0; double totalWeight = 0; double totalVolume = 0; for (OrderItem orderItem : orderItems) { totalCount += orderItem.getCount(); - totalPrice += orderItem.getPrice(); + totalPrice += orderItem.getPrice(); // TODO jason:应该按照 payPrice? ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId()); if (skuResp != null) { - totalWeight = totalWeight + skuResp.getWeight(); + totalWeight = totalWeight + skuResp.getWeight(); // TODO @jason:* 数量 totalVolume = totalVolume + skuResp.getVolume(); } } @@ -130,6 +135,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { continue; } // 计算快递运费 + // TODO @jason:貌似也可以抽成 checkExpressFree 类似方法 if (areaTemplateChargeMap.containsKey(receiverAreaId)) { DeliveryExpressTemplateChargeDO templateCharge = areaTemplateChargeMap.get(receiverAreaId); DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); @@ -170,8 +176,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { int extraPrice = templateCharge.getExtraPrice() * extraNum; deliveryPrice = templateCharge.getStartPrice() + extraPrice; } - // - // TODO @芋艿 分摊快递费用到 SKU. 是不是搞复杂了 + // TODO @芋艿 分摊快递费用到 SKU. 是不是搞复杂了; + // TODO @jason:因为退费的时候,可能按照 SKU 考虑退费金额 divideDeliveryPrice(deliveryPrice, orderItems); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java index ba7fd6c8e..92ae9c2ee 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -11,12 +11,14 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; public interface TradePriceCalculator { int ORDER_DISCOUNT_ACTIVITY = 10; - /** - * TODO @芋艿 快递运费的计算在满减之前。 例如有满多少包邮 - */ - int ORDER_DELIVERY = 15; int ORDER_REWARD_ACTIVITY = 20; int ORDER_COUPON = 30; + /** + * 快递运费的计算 + * + * 放在各种营销活动、优惠劵后面 TODO + */ + int ORDER_DELIVERY = 40; void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); From 910d374ceee729396afd932ab8665706ab46a11d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 19:56:23 +0800 Subject: [PATCH 079/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E8=BF=90=E8=B4=B9=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DeliveryExpressTemplateController.java | 6 ++--- .../DeliveryExpressTemplateDetailRespVO.java | 25 +++++++++++++++++++ .../DeliveryExpressTemplateRespVO.java | 19 ++++---------- .../DeliveryExpressTemplateSimpleRespVO.java | 21 ---------------- .../DeliveryExpressTemplateConvert.java | 16 ++++++------ .../DeliveryExpressTemplateService.java | 4 +-- .../DeliveryExpressTemplateServiceImpl.java | 2 +- 7 files changed, 44 insertions(+), 49 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 1dcab4055..7a6068827 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -57,7 +57,7 @@ public class DeliveryExpressTemplateController { @Operation(summary = "获得快递运费模板") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") - public CommonResult getDeliveryExpressTemplate(@RequestParam("id") Long id) { + public CommonResult getDeliveryExpressTemplate(@RequestParam("id") Long id) { return success(deliveryExpressTemplateService.getDeliveryExpressTemplate(id)); } @@ -65,7 +65,7 @@ public class DeliveryExpressTemplateController { @Operation(summary = "获得快递运费模板列表") @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") - public CommonResult> getDeliveryExpressTemplateList(@RequestParam("ids") Collection ids) { + public CommonResult> getDeliveryExpressTemplateList(@RequestParam("ids") Collection ids) { List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(ids); return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); } @@ -73,7 +73,7 @@ public class DeliveryExpressTemplateController { @GetMapping("/page") @Operation(summary = "获得快递运费模板分页") @PreAuthorize("@ss.hasPermission('trade:delivery:express-template:query')") - public CommonResult> getDeliveryExpressTemplatePage(@Valid DeliveryExpressTemplatePageReqVO pageVO) { + public CommonResult> getDeliveryExpressTemplatePage(@Valid DeliveryExpressTemplatePageReqVO pageVO) { PageResult pageResult = deliveryExpressTemplateService.getDeliveryExpressTemplatePage(pageVO); return success(DeliveryExpressTemplateConvert.INSTANCE.convertPage(pageResult)); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java new file mode 100644 index 000000000..44cb042f9 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 快递运费模板的详细 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DeliveryExpressTemplateDetailRespVO extends DeliveryExpressTemplateBaseVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "371") + private Long id; + + @Schema(description = "运费模板运费设置", requiredMode = Schema.RequiredMode.REQUIRED) + private List templateCharge; + + @Schema(description = "运费模板包邮区域", requiredMode = Schema.RequiredMode.REQUIRED) + private List templateFree; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java index a03a8e61b..222cab9fd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateRespVO.java @@ -1,28 +1,19 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import lombok.*; +import java.time.LocalDateTime; -import java.util.List; - -/** - * @author jason - */ @Schema(description = "管理后台 - 快递运费模板 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DeliveryExpressTemplateRespVO extends DeliveryExpressTemplateBaseVO { - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "371") + @Schema(description = "编号,自增", required = true, example = "371") private Long id; - @Schema(description = "运费模板运费设置", requiredMode = Schema.RequiredMode.REQUIRED) - private List templateCharge; - - @Schema(description = "运费模板包邮区域", requiredMode = Schema.RequiredMode.REQUIRED) - private List templateFree; + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java deleted file mode 100644 index 957ce3c08..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.time.LocalDateTime; - -// TODO @jason:simplae 是不是不用继承 DeliveryExpressTemplateBaseVO,直接 id name 属性就够了。 -// @芋艿 这里给列表显示用的。 需要显示计费方式和排序, 所以继承 DeliveryExpressTemplateBaseVO。 这是去掉了包邮区域和 区域运费列表 -@Schema(description = "管理后台 - 快递运费模板 精简 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DeliveryExpressTemplateSimpleRespVO extends DeliveryExpressTemplateBaseVO { - - @Schema(description = "编号,自增", required = true, example = "371") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index 424c7e132..af247367c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -22,18 +22,18 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateDO convert(DeliveryExpressTemplateUpdateReqVO bean); - DeliveryExpressTemplateSimpleRespVO convert(DeliveryExpressTemplateDO bean); + DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean); - DeliveryExpressTemplateRespVO convert2(DeliveryExpressTemplateDO bean); + DeliveryExpressTemplateDetailRespVO convert2(DeliveryExpressTemplateDO bean); - List convertList(List list); + List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); - default DeliveryExpressTemplateRespVO convert(DeliveryExpressTemplateDO bean, - List chargeList, - List freeList){ - DeliveryExpressTemplateRespVO respVO = convert2(bean); + default DeliveryExpressTemplateDetailRespVO convert(DeliveryExpressTemplateDO bean, + List chargeList, + List freeList){ + DeliveryExpressTemplateDetailRespVO respVO = convert2(bean); respVO.setTemplateCharge(convertTemplateChargeList(chargeList)); respVO.setTemplateFree(convertTemplateFreeList(freeList)); return respVO; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index e4fb5e69a..46a2d89b6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; @@ -46,7 +46,7 @@ public interface DeliveryExpressTemplateService { * @param id 编号 * @return 快递运费模板详情 */ - DeliveryExpressTemplateRespVO getDeliveryExpressTemplate(Long id); + DeliveryExpressTemplateDetailRespVO getDeliveryExpressTemplate(Long id); /** * 获得快递运费模板列表 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 50a24e3bf..3e71bb1c9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -185,7 +185,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } @Override - public DeliveryExpressTemplateRespVO getDeliveryExpressTemplate(Long id) { + public DeliveryExpressTemplateDetailRespVO getDeliveryExpressTemplate(Long id) { List chargeList = expressTemplateChargeMapper.selectListByTemplateId(id); List freeList = expressTemplateFreeMapper.selectListByTemplateId(id); DeliveryExpressTemplateDO template = expressTemplateMapper.selectById(id); From f3a982da3152f64700bcfc95671cbd79d2934ea4 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 3 Jun 2023 21:12:12 +0800 Subject: [PATCH 080/232] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=B7=AE=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/delivery/DeliveryExpressTemplateController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 4e98e3b40..642fcb912 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -73,7 +73,7 @@ public class DeliveryExpressTemplateController { @GetMapping("/list-all-simple") @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项") - public CommonResult> getSimpleTemplateList() { + public CommonResult> getSimpleTemplateList() { // 获取运费模版列表,只要开启状态的 List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(); // 排序后,返回给前端 From dd932151391dce7051eb86f8e9a84a663182ce01 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 3 Jun 2023 22:59:34 +0800 Subject: [PATCH 081/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E5=95=86=E5=93=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ProductConstants.java | 11 +----- .../app/spu/AppProductSpuController.java | 3 +- .../convert/spu/ProductSpuConvert.java | 6 ---- .../dal/mysql/sku/ProductSkuMapper.java | 11 +----- .../category/ProductCategoryServiceImpl.java | 5 +-- .../property/ProductPropertyServiceImpl.java | 3 +- .../ProductPropertyValueServiceImpl.java | 2 ++ .../service/sku/ProductSkuService.java | 9 ----- .../service/sku/ProductSkuServiceImpl.java | 34 ++++++++----------- .../service/spu/ProductSpuServiceImpl.java | 15 ++++---- .../DeliveryExpressTemplateController.java | 2 +- .../server/controller/DefaultController.java | 14 ++++---- 12 files changed, 40 insertions(+), 75 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java index 117285071..f3570c589 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.product.enums; /** - * Product 常量 TODO 把使用到的常量收拢到一块定义替换魔法值 + * Product 常量 * * @author HUIHUI */ @@ -12,13 +12,4 @@ public interface ProductConstants { */ int ALERT_STOCK = 10; - /** - * 默认商品销量 TODO 默认商品销量为零 - */ - Integer SALES_COUNT = 0; - /** - * 默认善品浏览量 TODO 默认浏览量为零 - */ - Integer BROWSE_COUNT = 0; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 2a0f4cd68..0e173f902 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.app.spu; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; @@ -67,7 +66,7 @@ public class AppProductSpuController { } // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId()); + List skus = productSkuService.getSkuListBySpuId(spu.getId()); // 查询商品属性 List propertyValues = productPropertyValueService .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 62c47bfb6..58d69d077 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; @@ -23,9 +22,6 @@ import org.mapstruct.factory.Mappers; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; import static cn.hutool.core.util.ObjectUtil.defaultIfNull; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; @@ -65,8 +61,6 @@ public interface ProductSpuConvert { return StrUtil.toString(list); } - // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 fix:哈哈 这样确实丝滑哈 - @Mapping(source = "sliderPicUrls", target = "sliderPicUrls", qualifiedByName = "convertListToString") @Mapping(source = "giveCouponTemplateIds", target = "giveCouponTemplateIds", qualifiedByName = "convertListToString") @Mapping(source = "activityOrders", target = "activityOrders", qualifiedByName = "convertListToString") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index da05951ab..0b6ef5ed0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -14,11 +14,6 @@ import org.apache.ibatis.annotations.Mapper; import java.util.Collection; import java.util.List; -/** - * 商品 SKU Mapper - * - * @author 芋道源码 - */ @Mapper public interface ProductSkuMapper extends BaseMapperX { @@ -26,11 +21,6 @@ public interface ProductSkuMapper extends BaseMapperX { return selectList(ProductSkuDO::getSpuId, spuId); } - default List selectListBySpuIdAndStatus(Long spuId) { - return selectList(new LambdaQueryWrapperX() - .eq(ProductSkuDO::getSpuId, spuId)); - } - default List selectListBySpuId(Collection spuIds) { return selectList(ProductSkuDO::getSpuId, spuIds); } @@ -73,6 +63,7 @@ public interface ProductSkuMapper extends BaseMapperX { return selectList(new QueryWrapper().apply("stock <= warn_stock")); } + // TODO @puhui999:貌似 IN 不出来数据哈。直接全部查询出来,处理就好列; /** * 更新 sku 属性值时使用的分页查询 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 29133219f..ab4f127ba 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -96,6 +96,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } } + // TODO @puhui999:不用抽方法,因为不太会复用这个方法哈。 private void validateProductCategoryIsHaveBindSpu(Long id) { Long count = productSpuService.getSpuCountByCategoryId(id); if (0 != count) { @@ -126,9 +127,9 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } int level = 1; // for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈 - for (int i = 0; i < 100; i++) { - ProductCategoryDO category = productCategoryMapper.selectById(id); + for (int i = 0; i < Byte.MAX_VALUE; i++) { // 如果没有父节点,break 结束 + ProductCategoryDO category = productCategoryMapper.selectById(id); if (category == null || Objects.equals(category.getParentId(), PARENT_ID_NULL)) { break; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index 6c3ec8938..518b1065c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.service.property; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; @@ -72,7 +71,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { // 更新 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); productPropertyMapper.updateById(updateObj); - // TODO 芋艿:更新时,需要看看 sku 表 fix + // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈 productSkuService.updateSkuProperty(updateObj); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index f76f8f493..2666f13f4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -73,7 +73,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ // 更新 ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); productPropertyValueMapper.updateById(updateObj); + // TODO 芋艿:更新时,需要看看 sku 表 fix + // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈 productSkuService.updateSkuPropertyValue(updateObj); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index a46c4fd30..f66b9d829 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateO import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import org.springframework.lang.Nullable; import java.util.Collection; import java.util.List; @@ -87,14 +86,6 @@ public interface ProductSkuService { */ List getSkuListBySpuId(Long spuId); - /** - * 基于 SPU 编号和状态,获得商品 SKU 集合 - * - * @param spuId SPU 编号 - * @return 商品 SKU 集合 - */ - List getSkuListBySpuIdAndStatus(Long spuId); - /** * 获得 spu 对应的 SKU 集合 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index ee8266467..8e0a1c9a1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -140,11 +140,6 @@ public class ProductSkuServiceImpl implements ProductSkuService { return productSkuMapper.selectListBySpuId(spuId); } - @Override - public List getSkuListBySpuIdAndStatus(Long spuId) { - return productSkuMapper.selectListBySpuIdAndStatus(spuId); - } - @Override public List getSkuListBySpuId(List spuIds) { return productSkuMapper.selectListBySpuId(spuIds); @@ -163,9 +158,10 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Override public int updateSkuProperty(ProductPropertyDO updateObj) { // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 + // TODO @puhui999:直接全部查询处理,批量处理就好列;一般项目的商品不会超过几十万的哈。 Long count = productSkuMapper.selectCountByPropertyNotNull(); int currentPage = 1; - List skuDOs = new ArrayList<>(); + List updateSkus = new ArrayList<>(); if (count == 0) { return 0; } @@ -178,25 +174,25 @@ public class ProductSkuServiceImpl implements ProductSkuService { if (CollUtil.isEmpty(records)) { break; } - records.stream() - .filter(sku -> sku.getProperties() != null) + records.stream().filter(sku -> sku.getProperties() != null) .forEach(sku -> sku.getProperties().forEach(property -> { if (property.getPropertyId().equals(updateObj.getId())) { property.setPropertyName(updateObj.getName()); - skuDOs.add(sku); + updateSkus.add(sku); } })); } - if (CollUtil.isEmpty(skuDOs)) { + if (CollUtil.isEmpty(updateSkus)) { return 0; } + // TODO @puhui999:貌似 updateBatch 自己会拆分批次,这里不用再拆分了 // 每批处理的大小 int batchSize = 1000; - for (int i = 0; i < skuDOs.size(); i += batchSize) { - List batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size())); + for (int i = 0; i < updateSkus.size(); i += batchSize) { + List batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size())); productSkuMapper.updateBatch(batchSkuDOs, batchSize); } - return skuDOs.size(); + return updateSkus.size(); } @Override @@ -204,7 +200,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 Long count = productSkuMapper.selectCountByPropertyNotNull(); int currentPage = 1; - List skuDOs = new ArrayList<>(); + List updateSkus = new ArrayList<>(); if (count == 0) { return 0; } @@ -222,20 +218,20 @@ public class ProductSkuServiceImpl implements ProductSkuService { .forEach(sku -> sku.getProperties().forEach(property -> { if (property.getValueId().equals(updateObj.getId())) { property.setValueName(updateObj.getName()); - skuDOs.add(sku); + updateSkus.add(sku); } })); } - if (CollUtil.isEmpty(skuDOs)) { + if (CollUtil.isEmpty(updateSkus)) { return 0; } // 每批处理的大小 int batchSize = 1000; - for (int i = 0; i < skuDOs.size(); i += batchSize) { - List batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size())); + for (int i = 0; i < updateSkus.size(); i += batchSize) { + List batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size())); productSkuMapper.updateBatch(batchSkuDOs, batchSize); } - return skuDOs.size(); + return updateSkus.size(); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index ed40a281b..78e9ba62c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.enums.ProductConstants; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; @@ -27,6 +26,7 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; @@ -101,13 +101,13 @@ public class ProductSpuServiceImpl implements ProductSpuService { */ private void initSpuFromSkus(ProductSpuDO spu, List skus) { // sku 单价最低的商品的价格 - spu.setPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); + spu.setPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); // sku 单价最低的商品的市场价格 - spu.setMarketPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); + spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); // sku单价最低的商品的成本价格 - spu.setCostPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice)); + spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice)); // sku单价最低的商品的条形码 - spu.setBarCode(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); + spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); // skus 库存总数 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); // 若是 spu 已有状态则不处理 @@ -115,9 +115,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 默认状态为上架 spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); // 默认商品销量 - spu.setSalesCount(ProductConstants.SALES_COUNT); + spu.setSalesCount(0); // 默认商品浏览量 - spu.setBrowseCount(ProductConstants.BROWSE_COUNT); + spu.setBrowseCount(0); } } @@ -159,6 +159,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { * * @param id id */ + // TODO puhui999:感觉不用独立出来一个方法,直接在 deleteSpu 方法中校验即可 private void validateSpuStatus(Long id) { ProductSpuDO spuDO = productSpuMapper.selectById(id); // 判断 SPU 状态是否为回收站 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 642fcb912..572c04e99 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.controller.admin.delivery; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; @@ -71,6 +70,7 @@ public class DeliveryExpressTemplateController { return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); } + // TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈 @GetMapping("/list-all-simple") @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项") public CommonResult> getSimpleTemplateList() { diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java b/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java index 3a7cd3bfa..1fe56678b 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java @@ -27,13 +27,13 @@ public class DefaultController { "[微信公众号 yudao-module-mp - 已禁用][参考 https://doc.iocoder.cn/mp/build/ 开启]"); } - @RequestMapping(value = {"/admin-api/product/**", // 商品中心 - "/admin-api/trade/**", // 交易中心 - "/admin-api/promotion/**"}) // 营销中心 - public CommonResult mall404() { - return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]"); - } +// @RequestMapping(value = {"/admin-api/product/**", // 商品中心 +// "/admin-api/trade/**", // 交易中心 +// "/admin-api/promotion/**"}) // 营销中心 +// public CommonResult mall404() { +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), +// "[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]"); +// } @RequestMapping(value = {"/admin-api/report/**"}) public CommonResult report404() { From 36c45bd44e1b0ac18fa432dc21a8e85b395785e4 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 4 Jun 2023 17:45:40 +0800 Subject: [PATCH 082/232] =?UTF-8?q?review=20=E4=BB=B7=E6=A0=BC=E8=BF=90?= =?UTF-8?q?=E7=AE=97=E4=BF=AE=E6=94=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/spu/dto/ProductSpuRespDTO.java | 9 + .../DeliveryExpressTemplateService.java | 14 +- .../DeliveryExpressTemplateServiceImpl.java | 53 ++++++ .../bo/SpuDeliveryExpressTemplateRespBO.java | 45 +++++ .../price/bo/TradePriceCalculateReqBO.java | 9 - .../TradeDeliveryPriceCalculator.java | 166 ++++++++---------- 6 files changed, 198 insertions(+), 98 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java index a11b52b7c..3188f9632 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -103,6 +103,15 @@ public class ProductSpuRespDTO { */ private Integer stock; + // ========== 物流相关字段 ========= + + /** + * 物流配置模板编号 + * + * 对应 TradeDeliveryExpressTemplateDO 的 id 编号 + */ + private Long deliveryTemplateId; + // ========== 统计相关字段 ========= /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 080e7af7d..6ec95a27a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -6,10 +6,12 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; import javax.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 快递运费模板 Service 接口 @@ -73,11 +75,21 @@ public interface DeliveryExpressTemplateService { /** * 校验快递运费模板 - * + *

* 如果校验不通过,抛出 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 异常 * * @param templateId 模板编号 * @return 快递运费模板 */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); + + /** + * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 + * + * @param ids SPU 编号列表 + * @param areaId 区域编号 + * @return Map (spuId -> 运费模板设置) + */ + Map getExpressTemplateBySpuIdsAndArea(Collection ids, Integer areaId); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 5160be41e..87b2d4920 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; @@ -9,6 +12,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateMapper; +import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -17,6 +21,7 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NAME_DUPLICATE; @@ -37,6 +42,8 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; @Resource private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; + @Resource + private ProductSpuApi productSpuApi; @Override @Transactional(rollbackFor = Exception.class) @@ -216,4 +223,50 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla return template; } + @Override + public Map getExpressTemplateBySpuIdsAndArea(Collection spuIds, Integer areaId) { + Assert.notNull(areaId, "区域编号 {} 不能为空", areaId); + List spuList = productSpuApi.getSpuList(spuIds); + if (CollUtil.isEmpty(spuList)) { + return Collections.emptyMap(); + } + Map spuMap = convertMap(spuList, ProductSpuRespDTO::getDeliveryTemplateId); + List templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet()); + Map result = new HashMap<>(templateList.size()); + templateList.forEach(item -> { + if (spuMap.containsKey(item.getId())) { + ProductSpuRespDTO spuDTO = spuMap.get(item.getId()); + SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() + .setSpuId(spuDTO.getId()).setAreaId(areaId) + .setChargeMode(item.getChargeMode()) + .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) + .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); + result.put(spuDTO.getId(), bo); + } + }); + return result; + } + + private DeliveryExpressTemplateChargeDO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { + List list = expressTemplateChargeMapper.selectListByTemplateId(templateId); + for (DeliveryExpressTemplateChargeDO item : list) { + // 第一个匹配的返回。 areaId 不能重复 + if (item.getAreaIds().contains(areaId)) { + return item; + } + } + return null; + } + + private DeliveryExpressTemplateFreeDO findMatchExpressTemplateFree(Long templateId, Integer areaId) { + List list = expressTemplateFreeMapper.selectListByTemplateId(templateId); + for (DeliveryExpressTemplateFreeDO item : list) { + // 第一个匹配的返回。 areaId 不能重复 + if (item.getAreaIds().contains(areaId)) { + return item; + } + } + return null; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java new file mode 100644 index 000000000..87d04001b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.service.delivery.bo; + +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; +import lombok.Data; + +/** + * SPU 运费模板配置 Resp BO + * + * @author jason + */ +@Data +public class SpuDeliveryExpressTemplateRespBO { + + /** + * 配送计费方式 + *

+ * 枚举 {@link DeliveryExpressChargeModeEnum} + */ + private Integer chargeMode; + + /** + * 运费模板快递运费设置 + */ + private DeliveryExpressTemplateChargeDO templateCharge; + + /** + * 运费模板包邮设置 + */ + private DeliveryExpressTemplateFreeDO templateFree; + + /** + * SPU 编号 + *

+ * 关联 ProductSpuDO 的 id 编号 + */ + private Long spuId; + + /** + * 区域编号 + */ + private Integer areaId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index 7f9d333ae..ff5faea26 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.service.price.bo; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import lombok.Data; @@ -53,14 +52,6 @@ public class TradePriceCalculateReqBO { */ private Integer deliveryType; - /** - * 配送模板编号 - * - * 关联 {@link DeliveryExpressTemplateDO#getId()} - */ - // TODO @jason:运费模版,是不是每个 SKU 传入哈 - private Long templateId; - /** * 商品 SKU 数组 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 1f53bf8cc..46399b203 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -1,17 +1,17 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; -import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem; @@ -19,7 +19,6 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,14 +38,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { private AddressApi addressApi; @Resource private ProductSkuApi productSkuApi; - @Resource private DeliveryExpressTemplateService deliveryExpressTemplateService; - // TODO @jason:走 Service 哈。Mapper 只允许自己的 Service 调用,保护好数据结构; - @Resource - private DeliveryExpressTemplateChargeMapper templateChargeMapper; - @Resource - private DeliveryExpressTemplateFreeMapper templateFreeMapper; @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { @@ -54,66 +47,45 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { return; } - - if (param.getTemplateId() == null || param.getAddressId() == null) { + // 1.2 得到收件地址区域 + if (param.getAddressId() == null) { return; } - // 1.2 校验运费模板是否存在 - DeliveryExpressTemplateDO template = deliveryExpressTemplateService.validateDeliveryExpressTemplate(param.getTemplateId()); - - // 得到包邮配置 - List expressTemplateFreeList = templateFreeMapper.selectListByTemplateId(template.getId()); - Map areaTemplateFreeMap = new HashMap<>(); - expressTemplateFreeList.forEach(item -> { - for (Integer areaId : item.getAreaIds()) { - // TODO 需要保证 areaId 不能重复 - if (!areaTemplateFreeMap.containsKey(areaId)) { - areaTemplateFreeMap.put(areaId, item); - } - } - }); - // 得到快递运费配置 - List expressTemplateChargeList = templateChargeMapper.selectListByTemplateId(template.getId()); - Map areaTemplateChargeMap = new HashMap<>(); - expressTemplateChargeList.forEach(item -> { - for (Integer areaId : item.getAreaIds()) { - // areaId 不能重复 - if (!areaTemplateChargeMap.containsKey(areaId)) { - areaTemplateChargeMap.put(areaId, item); - } - } - }); - // 得到收件地址区域 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); - // 1.3 计算快递费用 - calculateDeliveryPrice(address.getAreaId(), template.getChargeMode(), - areaTemplateFreeMap, areaTemplateChargeMap, result); + Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); + + //1.3 过滤出已选中的商品SKU + List selectedItem = filterList(result.getItems(), OrderItem::getSelected); + + Map spuExpressTemplateMap = + deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea( + convertSet(selectedItem, OrderItem::getSpuId), address.getAreaId()); + + // 1.4 计算配送费用 + if (CollUtil.isNotEmpty(spuExpressTemplateMap)) { + calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); + } + } - /** - * 校验订单是否满足包邮条件 - * - * @param receiverAreaId 收件人地区的区域编号 - * @param chargeMode 配送计费方式 - * @param areaTemplateFreeMap 运费模板包邮区域设置 Map - * @param areaTemplateChargeMap 运费模板快递费用设置 Map - */ - private void calculateDeliveryPrice(Integer receiverAreaId, - Integer chargeMode, - Map areaTemplateFreeMap, - Map areaTemplateChargeMap, + private void calculateDeliveryPrice(List selectedSkus, + Map spuExpressTemplateMap, TradePriceCalculateRespBO result) { - // 过滤出已选中的商品SKU - List selectedItem = filterList(result.getItems(), OrderItem::getSelected); - Set skuIds = convertSet(selectedItem, OrderItem::getSkuId); + Set skuIds = convertSet(selectedSkus, OrderItem::getSkuId); // 得到SKU 详情。得到 重量体积 Map skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId); - // 一个 spuId 可能对应多条订单商品 SKU - // TODO @jason:得确认下,按照 sku 算,还是 spu 算; - Map> spuIdItemMap = convertMultiMap(selectedItem, OrderItem::getSpuId); + // 按spu 来计算商品的运费 一个 spuId 可能对应多条订单商品 SKU, + Map> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId); + // 依次计算每个 SPU 的快递运费 for (Map.Entry> entry : spuIdItemMap.entrySet()) { + Long spuId = entry.getKey(); List orderItems = entry.getValue(); + SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId); + if (templateBO == null) { + // 记录错误日志 + continue; + } // 总件数, 总金额, 总重量, 总体积 int totalCount = 0; int totalPrice = 0; @@ -121,51 +93,67 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { double totalVolume = 0; for (OrderItem orderItem : orderItems) { totalCount += orderItem.getCount(); - totalPrice += orderItem.getPrice(); // TODO jason:应该按照 payPrice? + totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下 ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId()); if (skuResp != null) { - totalWeight = totalWeight + skuResp.getWeight(); // TODO @jason:* 数量 - totalVolume = totalVolume + skuResp.getVolume(); + totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount(); + totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount(); } } // 优先判断是否包邮. 如果包邮不计算快递运费 - if (areaTemplateFreeMap.containsKey(receiverAreaId) && - checkExpressFree(chargeMode, totalCount, totalWeight, - totalVolume, totalPrice, areaTemplateFreeMap.get(receiverAreaId))) { + if (checkExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, + totalVolume, totalPrice, templateBO.getTemplateFree())) { + continue; + } + if (templateBO.getTemplateCharge() == null) { continue; } // 计算快递运费 - // TODO @jason:貌似也可以抽成 checkExpressFree 类似方法 - if (areaTemplateChargeMap.containsKey(receiverAreaId)) { - DeliveryExpressTemplateChargeDO templateCharge = areaTemplateChargeMap.get(receiverAreaId); - DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); - switch (chargeModeEnum) { - case PIECE: { - calculateExpressFeeBySpu(totalCount, templateCharge, orderItems); - break; - } - case WEIGHT: { - calculateExpressFeeBySpu(totalWeight, templateCharge, orderItems); - break; - } - case VOLUME: { - calculateExpressFeeBySpu(totalVolume, templateCharge, orderItems); - break; - } - } - } + calculateExpressFeeByChargeMode(totalCount, totalWeight, totalVolume, + templateBO.getChargeMode(), templateBO.getTemplateCharge(), orderItems); + } TradePriceCalculatorHelper.recountAllPrice(result); } /** - * 按 spu 来计算快递费用 + * 按配送方式来计算运费 + * + * @param totalCount 总件数 + * @param totalWeight 总重量 + * @param totalVolume 总体积 + * @param chargeMode 配送计费方式 + * @param templateCharge 快递运费配置 + * @param orderItems SKU 商品项目 + */ + private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume, + int chargeMode, DeliveryExpressTemplateChargeDO templateCharge, + List orderItems) { + DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); + switch (chargeModeEnum) { + case PIECE: { + calculateExpressFee(totalCount, templateCharge, orderItems); + break; + } + case WEIGHT: { + calculateExpressFee(totalWeight, templateCharge, orderItems); + break; + } + case VOLUME: { + calculateExpressFee(totalVolume, templateCharge, orderItems); + break; + } + } + } + + /** + * 计算 SKU 商品快递费用 * * @param total 总件数/总重量/总体积 * @param templateCharge 快递运费配置 * @param orderItems SKU 商品项目 */ - private void calculateExpressFeeBySpu(double total, DeliveryExpressTemplateChargeDO templateCharge, List orderItems) { + private void calculateExpressFee(double total, DeliveryExpressTemplateChargeDO templateCharge, List orderItems) { int deliveryPrice; if (total <= templateCharge.getStartCount()) { deliveryPrice = templateCharge.getStartPrice(); @@ -176,8 +164,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { int extraPrice = templateCharge.getExtraPrice() * extraNum; deliveryPrice = templateCharge.getStartPrice() + extraPrice; } - // TODO @芋艿 分摊快递费用到 SKU. 是不是搞复杂了; - // TODO @jason:因为退费的时候,可能按照 SKU 考虑退费金额 + // 分摊快递费用到 SKU. 退费的时候,可能按照 SKU 考虑退费金额 divideDeliveryPrice(deliveryPrice, orderItems); } @@ -207,6 +194,9 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { */ private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight, double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) { + if (templateFree == null) { + return false; + } DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); switch (chargeModeEnum) { case PIECE: From db7e47faa2b8a00ae531beb166bba4859ef1423a Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 7 Jun 2023 14:15:25 +0800 Subject: [PATCH 083/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=20TODO?= =?UTF-8?q?=20=E6=8F=90=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao-module-product-biz/pom.xml | 11 +- .../app/spu/AppProductSpuController.java | 31 +---- .../property/ProductPropertyDO.java | 10 +- .../property/ProductPropertyValueDO.java | 10 +- .../dal/mysql/sku/ProductSkuMapper.java | 22 ---- .../category/ProductCategoryServiceImpl.java | 13 +- .../comment/ProductCommentServiceImpl.java | 20 ++++ .../property/ProductPropertyServiceImpl.java | 4 +- .../ProductPropertyValueServiceImpl.java | 6 +- .../service/sku/ProductSkuService.java | 12 +- .../service/sku/ProductSkuServiceImpl.java | 112 +++++++----------- .../service/spu/ProductSpuService.java | 8 ++ .../service/spu/ProductSpuServiceImpl.java | 60 +++++++--- .../module/trade/api/order/TradeOrderApi.java | 20 ++++ .../api/order/dto/TradeOrderRespDTO.java | 92 ++++++++++++++ .../yudao/module/trade/api/package-info.java | 1 + .../trade/api/order/TradeOrderApiImpl.java | 28 +++++ .../yudao/module/trade/api/package-info.java | 1 + .../DeliveryExpressTemplateController.java | 6 +- .../DeliveryExpressTemplateSimpleRespVO.java | 21 ++++ .../DeliveryExpressTemplateConvert.java | 4 +- .../convert/order/TradeOrderConvert.java | 3 + 22 files changed, 328 insertions(+), 167 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index b04e03208..386ef51c6 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -23,7 +23,11 @@ yudao-module-product-api ${revision} - + + cn.iocoder.boot + yudao-module-trade-api + ${revision} + cn.iocoder.boot yudao-module-member-api @@ -35,11 +39,6 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 0e173f902..6d03ce59d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -5,14 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -25,12 +19,8 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.List; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; @Tag(name = "用户 APP - 商品 SPU") @RestController @@ -40,10 +30,6 @@ public class AppProductSpuController { @Resource private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") @@ -56,22 +42,7 @@ public class AppProductSpuController { @Operation(summary = "获得商品 SPU 明细") @Parameter(name = "id", description = "编号", required = true) public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { - throw exception(SPU_NOT_ENABLE); - } - - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuId(spu.getId()); - // 查询商品属性 - List propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); - // 拼接 - return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues)); + return success(productSpuService.getAppProductSpuDetail(id)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index dfe666e1f..e7e3c8ba6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -22,6 +21,15 @@ import lombok.*; @AllArgsConstructor public class ProductPropertyDO extends BaseDO { + /** + * 默认属性id + */ + public static final Long PROPERTY_ID = 0L; + /** + * 默认属性名字 + */ + public static final String PROPERTY_NAME = "默认"; + /** * 主键 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index 80756bc5a..a632c8f11 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -23,6 +22,15 @@ import lombok.*; @AllArgsConstructor public class ProductPropertyValueDO extends BaseDO { + /** + * 默认属性值id + */ + public static final Long VALUE_ID = 0L; + /** + * 默认属性值名字 + */ + public static final String VALUE_NAME = "默认"; + /** * 主键 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 0b6ef5ed0..6da00caf4 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -1,12 +1,9 @@ package cn.iocoder.yudao.module.product.dal.mysql.sku; import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -63,23 +60,4 @@ public interface ProductSkuMapper extends BaseMapperX { return selectList(new QueryWrapper().apply("stock <= warn_stock")); } - // TODO @puhui999:貌似 IN 不出来数据哈。直接全部查询出来,处理就好列; - /** - * 更新 sku 属性值时使用的分页查询 - * - * @param pageParam 页面参数 - * @return {@link PageResult}<{@link ProductSkuDO}> - */ - default PageResult selectPage(PageParam pageParam) { - return selectPage(pageParam, new LambdaQueryWrapper().isNotNull(ProductSkuDO::getProperties)); - } - - /** - * 查询 sku properties 不等于 null 的数量 - * - * @return {@link Long} - */ - default Long selectCountByPropertyNotNull() { - return selectCount(new LambdaQueryWrapper().isNotNull(ProductSkuDO::getProperties)); - } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index ab4f127ba..7e64c802d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -68,7 +68,10 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { throw exception(CATEGORY_EXISTS_CHILDREN); } // 校验分类是否绑定了 SPU - validateProductCategoryIsHaveBindSpu(id); + Long count = productSpuService.getSpuCountByCategoryId(id); + if (0 != count) { + throw exception(CATEGORY_HAVE_BIND_SPU); + } // 删除 productCategoryMapper.deleteById(id); } @@ -96,14 +99,6 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } } - // TODO @puhui999:不用抽方法,因为不太会复用这个方法哈。 - private void validateProductCategoryIsHaveBindSpu(Long id) { - Long count = productSpuService.getSpuCountByCategoryId(id); - if (0 != count) { - throw exception(CATEGORY_HAVE_BIND_SPU); - } - } - @Override public ProductCategoryDO getCategory(Long id) { return productCategoryMapper.selectById(id); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 2fe331d59..f16f85871 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -8,7 +8,11 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; +import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; @@ -18,6 +22,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; /** * 商品评论 Service 实现类 @@ -30,6 +35,11 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Resource private ProductCommentMapper productCommentMapper; + @Resource + private TradeOrderApi tradeOrderApi; + + @Resource + private ProductSpuService productSpuService; @Override public PageResult getCommentPage(ProductCommentPageReqVO pageReqVO) { @@ -60,6 +70,16 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override public void createComment(ProductCommentDO productComment, Boolean system) { if (!system) { + // TODO 判断订单是否存在 fix + TradeOrderRespDTO order = tradeOrderApi.getOrder(productComment.getOrderId()); + if (null == order) { + throw exception(ORDER_NOT_FOUND); + } + // TODO 判断 SPU 是否存在 fix + ProductSpuDO spu = productSpuService.getSpu(productComment.getSpuId()); + if (null == spu) { + throw exception(SPU_NOT_EXISTS); + } // 判断当前订单的当前商品用户是否评价过 ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId()); if (null != exist) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index 518b1065c..44bf95e71 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -71,8 +71,8 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { // 更新 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); productPropertyMapper.updateById(updateObj); - // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈 - productSkuService.updateSkuProperty(updateObj); + // 更新 sku 相关属性 + productSkuService.updateSkuProperty(updateObj.getId(), updateObj.getName()); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index 2666f13f4..6b4d1e9c8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -73,10 +73,8 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ // 更新 ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); productPropertyValueMapper.updateById(updateObj); - - // TODO 芋艿:更新时,需要看看 sku 表 fix - // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈 - productSkuService.updateSkuPropertyValue(updateObj); + // 更新 sku 相关属性 + productSkuService.updateSkuPropertyValue(updateObj.getId(), updateObj.getName()); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index f66b9d829..9ee2c00a2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import java.util.Collection; @@ -111,16 +109,18 @@ public interface ProductSkuService { /** * 更新 sku 属性 * - * @param updateObj 属性对象 + * @param propertyId 属性 id + * @param propertyName 属性名 * @return int 影响的行数 */ - int updateSkuProperty(ProductPropertyDO updateObj); + int updateSkuProperty(Long propertyId, String propertyName); /** * 更新 sku 属性值 * - * @param updateObj 属性值对象 + * @param propertyValueId 属性值 id + * @param propertyValueName 属性值名字 * @return int 影响的行数 */ - int updateSkuPropertyValue(ProductPropertyValueDO updateObj); + int updateSkuPropertyValue(Long propertyValueId, String propertyValueName); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 8e0a1c9a1..6b317bf22 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.product.service.sku; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; @@ -80,16 +79,25 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Override public void validateSkuList(List skus, Boolean specType) { - // 非多规格,不需要校验 - if (ObjectUtil.notEqual(specType, true)) { - return; - } - // 0、校验skus是否为空 if (CollUtil.isEmpty(skus)) { throw exception(SKU_NOT_EXISTS); } - + // 单规格处理 + if (ObjectUtil.equal(specType, false)) { + ProductSkuCreateOrUpdateReqVO skuVO = skus.get(0); + // 赋予单规格默认属性 + List properties = new ArrayList<>(); + ProductSkuBaseVO.Property property = new ProductSkuBaseVO.Property(); + property.setPropertyId(ProductPropertyDO.PROPERTY_ID); + property.setPropertyName(ProductPropertyDO.PROPERTY_NAME); + property.setValueId(ProductPropertyValueDO.VALUE_ID); + property.setValueName(ProductPropertyValueDO.VALUE_NAME); + properties.add(property); + skuVO.setProperties(properties); + // 单规格不需要后续的校验 + return; + } // 1、校验属性项存在 Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) // 遍历多个 Property 属性 @@ -156,81 +164,51 @@ public class ProductSkuServiceImpl implements ProductSkuService { } @Override - public int updateSkuProperty(ProductPropertyDO updateObj) { - // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 - // TODO @puhui999:直接全部查询处理,批量处理就好列;一般项目的商品不会超过几十万的哈。 - Long count = productSkuMapper.selectCountByPropertyNotNull(); - int currentPage = 1; + public int updateSkuProperty(Long propertyId, String propertyName) { + // 获取所有的 sku + List skuDOList = productSkuMapper.selectList(); + // 处理后需要更新的 sku List updateSkus = new ArrayList<>(); - if (count == 0) { + if (CollUtil.isEmpty(skuDOList)) { return 0; } - int pageSize = 100; - for (int i = 0; i <= count / 100; i++) { - PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize); - // 分页查找出 sku 属性不为 null 的 - PageResult skuPage = productSkuMapper.selectPage(pageParam); - List records = skuPage.getList(); - if (CollUtil.isEmpty(records)) { - break; - } - records.stream().filter(sku -> sku.getProperties() != null) - .forEach(sku -> sku.getProperties().forEach(property -> { - if (property.getPropertyId().equals(updateObj.getId())) { - property.setPropertyName(updateObj.getName()); - updateSkus.add(sku); - } - })); - } + skuDOList.stream().filter(sku -> sku.getProperties() != null) + .forEach(sku -> sku.getProperties().forEach(property -> { + if (property.getPropertyId().equals(propertyId)) { + property.setPropertyName(propertyName); + updateSkus.add(sku); + } + })); if (CollUtil.isEmpty(updateSkus)) { return 0; } - // TODO @puhui999:貌似 updateBatch 自己会拆分批次,这里不用再拆分了 - // 每批处理的大小 - int batchSize = 1000; - for (int i = 0; i < updateSkus.size(); i += batchSize) { - List batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size())); - productSkuMapper.updateBatch(batchSkuDOs, batchSize); - } + + productSkuMapper.updateBatch(updateSkus); return updateSkus.size(); } @Override - public int updateSkuPropertyValue(ProductPropertyValueDO updateObj) { - // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现 - Long count = productSkuMapper.selectCountByPropertyNotNull(); - int currentPage = 1; + public int updateSkuPropertyValue(Long propertyValueId, String propertyValueName) { + // 获取所有的 sku + List skuDOList = productSkuMapper.selectList(); + // 处理后需要更新的 sku List updateSkus = new ArrayList<>(); - if (count == 0) { + if (CollUtil.isEmpty(skuDOList)) { return 0; } - int pageSize = 100; - for (int i = 0; i <= count / 100; i++) { - PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize); - // 分页查找出 sku 属性不为 null 的 - PageResult skuPage = productSkuMapper.selectPage(pageParam); - List records = skuPage.getList(); - if (CollUtil.isEmpty(records)) { - break; - } - records.stream() - .filter(sku -> sku.getProperties() != null) - .forEach(sku -> sku.getProperties().forEach(property -> { - if (property.getValueId().equals(updateObj.getId())) { - property.setValueName(updateObj.getName()); - updateSkus.add(sku); - } - })); - } + skuDOList.stream() + .filter(sku -> sku.getProperties() != null) + .forEach(sku -> sku.getProperties().forEach(property -> { + if (property.getValueId().equals(propertyValueId)) { + property.setValueName(propertyValueName); + updateSkus.add(sku); + } + })); if (CollUtil.isEmpty(updateSkus)) { return 0; } - // 每批处理的大小 - int batchSize = 1000; - for (int i = 0; i < updateSkus.size(); i += batchSize) { - List batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size())); - productSkuMapper.updateBatch(batchSkuDOs, batchSize); - } + + productSkuMapper.updateBatch(updateSkus); return updateSkus.size(); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 5eeca1adb..be6851191 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -135,4 +136,11 @@ public interface ProductSpuService { */ Long getSpuCountByCategoryId(Long id); + /** + * 通过 spu id 获取商品 SPU 明细 + * + * @param id id + * @return 用户 App - 商品 SPU 明细 + */ + AppProductSpuDetailRespVO getAppProductSpuDetail(Long id); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 78e9ba62c..b83114eab 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -7,15 +7,21 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -50,6 +56,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { private ProductBrandService brandService; @Resource private ProductCategoryService categoryService; + @Resource + @Lazy // 循环依赖,避免报错 + private ProductPropertyValueService productPropertyValueService; @Override @Transactional(rollbackFor = Exception.class) @@ -140,7 +149,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 校验存在 validateSpuExists(id); // 校验商品状态不是回收站不能删除 - validateSpuStatus(id); + ProductSpuDO spuDO = productSpuMapper.selectById(id); + // 判断 SPU 状态是否为回收站 + if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) { + throw exception(SPU_NOT_RECYCLE); + } // 删除 SPU productSpuMapper.deleteById(id); @@ -154,20 +167,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { } } - /** - * 验证 SPU 状态是否为回收站 - * - * @param id id - */ - // TODO puhui999:感觉不用独立出来一个方法,直接在 deleteSpu 方法中校验即可 - private void validateSpuStatus(Long id) { - ProductSpuDO spuDO = productSpuMapper.selectById(id); - // 判断 SPU 状态是否为回收站 - if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) { - throw exception(SPU_NOT_RECYCLE); - } - } - @Override public ProductSpuDO getSpu(Long id) { return productSpuMapper.selectById(id); @@ -257,4 +256,35 @@ public class ProductSpuServiceImpl implements ProductSpuService { return productSpuMapper.selectCount(ProductSpuDO::getCategoryId, id); } + @Override + public AppProductSpuDetailRespVO getAppProductSpuDetail(Long id) { + // 获得商品 SPU + ProductSpuDO spu = getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { + throw exception(SPU_NOT_ENABLE); + } + + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuId(spu.getId()); + List propertyValues = new ArrayList<>(); + // 单规格商品 赋予默认属性值 + if (ObjectUtil.equal(spu.getSpecType(), false)) { + ProductPropertyValueDetailRespBO respBO = new ProductPropertyValueDetailRespBO(); + respBO.setPropertyId(ProductPropertyDO.PROPERTY_ID); + respBO.setPropertyName(ProductPropertyDO.PROPERTY_NAME); + respBO.setValueId(ProductPropertyValueDO.VALUE_ID); + respBO.setValueName(ProductPropertyValueDO.VALUE_NAME); + propertyValues.add(respBO); + } else { + // 多规格商品则查询商品属性 + propertyValues = productPropertyValueService + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); + } + // 拼接 + return ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues); + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java new file mode 100644 index 000000000..8dc2aaced --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.api.order; + +import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; + +/** + * 订单 API 接口 + * + * @author HUIHUI + */ +public interface TradeOrderApi { + + /** + * 获取订单通过订单 id + * + * @param id id + * @return 订单信息 Response DTO + */ + TradeOrderRespDTO getOrder(Long id); + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java new file mode 100644 index 000000000..b9d362407 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java @@ -0,0 +1,92 @@ +package cn.iocoder.yudao.module.trade.api.order.dto; + +import cn.iocoder.yudao.framework.common.enums.TerminalEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 订单信息 Response DTO + * + * @author HUIHUI + */ +@Data +public class TradeOrderRespDTO { + + // ========== 订单基本信息 ========== + /** + * 订单编号,主键自增 + */ + private Long id; + /** + * 订单流水号 + *

+ * 例如说,1146347329394184195 + */ + private String no; + /** + * 订单类型 + *

+ * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer type; + /** + * 订单来源 + *

+ * 枚举 {@link TerminalEnum} + */ + private Integer terminal; + /** + * 用户编号 + *

+ * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 用户 IP + */ + private String userIp; + /** + * 用户备注 + */ + private String userRemark; + /** + * 订单状态 + *

+ * 枚举 {@link TradeOrderStatusEnum} + */ + private Integer status; + /** + * 购买的商品数量 + */ + private Integer productCount; + /** + * 订单完成时间 + */ + private LocalDateTime finishTime; + /** + * 订单取消时间 + */ + private LocalDateTime cancelTime; + /** + * 取消类型 + *

+ * 枚举 {@link TradeOrderCancelTypeEnum} + */ + private Integer cancelType; + /** + * 商家备注 + */ + private String remark; + /** + * 是否评价 + *

+ * true - 已评价 + * false - 未评价 + */ + private Boolean commentStatus; + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java new file mode 100644 index 000000000..5b0e37dcc --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.trade.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java new file mode 100644 index 000000000..3abdb2a9d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.api.order; + +import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 订单 API 接口实现类 + * + * @author HUIHUI + */ +@Service +@Validated +public class TradeOrderApiImpl implements TradeOrderApi { + + @Resource + private TradeOrderService tradeOrderService; + + @Override + public TradeOrderRespDTO getOrder(Long id) { + return TradeOrderConvert.INSTANCE.convert(tradeOrderService.getOrder(id)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java new file mode 100644 index 000000000..5b0e37dcc --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.trade.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 572c04e99..8f87e358e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -70,14 +70,14 @@ public class DeliveryExpressTemplateController { return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); } - // TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈 + // TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈 fix @GetMapping("/list-all-simple") @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项") - public CommonResult> getSimpleTemplateList() { + public CommonResult> getSimpleTemplateList() { // 获取运费模版列表,只要开启状态的 List list = deliveryExpressTemplateService.getDeliveryExpressTemplateList(); // 排序后,返回给前端 - return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); + return success(DeliveryExpressTemplateConvert.INSTANCE.convertList1(list)); } @GetMapping("/page") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java new file mode 100644 index 000000000..37abbd06d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateSimpleRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +@Schema(description = "管理后台 - 模版精简信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DeliveryExpressTemplateSimpleRespVO { + + @Schema(description = "模版编号", required = true, example = "1024") + private Long id; + + @Schema(description = "模板名称", required = true, example = "测试模版") + private String name; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index af247367c..aadaf42f3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -28,11 +28,13 @@ public interface DeliveryExpressTemplateConvert { List convertList(List list); + List convertList1(List list); + PageResult convertPage(PageResult page); default DeliveryExpressTemplateDetailRespVO convert(DeliveryExpressTemplateDO bean, List chargeList, - List freeList){ + List freeList) { DeliveryExpressTemplateDetailRespVO respVO = convert2(bean); respVO.setTemplateCharge(convertTemplateChargeList(chargeList)); respVO.setTemplateFree(convertTemplateFreeList(freeList)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index c53ae4d0a..8c5501b53 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; @@ -62,6 +63,8 @@ public interface TradeOrderConvert { TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address); + TradeOrderRespDTO convert(TradeOrderDO orderDO); + default List convertList(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { return CollectionUtils.convertList(calculateRespBO.getItems(), item -> { TradeOrderItemDO orderItem = convert(item); From 5bfca56efa58d6132086350b205d8a33a6c83d74 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 7 Jun 2023 18:08:49 +0800 Subject: [PATCH 084/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=20TODO?= =?UTF-8?q?=20=E6=8F=90=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao-module-trade-biz/pom.xml | 6 +- .../service/order/TradeOrderServiceImpl.java | 79 ++++++++++++++----- .../api/notify/NotifyMessageSendApi.java | 5 ++ .../api/notify/dto/NotifyTemplateReqDTO.java | 34 ++++++++ .../enums/notify/NotifyTemplateTypeEnum.java | 26 ++++++ .../api/notify/NotifyMessageSendApiImpl.java | 12 ++- 6 files changed, 141 insertions(+), 21 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/dto/NotifyTemplateReqDTO.java create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeEnum.java diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml index 4eb0164d4..24b2097ba 100644 --- a/yudao-module-mall/yudao-module-trade-biz/pom.xml +++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml @@ -23,7 +23,6 @@ yudao-module-trade-api ${revision} - cn.iocoder.boot yudao-module-product-api @@ -44,6 +43,11 @@ yudao-module-member-api ${revision} + + cn.iocoder.boot + yudao-module-system-api + ${revision} + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 8e75dd985..666841eee 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -6,7 +6,9 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.core.KeyValue; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.member.api.address.AddressApi; @@ -21,6 +23,11 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; +import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; +import cn.iocoder.yudao.module.system.api.notify.dto.NotifyTemplateReqDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.enums.notify.NotifyTemplateTypeEnum; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; @@ -29,6 +36,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; @@ -38,6 +46,7 @@ import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.price.TradePriceService; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; @@ -74,6 +83,8 @@ public class TradeOrderServiceImpl implements TradeOrderService { private TradeCartService tradeCartService; @Resource private TradePriceService tradePriceService; + @Resource + private DeliveryExpressService deliveryExpressService; @Resource private ProductSkuApi productSkuApi; @@ -85,7 +96,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { private CouponApi couponApi; @Resource private MemberUserApi memberUserApi; - + @Resource + private AdminUserApi adminUserApi; + @Resource + private NotifyMessageSendApi notifyMessageSendApi; @Resource private TradeOrderProperties tradeOrderProperties; @@ -123,7 +137,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 计算订单价格 * - * @param userId 用户编号 + * @param userId 用户编号 * @param settlementReqVO 结算信息 * @return 订单价格 */ @@ -162,7 +176,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 校验收件地址是否存在 * - * @param userId 用户编号 + * @param userId 用户编号 * @param addressId 收件地址编号 * @return 收件地址 */ @@ -181,7 +195,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); order.setType(TradeOrderTypeEnum.NORMAL.getType()); order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); - order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); + order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? // 支付信息 order.setAdjustPrice(0).setPayed(false); @@ -201,12 +215,12 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 执行创建完创建完订单后的逻辑 - * + *

* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 * - * @param userId 用户编号 - * @param createReqVO 创建订单请求 - * @param tradeOrderDO 交易订单 + * @param userId 用户编号 + * @param createReqVO 创建订单请求 + * @param tradeOrderDO 交易订单 * @param calculateRespBO 订单价格计算结果 */ private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, @@ -265,11 +279,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 校验交易订单满足被支付的条件 - * + *

* 1. 交易订单未支付 * 2. 支付单已支付 * - * @param id 交易订单编号 + * @param id 交易订单编号 * @param payOrderId 支付订单编号 * @return 交易订单 */ @@ -324,8 +338,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) { // 校验并获得交易订单(可发货) TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); - - // TODO 芋艿:logisticsId 校验存在 + // TODO 芋艿:logisticsId 校验存在 发货物流公司 fix + DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId()); + if (deliveryExpress == null) { + throw exception(DELIVERY_EXPRESS_NOT_EXISTS); + } // 更新 TradeOrderDO 状态为已发货,等待收货 int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), @@ -338,8 +355,32 @@ public class TradeOrderServiceImpl implements TradeOrderService { // TODO 芋艿:发送订单变化的消息 - // TODO 芋艿:发送站内信 - + // TODO 芋艿:发送站内信 fix + // 1、获取模版编码为 order_delivery 的模版,判断是否存在 存在放回 true + if (!notifyMessageSendApi.validateNotifyTemplate("order_delivery")) { + // 1、1 站内信模版不存在则创建模版 + NotifyTemplateReqDTO templateReqDTO = new NotifyTemplateReqDTO(); + templateReqDTO.setName("订单发货通知模版"); + templateReqDTO.setCode("order_delivery"); + templateReqDTO.setType(NotifyTemplateTypeEnum.NOTIFICATION_MESSAGE.getType()); // 系统消息 + // 获取操作用户 + // AdminUserRespDTO user = adminUserApi.getUser(userId); + // templateReqDTO.setNickname(user.getNickname()); + templateReqDTO.setNickname(UserTypeEnum.ADMIN.getName()); + templateReqDTO.setContent("订单:{orderId}{msg}"); + templateReqDTO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + notifyMessageSendApi.createNotifyTemplate(templateReqDTO); + } + // 2、构造消息 + Map msgMap = new HashMap<>(); + msgMap.put("orderId", deliveryReqVO.getId()); + msgMap.put("msg", TradeOrderStatusEnum.DELIVERED.getStatus()); + // 2、发送站内信 + notifyMessageSendApi.sendSingleMessageToAdmin( + new NotifySendSingleToUserReqDTO() + .setUserId(userId) + .setTemplateCode("order_delivery") + .setTemplateParams(msgMap)); // TODO 芋艿:OrderLog // TODO 设计:like:是否要单独一个 delivery 发货单表??? @@ -349,7 +390,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 校验交易订单满足被发货的条件 - * + *

* 1. 交易订单未发货 * * @param id 交易订单编号 @@ -363,7 +404,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { } // 校验订单是否是待发货状态 if (!TradeOrderStatusEnum.isUndelivered(order.getStatus()) - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { + || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); } return order; @@ -397,11 +438,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { /** * 校验交易订单满足可售货的条件 - * + *

* 1. 交易订单待收货 * * @param userId 用户编号 - * @param id 交易订单编号 + * @param id 交易订单编号 * @return 交易订单 */ private TradeOrderDO validateOrderReceivable(Long userId, Long id) { @@ -476,7 +517,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, Integer refundPrice) { // 如果退款成功,则 refundPrice 非空 if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()) - && refundPrice == null) { + && refundPrice == null) { throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id)); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java index facedfade..8e816d880 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.api.notify; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; +import cn.iocoder.yudao.module.system.api.notify.dto.NotifyTemplateReqDTO; import javax.validation.Valid; @@ -27,4 +28,8 @@ public interface NotifyMessageSendApi { */ Long sendSingleMessageToMember(@Valid NotifySendSingleToUserReqDTO reqDTO); + + boolean validateNotifyTemplate(String orderDelivery); + + void createNotifyTemplate(NotifyTemplateReqDTO templateReqDTO); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/dto/NotifyTemplateReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/dto/NotifyTemplateReqDTO.java new file mode 100644 index 000000000..09d5b6fff --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/dto/NotifyTemplateReqDTO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.api.notify.dto; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +public class NotifyTemplateReqDTO { + + @NotEmpty(message = "模版名称不能为空") + private String name; + + @NotNull(message = "模版编码不能为空") + private String code; + + @NotNull(message = "模版类型不能为空") + private Integer type; + + @NotEmpty(message = "发送人名称不能为空") + private String nickname; + + @NotEmpty(message = "模版内容不能为空") + private String content; + + @NotNull(message = "状态不能为空") + @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}") + private Integer status; + + private String remark; + +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeEnum.java new file mode 100644 index 000000000..dccfb1977 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeEnum.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.system.enums.notify; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 通知模板类型枚举 + * + * @author HUIHUI + */ +@Getter +@AllArgsConstructor +public enum NotifyTemplateTypeEnum { + + /** + * 系统消息 + */ + SYSTEM_MESSAGE(2), + /** + * 通知消息 + */ + NOTIFICATION_MESSAGE(1); + + private final Integer type; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java index fc5ba1d12..ee169a1c3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.api.notify; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; -import cn.iocoder.yudao.module.system.service.notify.NotifyMessageService; +import cn.iocoder.yudao.module.system.api.notify.dto.NotifyTemplateReqDTO; import cn.iocoder.yudao.module.system.service.notify.NotifySendService; import org.springframework.stereotype.Service; @@ -30,4 +30,14 @@ public class NotifyMessageSendApiImpl implements NotifyMessageSendApi { reqDTO.getTemplateCode(), reqDTO.getTemplateParams()); } + @Override + public boolean validateNotifyTemplate(String orderDelivery) { + return false; + } + + @Override + public void createNotifyTemplate(NotifyTemplateReqDTO templateReqDTO) { + + } + } From 151e58daa1497f1616ae76e0ad32948dda58a38c Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 8 Jun 2023 11:37:49 +0800 Subject: [PATCH 085/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=20app=20?= =?UTF-8?q?=E5=95=86=E5=93=81=E8=AF=84=E8=AE=BA=E9=A1=B5=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E5=88=86=E9=A1=B5=E6=8E=A5=E5=8F=A3=E5=92=8C?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E8=AF=84=E8=AE=BA=E5=88=86=E7=B1=BB=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/comment/AppCommentController.java | 7 ++++ .../app/comment/vo/AppCommentPageReqVO.java | 4 ++ .../dataobject/comment/ProductCommentDO.java | 17 +++++++++ .../mysql/comment/ProductCommentMapper.java | 38 +++++++++++++++++-- .../comment/ProductCommentService.java | 10 +++++ .../comment/ProductCommentServiceImpl.java | 16 ++++++++ 6 files changed, 89 insertions(+), 3 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java index a5621c57a..b4af14ff5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -41,6 +42,12 @@ public class AppCommentController { return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult)); } + @GetMapping("/get-count") + @Operation(summary = "获得商品评价分页 tab count") + public CommonResult> getCommentPage(@Valid Long spuId) { + return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); + } + @PostMapping(value = "/create") @Operation(summary = "创建商品评价") public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index f557d7779..fba876624 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -18,4 +18,8 @@ public class AppCommentPageReqVO extends PageParam { @NotNull(message = "商品SPU编号不能为空") private Long spuId; + @Schema(description = "app 评论页 tab 类型 (0 全部、1 好评、2 中评、3 差评)", example = "0") + @NotNull(message = "商品SPU编号不能为空") + private Integer type; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 6e0bd04fa..1686d8fd5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -28,6 +28,23 @@ import java.util.List; @AllArgsConstructor public class ProductCommentDO extends BaseDO { + /** + * 所有 + */ + public static final Integer ALL = 0; + /** + * 好评 + */ + public static final Integer FAVOURABLE_COMMENT = 1; + /** + * 中评 + */ + public static final Integer MEDIOCRE_COMMENT = 2; + /** + * 差评 + */ + public static final Integer NEGATIVE_COMMENT = 3; + /** * 评论编号,主键自增 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index e378f53ce..98a040b99 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.dal.mysql.comment; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -34,11 +35,33 @@ public interface ProductCommentMapper extends BaseMapperX { .orderByDesc(ProductCommentDO::getId)); } + static void appendTabQuery(LambdaQueryWrapperX queryWrapper, Integer type) { + // 构建好评查询语句 + if (ObjectUtil.equal(type, ProductCommentDO.FAVOURABLE_COMMENT)) { + // 好评计算 (商品评分星级+服务评分星级) >= 8 + queryWrapper.apply("(scores + benefitScores) >= 8"); + } + // 构建中评查询语句 + if (ObjectUtil.equal(type, ProductCommentDO.MEDIOCRE_COMMENT)) { + // 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 + queryWrapper.apply("(scores + benefitScores) > 4 and (scores + benefitScores) < 8"); + } + // 构建差评查询语句 + if (ObjectUtil.equal(type, ProductCommentDO.NEGATIVE_COMMENT)) { + // 差评计算 (商品评分星级+服务评分星级) <= 4 + queryWrapper.apply("(scores + benefitScores) <= 4"); + } + } + default PageResult selectPage(AppCommentPageReqVO reqVO, Boolean visible) { - return selectPage(reqVO, new LambdaQueryWrapperX() + LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId()) - .eqIfPresent(ProductCommentDO::getVisible, visible) - .orderByDesc(ProductCommentDO::getId)); + .eqIfPresent(ProductCommentDO::getVisible, visible); + // 构建评价查询语句 + appendTabQuery(queryWrapper, reqVO.getType()); + // 按评价时间排序最新的显示在前面 + queryWrapper.orderByDesc(ProductCommentDO::getCreateTime); + return selectPage(reqVO, queryWrapper); } default void updateCommentVisible(Long id, Boolean visible) { @@ -74,4 +97,13 @@ public interface ProductCommentMapper extends BaseMapperX { update(null, lambdaUpdateWrapper); } + default Long selectTabCount(Long spuId, Boolean visible, Integer type) { + LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() + .eqIfPresent(ProductCommentDO::getSpuId, spuId) + .eqIfPresent(ProductCommentDO::getVisible, visible); + // 构建评价查询语句 + appendTabQuery(queryWrapper, type); + return selectCount(queryWrapper); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 6f5e1b59f..cdda9e4c1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.Map; + /** * 商品评论 Service 接口 * @@ -68,4 +70,12 @@ public interface ProductCommentService { */ void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO); + /** + * 评论页面标签数 + * + * @param spuId spu id + * @param visible 是否可见 + * @return 获得商品评价分页 tab count + */ + Map getCommentPageTabsCount(Long spuId, Boolean visible); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index f16f85871..38dc20840 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -18,6 +18,8 @@ import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -62,6 +64,20 @@ public class ProductCommentServiceImpl implements ProductCommentService { productCommentMapper.commentReply(replyVO, loginUserId); } + @Override + public Map getCommentPageTabsCount(Long spuId, Boolean visible) { + Map countMap = new HashMap<>(4); + // 查询商品 id = spuId 的所有评论数量 + countMap.put("allCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.ALL)); + // 查询商品 id = spuId 的所有好评数量 + countMap.put("favourableCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.FAVOURABLE_COMMENT)); + // 查询商品 id = spuId 的所有中评数量 + countMap.put("mediocreCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.MEDIOCRE_COMMENT)); + // 查询商品 id = spuId 的所有差评数量 + countMap.put("negativeCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.NEGATIVE_COMMENT)); + return countMap; + } + @Override public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { return productCommentMapper.selectPage(pageVO, visible); From 8f7efbe4e2e5e0db21b0efd7a4289fd66012ee92 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 8 Jun 2023 16:14:23 +0800 Subject: [PATCH 086/232] =?UTF-8?q?fix=EF=BC=9A=E6=B5=8B=E8=AF=95=20app=20?= =?UTF-8?q?=E5=95=86=E5=93=81=E8=AF=84=E8=AE=BA=E9=A1=B5=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E5=88=86=E9=A1=B5=E6=8E=A5=E5=8F=A3=E5=92=8C?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E8=AF=84=E8=AE=BA=E5=88=86=E7=B1=BB=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=8E=A5=E5=8F=A3=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=97=B6=E5=8F=91=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/comment/AppCommentController.java | 4 +- .../app/comment/vo/AppCommentRespVO.java | 7 +-- .../dataobject/comment/ProductCommentDO.java | 28 ++++++++++ .../mysql/comment/ProductCommentMapper.java | 6 +-- .../comment/ProductCommentService.java | 3 +- .../comment/ProductCommentServiceImpl.java | 28 +++++++--- .../ProductCommentServiceImplTest.java | 53 +++++++++++++++++-- 7 files changed, 110 insertions(+), 19 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java index b4af14ff5..e1f1df3ea 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreat import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -38,8 +37,7 @@ public class AppCommentController { @GetMapping("/page") @Operation(summary = "获得商品评价分页") public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { - PageResult pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE); - return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult)); + return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); } @GetMapping("/get-count") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java index 43aeb2355..cd532ed4c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java @@ -5,7 +5,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; @@ -27,7 +26,7 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "订单项编号", required = true, example = "24965") private Long id; - @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true) + @Schema(description = "是否匿名", required = true) private Boolean anonymous; @Schema(description = "交易订单编号", required = true, example = "24428") @@ -36,7 +35,7 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "交易订单项编号", required = true, example = "8233") private Long orderItemId; - @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) + @Schema(description = "商家是否回复", required = true) private Boolean replied; @Schema(description = "回复管理员编号", example = "22212") @@ -60,4 +59,6 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "创建时间", required = true) private LocalDateTime createTime; + @Schema(description = "最终评分", required = true) + private Integer finalScore; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 1686d8fd5..d867b2128 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -32,19 +32,47 @@ public class ProductCommentDO extends BaseDO { * 所有 */ public static final Integer ALL = 0; + + /** + * 所有数量 key + */ + public static final String ALL_COUNT = "allCount"; + /** * 好评 */ public static final Integer FAVOURABLE_COMMENT = 1; + + /** + * 好评数量 key + */ + public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount"; + /** * 中评 */ public static final Integer MEDIOCRE_COMMENT = 2; + + /** + * 中评数量 key + */ + public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount"; + /** * 差评 */ public static final Integer NEGATIVE_COMMENT = 3; + /** + * 差评数量 key + */ + public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; + + /** + * 默认匿名昵称 + */ + public static final String ANONYMOUS_NICKNAME = "匿名用户"; + /** * 评论编号,主键自增 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index 98a040b99..d836d0758 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -39,17 +39,17 @@ public interface ProductCommentMapper extends BaseMapperX { // 构建好评查询语句 if (ObjectUtil.equal(type, ProductCommentDO.FAVOURABLE_COMMENT)) { // 好评计算 (商品评分星级+服务评分星级) >= 8 - queryWrapper.apply("(scores + benefitScores) >= 8"); + queryWrapper.apply("(scores + benefit_scores) >= 8"); } // 构建中评查询语句 if (ObjectUtil.equal(type, ProductCommentDO.MEDIOCRE_COMMENT)) { // 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 - queryWrapper.apply("(scores + benefitScores) > 4 and (scores + benefitScores) < 8"); + queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8"); } // 构建差评查询语句 if (ObjectUtil.equal(type, ProductCommentDO.NEGATIVE_COMMENT)) { // 差评计算 (商品评分星级+服务评分星级) <= 4 - queryWrapper.apply("(scores + benefitScores) <= 4"); + queryWrapper.apply("(scores + benefit_scores) <= 4"); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index cdda9e4c1..0c315b94f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -52,7 +53,7 @@ public interface ProductCommentService { * @param visible 是否可见 * @return 商品评价分页 */ - PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); + PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); /** * 创建商品评论 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 38dc20840..0ec70a4e6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.service.comment; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; @@ -7,6 +8,8 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; @@ -18,6 +21,8 @@ import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -68,19 +73,30 @@ public class ProductCommentServiceImpl implements ProductCommentService { public Map getCommentPageTabsCount(Long spuId, Boolean visible) { Map countMap = new HashMap<>(4); // 查询商品 id = spuId 的所有评论数量 - countMap.put("allCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.ALL)); + countMap.put(ProductCommentDO.ALL_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.ALL)); // 查询商品 id = spuId 的所有好评数量 - countMap.put("favourableCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.FAVOURABLE_COMMENT)); + countMap.put(ProductCommentDO.FAVOURABLE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.FAVOURABLE_COMMENT)); // 查询商品 id = spuId 的所有中评数量 - countMap.put("mediocreCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.MEDIOCRE_COMMENT)); + countMap.put(ProductCommentDO.MEDIOCRE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.MEDIOCRE_COMMENT)); // 查询商品 id = spuId 的所有差评数量 - countMap.put("negativeCommentCount", productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.NEGATIVE_COMMENT)); + countMap.put(ProductCommentDO.NEGATIVE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.NEGATIVE_COMMENT)); return countMap; } @Override - public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { - return productCommentMapper.selectPage(pageVO, visible); + public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { + PageResult result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); + result.getList().forEach(item -> { + // 判断用户是否选择匿名 + if (ObjectUtil.equal(item.getAnonymous(), true)) { + item.setUserNickname(ProductCommentDO.ANONYMOUS_NICKNAME); + } + // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 + BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores()); + BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN); + item.setFinalScore(divide.intValue()); + }); + return result; } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index af1d529d8..2b51f81d3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -11,15 +11,22 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Lazy; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.Date; +import java.util.Map; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; @@ -39,8 +46,14 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { private ProductCommentMapper productCommentMapper; @Resource + @Lazy private ProductCommentServiceImpl productCommentService; + @MockBean + private TradeOrderApi tradeOrderApi; + @MockBean + private ProductSpuService productSpuService; + public String generateNo() { return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); } @@ -70,6 +83,23 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setScores(ProductCommentScoresEnum.FOUR.getScores()); o.setReplied(Boolean.TRUE); o.setVisible(Boolean.TRUE); + o.setId(generateId()); + o.setUserId(generateId()); + o.setAnonymous(Boolean.TRUE); + o.setOrderId(generateId()); + o.setOrderItemId(generateId()); + o.setSpuId(generateId()); + o.setSkuId(generateId()); + o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores()); + o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores()); + o.setDeliveryScores(ProductCommentScoresEnum.FOUR.getScores()); + o.setContent("真好吃"); + o.setReplyUserId(generateId()); + o.setReplyContent("确实"); + o.setReplyTime(LocalDateTime.now()); + o.setAdditionalTime(LocalDateTime.now()); + o.setCreateTime(LocalDateTime.now()); + o.setUpdateTime(LocalDateTime.now()); }); productCommentMapper.insert(productComment); @@ -77,7 +107,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { Long spuId = productComment.getSpuId(); // 测试 userNickname 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三"))); + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三").setScores(ProductCommentScoresEnum.ONE.getScores()))); // 测试 orderId 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setOrderId(generateId()))); // 测试 spuId 不匹配 @@ -107,8 +137,25 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); assertEquals(8, all.getTotal()); - PageResult visible = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); - assertEquals(7, visible.getTotal()); + // 测试获取所有商品分页评论数据 + PageResult result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); + assertEquals(7, result1.getTotal()); + + // 测试获取所有商品分页中评数据 + PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(ProductCommentDO.MEDIOCRE_COMMENT), Boolean.TRUE); + assertEquals(2, result2.getTotal()); + + // 测试获取指定 spuId 商品分页中评数据 + PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(ProductCommentDO.MEDIOCRE_COMMENT), Boolean.TRUE); + assertEquals(2, result3.getTotal()); + + // 测试分页 tab count + Map tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE); + assertEquals(6, tabsCount.get(ProductCommentDO.ALL_COUNT)); + assertEquals(4, tabsCount.get(ProductCommentDO.FAVOURABLE_COMMENT_COUNT)); + assertEquals(2, tabsCount.get(ProductCommentDO.MEDIOCRE_COMMENT_COUNT)); + assertEquals(0, tabsCount.get(ProductCommentDO.NEGATIVE_COMMENT_COUNT)); + } @Test From 91e357e59d3058217872c9ca9f2ad122ffaa7fef Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 8 Jun 2023 17:15:37 +0800 Subject: [PATCH 087/232] =?UTF-8?q?fix=EF=BC=9A=E7=A7=BB=E5=8A=A8=20app=20?= =?UTF-8?q?=E5=95=86=E5=93=81=E8=AF=84=E8=AE=BA=E5=88=86=E9=A1=B5=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=B8=B8=E9=87=8F=E5=88=B0=20AppCommentPageReqVO=20?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/comment/vo/AppCommentPageReqVO.java | 45 +++++++++++++++++++ .../dataobject/comment/ProductCommentDO.java | 45 ------------------- .../mysql/comment/ProductCommentMapper.java | 6 +-- .../comment/ProductCommentServiceImpl.java | 10 ++--- .../ProductCommentServiceImplTest.java | 12 ++--- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index fba876624..8dbff09c3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -14,6 +14,51 @@ import javax.validation.constraints.NotNull; @ToString(callSuper = true) public class AppCommentPageReqVO extends PageParam { + /** + * 所有 + */ + public static final Integer ALL = 0; + + /** + * 所有数量 key + */ + public static final String ALL_COUNT = "allCount"; + + /** + * 好评 + */ + public static final Integer FAVOURABLE_COMMENT = 1; + + /** + * 好评数量 key + */ + public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount"; + + /** + * 中评 + */ + public static final Integer MEDIOCRE_COMMENT = 2; + + /** + * 中评数量 key + */ + public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount"; + + /** + * 差评 + */ + public static final Integer NEGATIVE_COMMENT = 3; + + /** + * 差评数量 key + */ + public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; + + /** + * 默认匿名昵称 + */ + public static final String ANONYMOUS_NICKNAME = "匿名用户"; + @Schema(description = "商品SPU编号", example = "29502") @NotNull(message = "商品SPU编号不能为空") private Long spuId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index d867b2128..6e0bd04fa 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -28,51 +28,6 @@ import java.util.List; @AllArgsConstructor public class ProductCommentDO extends BaseDO { - /** - * 所有 - */ - public static final Integer ALL = 0; - - /** - * 所有数量 key - */ - public static final String ALL_COUNT = "allCount"; - - /** - * 好评 - */ - public static final Integer FAVOURABLE_COMMENT = 1; - - /** - * 好评数量 key - */ - public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount"; - - /** - * 中评 - */ - public static final Integer MEDIOCRE_COMMENT = 2; - - /** - * 中评数量 key - */ - public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount"; - - /** - * 差评 - */ - public static final Integer NEGATIVE_COMMENT = 3; - - /** - * 差评数量 key - */ - public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; - - /** - * 默认匿名昵称 - */ - public static final String ANONYMOUS_NICKNAME = "匿名用户"; - /** * 评论编号,主键自增 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index d836d0758..b010167cc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -37,17 +37,17 @@ public interface ProductCommentMapper extends BaseMapperX { static void appendTabQuery(LambdaQueryWrapperX queryWrapper, Integer type) { // 构建好评查询语句 - if (ObjectUtil.equal(type, ProductCommentDO.FAVOURABLE_COMMENT)) { + if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) { // 好评计算 (商品评分星级+服务评分星级) >= 8 queryWrapper.apply("(scores + benefit_scores) >= 8"); } // 构建中评查询语句 - if (ObjectUtil.equal(type, ProductCommentDO.MEDIOCRE_COMMENT)) { + if (ObjectUtil.equal(type, AppCommentPageReqVO.MEDIOCRE_COMMENT)) { // 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8"); } // 构建差评查询语句 - if (ObjectUtil.equal(type, ProductCommentDO.NEGATIVE_COMMENT)) { + if (ObjectUtil.equal(type, AppCommentPageReqVO.NEGATIVE_COMMENT)) { // 差评计算 (商品评分星级+服务评分星级) <= 4 queryWrapper.apply("(scores + benefit_scores) <= 4"); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 0ec70a4e6..edec1c651 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -73,13 +73,13 @@ public class ProductCommentServiceImpl implements ProductCommentService { public Map getCommentPageTabsCount(Long spuId, Boolean visible) { Map countMap = new HashMap<>(4); // 查询商品 id = spuId 的所有评论数量 - countMap.put(ProductCommentDO.ALL_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.ALL)); + countMap.put(AppCommentPageReqVO.ALL_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL)); // 查询商品 id = spuId 的所有好评数量 - countMap.put(ProductCommentDO.FAVOURABLE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.FAVOURABLE_COMMENT)); + countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT)); // 查询商品 id = spuId 的所有中评数量 - countMap.put(ProductCommentDO.MEDIOCRE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.MEDIOCRE_COMMENT)); + countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT)); // 查询商品 id = spuId 的所有差评数量 - countMap.put(ProductCommentDO.NEGATIVE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, ProductCommentDO.NEGATIVE_COMMENT)); + countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)); return countMap; } @@ -89,7 +89,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { result.getList().forEach(item -> { // 判断用户是否选择匿名 if (ObjectUtil.equal(item.getAnonymous(), true)) { - item.setUserNickname(ProductCommentDO.ANONYMOUS_NICKNAME); + item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME); } // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores()); diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 2b51f81d3..24d912025 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -142,19 +142,19 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals(7, result1.getTotal()); // 测试获取所有商品分页中评数据 - PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(ProductCommentDO.MEDIOCRE_COMMENT), Boolean.TRUE); + PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); assertEquals(2, result2.getTotal()); // 测试获取指定 spuId 商品分页中评数据 - PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(ProductCommentDO.MEDIOCRE_COMMENT), Boolean.TRUE); + PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); assertEquals(2, result3.getTotal()); // 测试分页 tab count Map tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE); - assertEquals(6, tabsCount.get(ProductCommentDO.ALL_COUNT)); - assertEquals(4, tabsCount.get(ProductCommentDO.FAVOURABLE_COMMENT_COUNT)); - assertEquals(2, tabsCount.get(ProductCommentDO.MEDIOCRE_COMMENT_COUNT)); - assertEquals(0, tabsCount.get(ProductCommentDO.NEGATIVE_COMMENT_COUNT)); + assertEquals(6, tabsCount.get(AppCommentPageReqVO.ALL_COUNT)); + assertEquals(4, tabsCount.get(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT)); + assertEquals(2, tabsCount.get(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT)); + assertEquals(0, tabsCount.get(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT)); } From f75f4e8846ff372bfa5c20048291f7b776572d97 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Jun 2023 08:54:33 +0800 Subject: [PATCH 088/232] =?UTF-8?q?mall=20+=20product=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=95=86=E5=93=81=E8=AF=A6=E6=83=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dict/core/util/DictFrameworkUtils.java | 5 +++ .../yudao-module-product-biz/pom.xml | 3 +- .../app/spu/AppProductSpuController.java | 7 +--- .../app/spu/vo/AppProductSpuDetailRespVO.java | 10 +++++ .../convert/sku/ProductSkuConvert.java | 10 ----- .../convert/spu/ProductSpuConvert.java | 37 ++++++------------- .../property/ProductPropertyDO.java | 1 - .../property/ProductPropertyValueDO.java | 1 - .../service/spu/ProductSpuServiceImpl.java | 18 ++++++--- 9 files changed, 40 insertions(+), 52 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtils.java index 58e1258b0..d0a765b92 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-dict/src/main/java/cn/iocoder/yudao/framework/dict/core/util/DictFrameworkUtils.java @@ -57,6 +57,11 @@ public class DictFrameworkUtils { log.info("[init][初始化 DictFrameworkUtils 成功]"); } + @SneakyThrows + public static String getDictDataLabel(String dictType, Integer value) { + return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, String.valueOf(value))).getLabel(); + } + @SneakyThrows public static String getDictDataLabel(String dictType, String value) { return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel(); diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index b04e03208..08b3c7533 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -35,10 +35,9 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant + yudao-spring-boot-starter-biz-dict diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 0e173f902..693e8e911 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -5,13 +5,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; @@ -67,11 +65,8 @@ public class AppProductSpuController { // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); - // 查询商品属性 - List propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); // 拼接 - return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues)); + return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index 41e36fb98..a543f0af2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -36,6 +36,9 @@ public class AppProductSpuDetailRespVO { @Schema(description = "商品视频", required = true) private String videoUrl; + @Schema(description = "单位名", required = true, example = "个") + private String unitName; + // ========== SKU 相关字段 ========= @Schema(description = "规格类型", required = true, example = "true") @@ -47,6 +50,9 @@ public class AppProductSpuDetailRespVO { @Schema(description = "市场价,单位使用:分", required = true, example = "1024") private Integer marketPrice; + @Schema(description = "VIP 价格,单位使用:分", required = true, example = "968") // 通过会员等级,计算出折扣后价格 + private Integer vipPrice; + @Schema(description = "库存", required = true, example = "666") private Integer stock; @@ -78,6 +84,9 @@ public class AppProductSpuDetailRespVO { @Schema(description = "市场价,单位使用:分", required = true, example = "1024") private Integer marketPrice; + @Schema(description = "VIP 价格,单位使用:分", required = true, example = "968") // 通过会员等级,计算出折扣后价格 + private Integer vipPrice; + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") private String picUrl; @@ -89,6 +98,7 @@ public class AppProductSpuDetailRespVO { @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 private Double volume; + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index abb93c911..2b78a00ef 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -68,16 +68,6 @@ public interface ProductSkuConvert { return spuIdAndStockMap; } - default Collection convertPropertyValueIds(List list) { - if (CollUtil.isEmpty(list)) { - return new HashSet<>(); - } - return list.stream().filter(item -> item.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - } - default String buildPropertyKey(ProductSkuDO bean) { if (CollUtil.isEmpty(bean.getProperties())) { return StrUtil.EMPTY; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 58d69d077..80902660c 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.convert.spu; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import cn.iocoder.yudao.module.product.enums.DictTypeConstants; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; @@ -21,10 +21,8 @@ import org.mapstruct.factory.Mappers; import java.util.ArrayList; import java.util.List; -import java.util.Map; import static cn.hutool.core.util.ObjectUtil.defaultIfNull; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * 商品 SPU Convert @@ -91,28 +89,17 @@ public interface ProductSpuConvert { PageResult convertPageForGetSpuPage0(PageResult page); - default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus, - List propertyValues) { + default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus) { + // 处理 SPU AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu) - .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); + .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)) + .setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); + // 处理 SKU spuVO.setSkus(convertListForGetSpuDetail(skus)); - // 处理商品属性 - Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); - for (int i = 0; i < skus.size(); i++) { - List properties = skus.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); - sku.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); - if (propertyValue == null) { - return; - } - sku.getProperties().add(convertForGetSpuDetail(propertyValue)); - }); + // 计算 vip 价格 TODO 芋艿:临时的逻辑,等 vip 支持后 + if (true) { + spuVO.setVipPrice((int) (spuVO.getPrice() * 0.9)); + spuVO.getSkus().forEach(sku -> sku.setVipPrice((int) (sku.getPrice() * 0.9))); } return spuVO; } @@ -121,8 +108,6 @@ public interface ProductSpuConvert { List convertListForGetSpuDetail(List skus); - AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); - default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus) { ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu); // skus 为空直接返回 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index dfe666e1f..34b6f6604 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index 80756bc5a..d73fe06b2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.property; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 78e9ba62c..9aecfb52e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import com.google.common.collect.Maps; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -238,17 +239,22 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Override public Map getTabsCount() { - Map counts = new HashMap<>(5); + Map counts = Maps.newLinkedHashMapWithExpectedSize(5); // 查询销售中的商品数量 - counts.put(ProductSpuPageReqVO.FOR_SALE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); + counts.put(ProductSpuPageReqVO.FOR_SALE, + productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus())); // 查询仓库中的商品数量 - counts.put(ProductSpuPageReqVO.IN_WAREHOUSE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); + counts.put(ProductSpuPageReqVO.IN_WAREHOUSE, + productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus())); // 查询售空的商品数量 - counts.put(ProductSpuPageReqVO.SOLD_OUT, productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); + counts.put(ProductSpuPageReqVO.SOLD_OUT, + productSpuMapper.selectCount(ProductSpuDO::getStock, 0)); // 查询触发警戒库存的商品数量 - counts.put(ProductSpuPageReqVO.ALERT_STOCK, productSpuMapper.selectCount()); + counts.put(ProductSpuPageReqVO.ALERT_STOCK, + productSpuMapper.selectCount()); // 查询回收站中的商品数量 - counts.put(ProductSpuPageReqVO.RECYCLE_BIN, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); + counts.put(ProductSpuPageReqVO.RECYCLE_BIN, + productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())); return counts; } From f2d803c111341d9ee2d82ddbb40b3e447d5cd0fd Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Jun 2023 13:59:04 +0800 Subject: [PATCH 089/232] =?UTF-8?q?mall=20+=20product=EF=BC=9Areview=20?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/spu/ProductSpuController.java | 17 +++++- .../app/spu/AppProductSpuController.java | 27 ++++++++- .../property/ProductPropertyDO.java | 8 +-- .../property/ProductPropertyValueDO.java | 8 +-- .../mysql/comment/ProductCommentMapper.java | 1 + .../category/ProductCategoryServiceImpl.java | 4 +- .../comment/ProductCommentServiceImpl.java | 19 +++--- .../service/sku/ProductSkuServiceImpl.java | 15 +++-- .../service/spu/ProductSpuService.java | 34 +++-------- .../service/spu/ProductSpuServiceImpl.java | 59 ++----------------- .../ProductCommentServiceImplTest.java | 1 + .../api/order/dto/TradeOrderRespDTO.java | 15 ++--- .../DeliveryExpressTemplateController.java | 1 - .../service/order/TradeOrderServiceImpl.java | 2 + 14 files changed, 92 insertions(+), 119 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 184a44f7e..0df57ca4f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -22,8 +24,10 @@ import java.io.IOException; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; /** * 商品 SPU 相关接口 @@ -38,6 +42,8 @@ public class ProductSpuController { @Resource private ProductSpuService productSpuService; + @Resource + private ProductSkuService productSkuService; @PostMapping("/create") @Operation(summary = "创建商品 SPU") @@ -58,7 +64,7 @@ public class ProductSpuController { @Operation(summary = "更新商品 SPU Status") @PreAuthorize("@ss.hasPermission('product:spu:update')") public CommonResult updateStatus(@Valid @RequestBody ProductSpuUpdateStatusReqVO updateReqVO) { - productSpuService.updateStatus(updateReqVO); + productSpuService.updateSpuStatus(updateReqVO); return success(true); } @@ -76,7 +82,14 @@ public class ProductSpuController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult getSpuDetail(@RequestParam("id") Long id) { - return success(productSpuService.getSpuDetail(id)); + // 获得商品 SPU + ProductSpuDO spu = productSpuService.getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuId(spu.getId()); + return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus)); } @GetMapping("/get-simple-list") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 49f9524f0..693e8e911 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -6,7 +6,11 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetail import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -19,8 +23,12 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; @Tag(name = "用户 APP - 商品 SPU") @RestController @@ -30,6 +38,10 @@ public class AppProductSpuController { @Resource private ProductSpuService productSpuService; + @Resource + private ProductSkuService productSkuService; + @Resource + private ProductPropertyValueService productPropertyValueService; @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") @@ -38,12 +50,23 @@ public class AppProductSpuController { return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult)); } - // TODO 芋艿:等会看看 @GetMapping("/get-detail") @Operation(summary = "获得商品 SPU 明细") @Parameter(name = "id", description = "编号", required = true) public CommonResult getSpuDetail(@RequestParam("id") Long id) { - return success(productSpuService.getAppProductSpuDetail(id)); + // 获得商品 SPU + ProductSpuDO spu = productSpuService.getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { + throw exception(SPU_NOT_ENABLE); + } + + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuId(spu.getId()); + // 拼接 + return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java index e7e3c8ba6..8cc646bd5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -22,13 +22,13 @@ import lombok.*; public class ProductPropertyDO extends BaseDO { /** - * 默认属性id + * SPU 单规格时,默认属性 id */ - public static final Long PROPERTY_ID = 0L; + public static final Long ID_DEFAULT = 0L; /** - * 默认属性名字 + * SPU 单规格时,默认属性名字 */ - public static final String PROPERTY_NAME = "默认"; + public static final String NAME_DEFAULT = "默认"; /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java index a632c8f11..cefa2d958 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -23,13 +23,13 @@ import lombok.*; public class ProductPropertyValueDO extends BaseDO { /** - * 默认属性值id + * SPU 单规格时,默认属性值 id */ - public static final Long VALUE_ID = 0L; + public static final Long ID_DEFAULT = 0L; /** - * 默认属性值名字 + * SPU 单规格时,默认属性值名字 */ - public static final String VALUE_NAME = "默认"; + public static final String NAME_DEFAULT = "默认"; /** * 主键 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index b010167cc..f25decbf8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -35,6 +35,7 @@ public interface ProductCommentMapper extends BaseMapperX { .orderByDesc(ProductCommentDO::getId)); } + // TODO 芋艿:在看看这块 static void appendTabQuery(LambdaQueryWrapperX queryWrapper, Integer type) { // 构建好评查询语句 if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 7e64c802d..7709f21a1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -68,8 +68,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { throw exception(CATEGORY_EXISTS_CHILDREN); } // 校验分类是否绑定了 SPU - Long count = productSpuService.getSpuCountByCategoryId(id); - if (0 != count) { + Long spuCount = productSpuService.getSpuCountByCategoryId(id); + if (spuCount > 0) { throw exception(CATEGORY_HAVE_BIND_SPU); } // 删除 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index edec1c651..a54afe2b3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -31,6 +31,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; +// TODO @芋艿:详细 review 下 /** * 商品评论 Service 实现类 * @@ -73,13 +74,17 @@ public class ProductCommentServiceImpl implements ProductCommentService { public Map getCommentPageTabsCount(Long spuId, Boolean visible) { Map countMap = new HashMap<>(4); // 查询商品 id = spuId 的所有评论数量 - countMap.put(AppCommentPageReqVO.ALL_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL)); + countMap.put(AppCommentPageReqVO.ALL_COUNT, + productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL)); // 查询商品 id = spuId 的所有好评数量 - countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT)); + countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT, + productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT)); // 查询商品 id = spuId 的所有中评数量 - countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT)); + countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT, + productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT)); // 查询商品 id = spuId 的所有差评数量 - countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)); + countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT, + productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)); return countMap; } @@ -101,13 +106,14 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override public void createComment(ProductCommentDO productComment, Boolean system) { + // TODO @puhui999:这里不区分是否为 system;直接都校验 if (!system) { - // TODO 判断订单是否存在 fix + // TODO 判断订单是否存在 fix; + // TODO @puhui999:改成 order 那有个 comment 接口,哪里校验下;商品评论这里不校验订单是否存在哈 TradeOrderRespDTO order = tradeOrderApi.getOrder(productComment.getOrderId()); if (null == order) { throw exception(ORDER_NOT_FOUND); } - // TODO 判断 SPU 是否存在 fix ProductSpuDO spu = productSpuService.getSpu(productComment.getSpuId()); if (null == spu) { throw exception(SPU_NOT_EXISTS); @@ -147,5 +153,4 @@ public class ProductCommentServiceImpl implements ProductCommentService { return productComment; } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 6b317bf22..3f77fbe8d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -83,21 +83,20 @@ public class ProductSkuServiceImpl implements ProductSkuService { if (CollUtil.isEmpty(skus)) { throw exception(SKU_NOT_EXISTS); } - // 单规格处理 + // 单规格,赋予单规格默认属性 if (ObjectUtil.equal(specType, false)) { ProductSkuCreateOrUpdateReqVO skuVO = skus.get(0); - // 赋予单规格默认属性 List properties = new ArrayList<>(); ProductSkuBaseVO.Property property = new ProductSkuBaseVO.Property(); - property.setPropertyId(ProductPropertyDO.PROPERTY_ID); - property.setPropertyName(ProductPropertyDO.PROPERTY_NAME); - property.setValueId(ProductPropertyValueDO.VALUE_ID); - property.setValueName(ProductPropertyValueDO.VALUE_NAME); + property.setPropertyId(ProductPropertyDO.ID_DEFAULT); + property.setPropertyName(ProductPropertyDO.NAME_DEFAULT); + property.setValueId(ProductPropertyValueDO.ID_DEFAULT); + property.setValueName(ProductPropertyValueDO.NAME_DEFAULT); properties.add(property); skuVO.setProperties(properties); - // 单规格不需要后续的校验 - return; + return; // 单规格不需要后续的校验 } + // 1、校验属性项存在 Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) // 遍历多个 Property 属性 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index be6851191..102b5e1fa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.service.spu; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -107,40 +106,25 @@ public interface ProductSpuService { void updateSpuStock(Map stockIncrCounts); /** - * 得到spu详细 + * 更新 SPU 状态 * - * @param id id - * @return {@link ProductSpuDetailRespVO} + * @param updateReqVO 更新请求 */ - ProductSpuDetailRespVO getSpuDetail(Long id); + void updateSpuStatus(ProductSpuUpdateStatusReqVO updateReqVO); /** - * 更新状态 + * 获取 SPU 列表标签对应的 Count 数量 * - * @param updateReqVO 更新请求签证官 - */ - void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO); - - /** - * 获取spu列表标签对应的Count数量 - * - * @return {@link Map}<{@link Integer}, {@link Integer}> + * @return Count 数量 */ Map getTabsCount(); /** - * 通过分类 id 查询 spu 个数 + * 通过分类 categoryId 查询 SPU 个数 * - * @param id 分类 id - * @return spu + * @param categoryId 分类 categoryId + * @return SPU 数量 */ - Long getSpuCountByCategoryId(Long id); + Long getSpuCountByCategoryId(Long categoryId); - /** - * 通过 spu id 获取商品 SPU 明细 - * - * @param id id - * @return 用户 App - 商品 SPU 明细 - */ - AppProductSpuDetailRespVO getAppProductSpuDetail(Long id); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 45097c3a6..297259509 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -7,21 +7,15 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import com.google.common.collect.Maps; import org.springframework.context.annotation.Lazy; @@ -114,9 +108,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { spu.setPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); // sku 单价最低的商品的市场价格 spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - // sku单价最低的商品的成本价格 + // sku 单价最低的商品的成本价格 spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice)); - // sku单价最低的商品的条形码 + // sku 单价最低的商品的条形码 spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); // skus 库存总数 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); @@ -213,21 +207,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); } - @Override - public ProductSpuDetailRespVO getSpuDetail(Long id) { - // 获得商品 SPU - ProductSpuDO spu = getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuId(spu.getId()); - return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus); - } - @Override @Transactional(rollbackFor = Exception.class) - public void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO) { + public void updateSpuStatus(ProductSpuUpdateStatusReqVO updateReqVO) { // 校验存在 validateSpuExists(updateReqVO.getId()); @@ -258,39 +240,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { } @Override - public Long getSpuCountByCategoryId(Long id) { - return productSpuMapper.selectCount(ProductSpuDO::getCategoryId, id); - } - - @Override - public AppProductSpuDetailRespVO getAppProductSpuDetail(Long id) { - // 获得商品 SPU - ProductSpuDO spu = getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { - throw exception(SPU_NOT_ENABLE); - } - - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuId(spu.getId()); - List propertyValues = new ArrayList<>(); - // 单规格商品 赋予默认属性值 - if (ObjectUtil.equal(spu.getSpecType(), false)) { - ProductPropertyValueDetailRespBO respBO = new ProductPropertyValueDetailRespBO(); - respBO.setPropertyId(ProductPropertyDO.PROPERTY_ID); - respBO.setPropertyName(ProductPropertyDO.PROPERTY_NAME); - respBO.setValueId(ProductPropertyValueDO.VALUE_ID); - respBO.setValueName(ProductPropertyValueDO.VALUE_NAME); - propertyValues.add(respBO); - } else { - // 多规格商品则查询商品属性 - propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); - } - // 拼接 - return ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues); + public Long getSpuCountByCategoryId(Long categoryId) { + return productSpuMapper.selectCount(ProductSpuDO::getCategoryId, categoryId); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 24d912025..15ee74cfd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -34,6 +34,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +// TODO 芋艿:单测详细 review 下 /** * {@link ProductCommentServiceImpl} 的单元测试类 * diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java index b9d362407..27b0a8af1 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/dto/TradeOrderRespDTO.java @@ -23,26 +23,24 @@ public class TradeOrderRespDTO { private Long id; /** * 订单流水号 - *

+ * * 例如说,1146347329394184195 */ private String no; /** * 订单类型 - *

+ * * 枚举 {@link TradeOrderTypeEnum} */ private Integer type; /** * 订单来源 - *

+ * * 枚举 {@link TerminalEnum} */ private Integer terminal; /** * 用户编号 - *

- * 关联 MemberUserDO 的 id 编号 */ private Long userId; /** @@ -55,7 +53,7 @@ public class TradeOrderRespDTO { private String userRemark; /** * 订单状态 - *

+ * * 枚举 {@link TradeOrderStatusEnum} */ private Integer status; @@ -73,7 +71,7 @@ public class TradeOrderRespDTO { private LocalDateTime cancelTime; /** * 取消类型 - *

+ * * 枚举 {@link TradeOrderCancelTypeEnum} */ private Integer cancelType; @@ -83,9 +81,6 @@ public class TradeOrderRespDTO { private String remark; /** * 是否评价 - *

- * true - 已评价 - * false - 未评价 */ private Boolean commentStatus; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java index 8f87e358e..5dc83682a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java @@ -70,7 +70,6 @@ public class DeliveryExpressTemplateController { return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list)); } - // TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈 fix @GetMapping("/list-all-simple") @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项") public CommonResult> getSimpleTemplateList() { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 666841eee..7cd6fe87b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -100,6 +100,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { private AdminUserApi adminUserApi; @Resource private NotifyMessageSendApi notifyMessageSendApi; + @Resource private TradeOrderProperties tradeOrderProperties; @@ -356,6 +357,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { // TODO 芋艿:发送订单变化的消息 // TODO 芋艿:发送站内信 fix + // TODO @puhui999:使用 sendSingleMessageToMember 呀;走模版;不用判断模版是否存在哈 // 1、获取模版编码为 order_delivery 的模版,判断是否存在 存在放回 true if (!notifyMessageSendApi.validateNotifyTemplate("order_delivery")) { // 1、1 站内信模版不存在则创建模版 From 25bea4920c05daa4b9004475aee2c851630e263d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Jun 2023 19:17:25 +0800 Subject: [PATCH 090/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Areview=20?= =?UTF-8?q?=E7=89=A9=E6=B5=81=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DeliveryExpressTemplateService.java | 3 +- .../DeliveryExpressTemplateServiceImpl.java | 15 ++++++--- .../bo/SpuDeliveryExpressTemplateRespBO.java | 5 ++- .../TradeDeliveryPriceCalculator.java | 32 +++++++++++-------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 6ec95a27a..3480f4072 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -83,10 +83,11 @@ public interface DeliveryExpressTemplateService { */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); + // TODO @jason 方法名可以改成 getExpressTemplateMapBySpuIdsAndArea /** * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 * - * @param ids SPU 编号列表 + * @param ids SPU 编号列表 // TODO @jason:模版编号? * @param areaId 区域编号 * @return Map (spuId -> 运费模板设置) */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 87b2d4920..07e80b5f3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -5,7 +5,10 @@ import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; @@ -234,14 +237,16 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla List templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet()); Map result = new HashMap<>(templateList.size()); templateList.forEach(item -> { + // TODO @jason:if return ,更简洁哈; if (spuMap.containsKey(item.getId())) { - ProductSpuRespDTO spuDTO = spuMap.get(item.getId()); + ProductSpuRespDTO spu = spuMap.get(item.getId()); SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() - .setSpuId(spuDTO.getId()).setAreaId(areaId) + .setSpuId(spu.getId()).setAreaId(areaId) .setChargeMode(item.getChargeMode()) + // TODO @jason:是不是只要查询到一个,就不用查询下一个了;TemplateCharge 和 TemplateFree .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); - result.put(spuDTO.getId(), bo); + result.put(spu.getId(), bo); } }); return result; @@ -249,6 +254,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeDO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { List list = expressTemplateChargeMapper.selectListByTemplateId(templateId); + // TODO @jason:可以使用 CollectionUtils.findFirst() for (DeliveryExpressTemplateChargeDO item : list) { // 第一个匹配的返回。 areaId 不能重复 if (item.getAreaIds().contains(areaId)) { @@ -260,6 +266,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateFreeDO findMatchExpressTemplateFree(Long templateId, Integer areaId) { List list = expressTemplateFreeMapper.selectListByTemplateId(templateId); + // TODO @jason:可以使用 CollectionUtils.findFirst() for (DeliveryExpressTemplateFreeDO item : list) { // 第一个匹配的返回。 areaId 不能重复 if (item.getAreaIds().contains(areaId)) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java index 87d04001b..2d5568915 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java @@ -13,9 +13,11 @@ import lombok.Data; @Data public class SpuDeliveryExpressTemplateRespBO { + // TODO @jason:是不是可以简单一点;是否包邮;然后直接把 templateCharge、templateFree 需要的字段平铺开 + /** * 配送计费方式 - *

+ * * 枚举 {@link DeliveryExpressChargeModeEnum} */ private Integer chargeMode; @@ -30,6 +32,7 @@ public class SpuDeliveryExpressTemplateRespBO { */ private DeliveryExpressTemplateFreeDO templateFree; + // TODO @jason:下面两个字段不用返回也可以呀 /** * SPU 编号 *

diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 46399b203..95e45182d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -54,33 +54,34 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); - //1.3 过滤出已选中的商品SKU + // 2. 过滤出已选中的商品SKU List selectedItem = filterList(result.getItems(), OrderItem::getSelected); - + Set spuIds = convertSet(selectedItem, OrderItem::getSpuId); Map spuExpressTemplateMap = - deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea( - convertSet(selectedItem, OrderItem::getSpuId), address.getAreaId()); + deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea(spuIds, address.getAreaId()); - // 1.4 计算配送费用 + // 3. 计算配送费用 + // TODO @jason:这里应该不能判断空;如果找不到模版,就要报错;不然配送费就亏了 if (CollUtil.isNotEmpty(spuExpressTemplateMap)) { calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); } - } private void calculateDeliveryPrice(List selectedSkus, Map spuExpressTemplateMap, TradePriceCalculateRespBO result) { + // 得到 SKU 详情 + // TODO @jason:可以去掉这里的读取;在 TradePriceCalculateRespBO 初始化的时候,把 weight、volume 拿到 Set skuIds = convertSet(selectedSkus, OrderItem::getSkuId); - // 得到SKU 详情。得到 重量体积 Map skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId); - // 按spu 来计算商品的运费 一个 spuId 可能对应多条订单商品 SKU, + // 按 SPU 来计算商品的运费:一个 spuId 可能对应多条订单商品 SKU Map> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId); // 依次计算每个 SPU 的快递运费 for (Map.Entry> entry : spuIdItemMap.entrySet()) { Long spuId = entry.getKey(); List orderItems = entry.getValue(); + // TODO @jason:如果找不到,则打印 error log SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId); if (templateBO == null) { // 记录错误日志 @@ -93,18 +94,18 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { double totalVolume = 0; for (OrderItem orderItem : orderItems) { totalCount += orderItem.getCount(); - totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下 + totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下 TODO @jason:是的哈 ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId()); - if (skuResp != null) { - totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount(); - totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount(); - } + // TODO @jason:是不是要保持风格统一,都用 += + totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount(); + totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount(); } // 优先判断是否包邮. 如果包邮不计算快递运费 if (checkExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, totalVolume, totalPrice, templateBO.getTemplateFree())) { continue; } + // TODO @jason:这块判断,可以收到 calculateExpressFeeByChargeMode 里;另外找不到,要打 error log if (templateBO.getTemplateCharge() == null) { continue; } @@ -175,6 +176,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品 */ private void divideDeliveryPrice(int deliveryPrice, List orderItems) { + // TODO @jason:分摊的话,是不是要按照比例呀?重量、价格、数量等等 int dividePrice = deliveryPrice / orderItems.size(); for (OrderItem item : orderItems) { // 更新快递运费 @@ -192,6 +194,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param totalPrice 总金额 * @param templateFree 包邮配置 */ + // TODO @jason:isExpressFree 更合适;因为 check 是一种校验,往往抛出异常; private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight, double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) { if (templateFree == null) { @@ -206,7 +209,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { } break; case WEIGHT: - // freeCount 是不是应该是 double ?? + // freeCount 是不是应该是 double ?? + // TODO @jason:要不配置的时候,把它的单位和商品对齐?到底是 kg、还是斤 if (totalWeight >= templateFree.getFreeCount() && totalPrice >= templateFree.getFreePrice()) { return true; From 84b365a70718f42f36fb405233fe8a8f3fbe4082 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Jun 2023 20:44:00 +0800 Subject: [PATCH 091/232] =?UTF-8?q?mall=20+=20product=EF=BC=9A=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E6=94=B6=E8=97=8F=E9=80=BB=E8=BE=91=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=20type=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../favorite/ProductFavoriteTypeEnum.java | 36 ------------------- .../app/favorite/AppFavoriteController.java | 15 ++++---- .../app/favorite/vo/AppFavoritePageReqVO.java | 12 ------- .../app/favorite/vo/AppFavoriteReqVO.java | 7 ---- .../app/favorite/vo/AppFavoriteRespVO.java | 3 -- .../favorite/ProductFavoriteConvert.java | 3 +- .../favorite/ProductFavoriteDO.java | 7 ---- .../mysql/favorite/ProductFavoriteMapper.java | 16 ++++----- .../favorite/ProductFavoriteService.java | 14 ++++---- .../favorite/ProductFavoriteServiceImpl.java | 19 +++++----- 10 files changed, 30 insertions(+), 102 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java deleted file mode 100644 index 4d28ae8ae..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/favorite/ProductFavoriteTypeEnum.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.favorite; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品收藏的类型枚举 - * - * @author jason - */ -@Getter -@AllArgsConstructor -public enum ProductFavoriteTypeEnum implements IntArrayValuable { - - COLLECT(1,"收藏"), - THUMBS_UP(2, "点赞"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductFavoriteTypeEnum::getType).toArray(); - - /** - * 类型 - */ - private final Integer type; - /** - * 描述 - */ - private final String desc; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index f2a41ac5a..68f6e8010 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.controller.app.favorite; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; @@ -35,21 +36,23 @@ public class AppFavoriteController { private ProductSpuService productSpuService; @PostMapping(value = "/create") - @Operation(summary = "商品收藏") - //@PreAuthenticated TODO 暂时注释 + @Operation(summary = "添加商品收藏") + @PreAuthenticated public CommonResult createFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { - return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO)); + return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO.getSpuId())); } @DeleteMapping(value = "/delete") @Operation(summary = "取消商品收藏") + @PreAuthenticated public CommonResult deleteFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) { - productFavoriteService.deleteFavorite(getLoginUserId(), reqVO); + productFavoriteService.deleteFavorite(getLoginUserId(), reqVO.getSpuId()); return success(Boolean.TRUE); } @GetMapping(value = "/page") @Operation(summary = "分页获取商品收藏列表") + @PreAuthenticated public CommonResult> getFavoritePage(AppFavoritePageReqVO reqVO) { PageResult favoritePage = productFavoriteService.getFavoritePage(getLoginUserId(), reqVO); if (CollUtil.isEmpty(favoritePage.getList())) { @@ -67,11 +70,11 @@ public class AppFavoriteController { return success(pageResult); } - @GetMapping(value = "/exits") @Operation(summary = "检查是否收藏过商品") + @PreAuthenticated public CommonResult isFavoriteExists(AppFavoriteReqVO reqVO) { - ProductFavoriteDO favoriteDO = productFavoriteService.getFavorite(getLoginUserId(), reqVO); + ProductFavoriteDO favoriteDO = productFavoriteService.getFavorite(getLoginUserId(), reqVO.getSpuId()); return success(Objects.nonNull(favoriteDO)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java index 3ca8b6da6..cdf8257c3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoritePageReqVO.java @@ -1,22 +1,10 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotNull; - -import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; - @Schema(description = "用户APP - 商品收藏分页查询 Request VO") @Data public class AppFavoritePageReqVO extends PageParam { - - @Schema(description = "类型", requiredMode = REQUIRED, example = "1") - @NotNull(message = "类型不能为空") - @InEnum(ProductFavoriteTypeEnum.class) - private Integer type; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index 63da3340b..639de011e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -17,9 +15,4 @@ public class AppFavoriteReqVO { @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; - @Schema(description = "类型", requiredMode = REQUIRED, example = "1") - @NotNull(message = "类型不能为空") - @InEnum(ProductFavoriteTypeEnum.class) - private Integer type; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java index a0f81a909..399e1fb0a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -14,9 +14,6 @@ public class AppFavoriteRespVO { @Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502") private Long spuId; - @Schema(description = "类型", requiredMode = REQUIRED, example = "1") - private Integer type; - // ========== 商品相关字段 ========== @Schema(description = "商品 SPU 名称", example = "赵六") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index d19f67c49..b15afacb2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.convert.favorite; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -19,7 +18,7 @@ public interface ProductFavoriteConvert { ProductFavoriteConvert INSTANCE = Mappers.getMapper(ProductFavoriteConvert.class); - ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO); + ProductFavoriteDO convert(Long userId, Long spuId); @Mapping(target = "id", source = "favorite.id") @Mapping(target = "spuName", source = "spu.name") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java index d99ae0fe6..6e00eaa6c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.favorite; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -40,11 +39,5 @@ public class ProductFavoriteDO extends BaseDO { * 关联 {@link ProductSpuDO#getId()} */ private Long spuId; - /** - * 类型 - * - * 枚举 {@link ProductFavoriteTypeEnum} - */ - private Integer type; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index 0246e0fee..68f7db319 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.dal.mysql.favorite; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -11,17 +10,14 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface ProductFavoriteMapper extends BaseMapperX { - default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) { - return selectOne(new LambdaQueryWrapperX() - .eq(ProductFavoriteDO::getUserId, userId) - .eq(ProductFavoriteDO::getSpuId, spuId) - .eq(ProductFavoriteDO::getType, type)); + default ProductFavoriteDO selectByUserIdAndSpuId(Long userId, Long spuId) { + return selectOne(ProductFavoriteDO::getUserId, userId, + ProductFavoriteDO::getSpuId, spuId); } - default PageResult selectPageByUserAndType(Long userId, Integer type, PageParam pageParam) { - return selectPage(pageParam, new LambdaQueryWrapper() + default PageResult selectPageByUserAndType(Long userId, AppFavoritePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapper() .eq(ProductFavoriteDO::getUserId, userId) - .eq(ProductFavoriteDO::getType, type) .orderByDesc(ProductFavoriteDO::getId)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index 2c6076969..7ea7489a4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.product.service.favorite; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import javax.validation.Valid; @@ -19,17 +17,17 @@ public interface ProductFavoriteService { * 创建商品收藏 * * @param userId 用户 id - * @param reqVO 请求 vo + * @param spuId SPU 编号 */ - Long createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + Long createFavorite(Long userId, Long spuId); /** * 取消商品收藏 * * @param userId 用户 id - * @param reqVO 请求 vo + * @param spuId SPU 编号 */ - void deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + void deleteFavorite(Long userId, Long spuId); /** * 分页查询用户收藏列表 @@ -43,8 +41,8 @@ public interface ProductFavoriteService { * 获取收藏过商品 * * @param userId 用户id - * @param reqVO 请求 vo + * @param spuId SPU 编号 */ - ProductFavoriteDO getFavorite(Long userId, @Valid AppFavoriteReqVO reqVO); + ProductFavoriteDO getFavorite(Long userId, Long spuId); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index b1dd84fa5..775aa0e69 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.service.favorite; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper; @@ -30,22 +29,20 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { private ProductFavoriteMapper productFavoriteMapper; @Override - public Long createFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - ProductFavoriteDO favorite = productFavoriteMapper.selectByUserAndSpuAndType( - userId, reqVO.getSpuId(), reqVO.getType()); + public Long createFavorite(Long userId, Long spuId) { + ProductFavoriteDO favorite = productFavoriteMapper.selectByUserIdAndSpuId(userId, spuId); if (Objects.nonNull(favorite)) { throw exception(FAVORITE_EXISTS); } - ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO); + ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, spuId); productFavoriteMapper.insert(entity); return entity.getId(); } @Override - public void deleteFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - ProductFavoriteDO favorite = productFavoriteMapper.selectByUserAndSpuAndType( - userId, reqVO.getSpuId(), reqVO.getType()); + public void deleteFavorite(Long userId, Long spuId) { + ProductFavoriteDO favorite = productFavoriteMapper.selectByUserIdAndSpuId(userId, spuId); if (Objects.isNull(favorite)) { throw exception(FAVORITE_NOT_EXISTS); } @@ -55,12 +52,12 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { @Override public PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO) { - return productFavoriteMapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO); + return productFavoriteMapper.selectPageByUserAndType(userId, reqVO); } @Override - public ProductFavoriteDO getFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) { - return productFavoriteMapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType()); + public ProductFavoriteDO getFavorite(Long userId, Long spuId) { + return productFavoriteMapper.selectByUserIdAndSpuId(userId, spuId); } } From 1e1a22c256ea736ece7135a96b4430aaaab80464 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 Jun 2023 22:41:16 +0800 Subject: [PATCH 092/232] =?UTF-8?q?mall=20+=20product=EF=BC=9A=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E7=9A=84=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/ProductCommentController.java | 2 + .../comment/vo/ProductCommentBaseVO.java | 24 +++++---- .../comment/vo/ProductCommentReplyVO.java | 4 +- .../comment/vo/ProductCommentRespVO.java | 12 +---- .../vo/ProductCommentUpdateVisibleReqVO.java | 2 +- .../app/comment/AppCommentController.java | 15 ++---- .../comment/vo/AppCommentAdditionalReqVO.java | 28 ----------- .../app/comment/vo/AppCommentBaseVO.java | 5 +- .../app/comment/vo/AppCommentCreateReqVO.java | 5 +- .../app/comment/vo/AppCommentPageReqVO.java | 4 ++ .../app/comment/vo/AppCommentRespVO.java | 7 ++- .../comment/ProductCommentConvert.java | 4 +- .../dataobject/comment/ProductCommentDO.java | 49 +++++-------------- .../mysql/comment/ProductCommentMapper.java | 29 +++-------- .../comment/ProductCommentService.java | 18 ++----- .../comment/ProductCommentServiceImpl.java | 33 +++---------- .../ProductCommentServiceImplTest.java | 4 +- 17 files changed, 70 insertions(+), 175 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index 9a49cbba0..fb8f8fe34 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -35,6 +35,7 @@ public class ProductCommentController { return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); } + // TODO @puhui999:update-visible @PutMapping("/update/visible") @Operation(summary = "显示 / 隐藏评论") @PreAuthorize("@ss.hasPermission('product:comment:update')") @@ -55,6 +56,7 @@ public class ProductCommentController { @Operation(summary = "添加自评") @PreAuthorize("@ss.hasPermission('product:comment:update')") public CommonResult createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) { + // TODO @puhui999:不用 ProductCommentConvert.INSTANCE.convert(createReqVO) 哈;多写一个 create 方法即可; productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE); return success(true); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java index 19dae8777..775801bbc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java @@ -10,6 +10,8 @@ import java.util.List; @Data public class ProductCommentBaseVO { + // TODO @puhui999:把 example 补充下 + @Schema(description = "评价人名称", required = true, example = "张三") @NotNull(message = "评价人名称不能为空") private String userNickname; @@ -18,34 +20,30 @@ public class ProductCommentBaseVO { @NotNull(message = "评价人头像不能为空") private String userAvatar; - @Schema(description = "商品SPU编号", required = true, example = "29502") - @NotNull(message = "商品SPU编号不能为空") + @Schema(description = "商品 SPU 编号", required = true, example = "29502") + @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; - @Schema(description = "商品SPU名称", required = true, example = "赵六") - @NotNull(message = "商品SPU名称不能为空") + @Schema(description = "商品 SPU 名称", required = true, example = "赵六") + @NotNull(message = "商品 SPU 名称不能为空") private String spuName; - @Schema(description = "商品SKU编号", required = true, example = "3082") - @NotNull(message = "商品SKU编号不能为空") + @Schema(description = "商品 SKU 编号", required = true, example = "3082") + @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; @Schema(description = "评分星级 1-5分", required = true) - @NotNull(message = "评分星级 1-5分不能为空") + @NotNull(message = "评分星级不能为空") private Integer scores; @Schema(description = "描述星级 1-5分", required = true) - @NotNull(message = "描述星级 1-5分不能为空") + @NotNull(message = "描述星级不能为空") private Integer descriptionScores; @Schema(description = "服务星级 1-5分", required = true) - @NotNull(message = "服务星级 1-5分不能为空") + @NotNull(message = "服务星级分不能为空") private Integer benefitScores; - @Schema(description = "配送星级 1-5分", required = true) - @NotNull(message = "配送星级 1-5分不能为空") - private Integer deliveryScores; - @Schema(description = "评论内容", required = true) @NotNull(message = "评论内容不能为空") private String content; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java index 44101b602..a935108dc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java @@ -4,8 +4,10 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +// TODO @puhui999:ReqVO @Schema(description = "管理后台 - 商品评价可见修改 Request VO") @Data @ToString(callSuper = true) @@ -16,7 +18,7 @@ public class ProductCommentReplyVO { private Long id; @Schema(description = "商家回复内容", required = true, example = "谢谢亲") - @NotNull(message = "商家回复内容不能为空") + @NotEmpty(message = "商家回复内容不能为空") private String replyContent; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index 8568b4f8c..400630afd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -6,7 +6,6 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -import java.util.List; @Schema(description = "管理后台 - 商品评价 Response VO") @Data @@ -33,7 +32,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { private Boolean visible; @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) - private Boolean replied; + private Boolean replyStatus; @Schema(description = "回复管理员编号", example = "22212") private Long replyUserId; @@ -44,15 +43,6 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "商家回复时间") private LocalDateTime replyTime; - @Schema(description = "追加评价内容") - private String additionalContent; - - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") - private List additionalPicUrls; - - @Schema(description = "追加评价时间") - private LocalDateTime additionalTime; - @Schema(description = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java index a297d37e1..77c085995 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java @@ -15,7 +15,7 @@ public class ProductCommentUpdateVisibleReqVO { @NotNull(message = "评价编号不能为空") private Long id; - @Schema(description = "是否可见 true:显示 false:隐藏", required = true, example = "false") + @Schema(description = "是否可见", required = true, example = "false") @NotNull(message = "是否可见不能为空") private Boolean visible; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java index e1f1df3ea..7d05161e7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; @@ -22,6 +21,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +// TODO @puhui999:AppCommentController =》 AppProductCommentController @Tag(name = "用户 APP - 商品评价") @RestController @RequestMapping("/product/comment") @@ -40,8 +40,9 @@ public class AppCommentController { return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); } + // TODO @puhui999:方法名改成 getCommentStatistics?然后搞个对应的 vo?想了下,这样更优雅 @GetMapping("/get-count") - @Operation(summary = "获得商品评价分页 tab count") + @Operation(summary = "获得商品的评价统计") // TODO @puhui999:@RequestParam 哈,针对 spuId public CommonResult> getCommentPage(@Valid Long spuId) { return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); } @@ -50,18 +51,10 @@ public class AppCommentController { @Operation(summary = "创建商品评价") public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { // TODO: 2023/3/20 要不要判断订单、商品是否存在 + // TODO @ouhui999:这个接口,搞到交易那比较合适; MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); return success(true); } - @PostMapping(value = "/additional") - @Operation(summary = "追加评论") - public CommonResult additionalComment(@RequestBody AppCommentAdditionalReqVO createReqVO) { - // 查询会员 - MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); - productCommentService.additionalComment(user, createReqVO); - return success(true); - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java deleted file mode 100644 index b989a867d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.comment.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.List; - -@Schema(description = "用户APP - 商品追加评价创建 Request VO") -@Data -@ToString(callSuper = true) -public class AppCommentAdditionalReqVO { - - @Schema(description = "评论编号", required = true) - @NotNull(message = "评论编号不能为空") - private Long id; - - @Schema(description = "追加评价内容", required = true) - @NotNull(message = "追加评价内容不能为空") - private String additionalContent; - - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", required = true) - @Size(max = 9, message = "追评评价图片地址数组长度不能超过9张") - private List additionalPicUrls; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java index 59716b5a6..2cbefad01 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java @@ -7,6 +7,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.List; +// TODO @puhui999:把 Product 前缀给补下哈 @Data public class AppCommentBaseVO { @@ -34,10 +35,6 @@ public class AppCommentBaseVO { @NotNull(message = "服务星级 1-5分不能为空") private Integer benefitScores; - @Schema(description = "配送星级 1-5分", required = true) - @NotNull(message = "配送星级 1-5分不能为空") - private Integer deliveryScores; - @Schema(description = "评论内容", required = true) @NotNull(message = "评论内容不能为空") private String content; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java index 9bfdf52c0..6eb8e89e3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java @@ -7,16 +7,19 @@ import lombok.ToString; import javax.validation.constraints.NotNull; +// TODO @puhui999:不应该继承 AppCommentCreateReqVO @Schema(description = "用户APP - 商品评价创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppCommentCreateReqVO extends AppCommentBaseVO { - @Schema(description = "是否匿名 true:是 false:否", required = true, example = "true") + @Schema(description = "是否匿名", required = true, example = "true") @NotNull(message = "是否匿名不能为空") private Boolean anonymous; + // TODO @puhui999:不应该传递 orderId + @Schema(description = "交易订单编号", required = true, example = "12312") @NotNull(message = "交易订单编号不能为空") private Long orderId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index 8dbff09c3..d2bf4ef99 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -14,6 +14,7 @@ import javax.validation.constraints.NotNull; @ToString(callSuper = true) public class AppCommentPageReqVO extends PageParam { + // TODO @puhui999:不传递就是 all; /** * 所有 */ @@ -24,11 +25,13 @@ public class AppCommentPageReqVO extends PageParam { */ public static final String ALL_COUNT = "allCount"; + // TODO @puhui999:good 好评; /** * 好评 */ public static final Integer FAVOURABLE_COMMENT = 1; + // TODO @puhui999:medium 中评;然后 mediumCount 就好啦; /** * 好评数量 key */ @@ -54,6 +57,7 @@ public class AppCommentPageReqVO extends PageParam { */ public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; + // TODO @puhui999:这个挪到 DO 那没问题的哈;NICKNAME_ANONYMOUS /** * 默认匿名昵称 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java index cd532ed4c..77c419b96 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java @@ -14,7 +14,9 @@ import java.util.List; @ToString(callSuper = true) public class AppCommentRespVO extends AppCommentBaseVO { - @Schema(description = "评价人 用户编号", required = true, example = "15721") + // TODO puhui999:把 example 也补充下哈 + + @Schema(description = "评价人的用户编号", required = true, example = "15721") private Long userId; @Schema(description = "评价人名称", required = true, example = "张三") @@ -36,7 +38,7 @@ public class AppCommentRespVO extends AppCommentBaseVO { private Long orderItemId; @Schema(description = "商家是否回复", required = true) - private Boolean replied; + private Boolean replyStatus; @Schema(description = "回复管理员编号", example = "22212") private Long replyUserId; @@ -61,4 +63,5 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "最终评分", required = true) private Integer finalScore; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index a0f5b154d..77f208214 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -30,6 +30,7 @@ public interface ProductCommentConvert { PageResult convertPage02(PageResult pageResult); + // TODO @puhui999:用 mapstruct 的映射 default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) { ProductCommentDO productComment = new ProductCommentDO(); productComment.setUserId(user.getId()); @@ -44,12 +45,12 @@ public interface ProductCommentConvert { productComment.setScores(createReqVO.getScores()); productComment.setDescriptionScores(createReqVO.getDescriptionScores()); productComment.setBenefitScores(createReqVO.getBenefitScores()); - productComment.setDeliveryScores(createReqVO.getDeliveryScores()); productComment.setContent(createReqVO.getContent()); productComment.setPicUrls(createReqVO.getPicUrls()); return productComment; } + // TODO @puhui999:用 mapstruct 的映射 default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { ProductCommentDO productComment = new ProductCommentDO(); productComment.setUserId(0L); @@ -64,7 +65,6 @@ public interface ProductCommentConvert { productComment.setScores(createReq.getScores()); productComment.setDescriptionScores(createReq.getDescriptionScores()); productComment.setBenefitScores(createReq.getBenefitScores()); - productComment.setDeliveryScores(createReq.getDeliveryScores()); productComment.setContent(createReq.getContent()); productComment.setPicUrls(createReq.getPicUrls()); return productComment; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 6e0bd04fa..cf7b47051 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -36,20 +36,18 @@ public class ProductCommentDO extends BaseDO { /** * 评价人 用户编号 + * * 关联 MemberUserDO 的 id 编号 */ private Long userId; - /** * 评价人名称 */ private String userNickname; - /** * 评价人头像 */ private String userAvatar; - /** * 是否匿名 */ @@ -57,12 +55,13 @@ public class ProductCommentDO extends BaseDO { /** * 交易订单编号 + * * 关联 TradeOrderDO 的 id 编号 */ private Long orderId; - /** * 交易订单项编号 + * * 关联 TradeOrderItemDO 的 id 编号 */ private Long orderItemId; @@ -72,53 +71,46 @@ public class ProductCommentDO extends BaseDO { * 关联 {@link ProductSpuDO#getId()} */ private Long spuId; - /** * 商品 SPU 名称 */ private String spuName; - /** * 商品 SKU 编号 + * * 关联 {@link ProductSkuDO#getId()} */ private Long skuId; /** * 是否可见 - * true:显示 false:隐藏 + * + * true:显示 + * false:隐藏 */ private Boolean visible; - /** * 评分星级 + * * 1-5分 */ private Integer scores; - /** * 描述星级 + * * 1-5 星 */ private Integer descriptionScores; - /** * 服务星级 + * * 1-5 星 */ private Integer benefitScores; - - /** - * 配送星级 - * 1-5 星 - */ - private Integer deliveryScores; - /** * 评论内容 */ private String content; - /** * 评论图片地址数组 */ @@ -128,38 +120,19 @@ public class ProductCommentDO extends BaseDO { /** * 商家是否回复 */ - private Boolean replied; - + private Boolean replyStatus; /** * 回复管理员编号 * 关联 AdminUserDO 的 id 编号 */ private Long replyUserId; - /** * 商家回复内容 */ private String replyContent; - /** * 商家回复时间 */ private LocalDateTime replyTime; - /** - * 追加评价内容 - */ - private String additionalContent; - - /** - * 追评评价图片地址数组 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List additionalPicUrls; - - /** - * 追加评价时间 - */ - private LocalDateTime additionalTime; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index f25decbf8..796a790f4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -15,12 +14,6 @@ import org.apache.ibatis.annotations.Mapper; import java.time.LocalDateTime; - -/** - * 商品评论 Mapper - * - * @author wangzhs - */ @Mapper public interface ProductCommentMapper extends BaseMapperX { @@ -37,19 +30,16 @@ public interface ProductCommentMapper extends BaseMapperX { // TODO 芋艿:在看看这块 static void appendTabQuery(LambdaQueryWrapperX queryWrapper, Integer type) { - // 构建好评查询语句 + // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8 if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) { - // 好评计算 (商品评分星级+服务评分星级) >= 8 queryWrapper.apply("(scores + benefit_scores) >= 8"); } - // 构建中评查询语句 + // 构建中评查询语句:中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 if (ObjectUtil.equal(type, AppCommentPageReqVO.MEDIOCRE_COMMENT)) { - // 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8"); } - // 构建差评查询语句 + // 构建差评查询语句:差评计算 (商品评分星级+服务评分星级) <= 4 if (ObjectUtil.equal(type, AppCommentPageReqVO.NEGATIVE_COMMENT)) { - // 差评计算 (商品评分星级+服务评分星级) <= 4 queryWrapper.apply("(scores + benefit_scores) <= 4"); } } @@ -74,7 +64,7 @@ public interface ProductCommentMapper extends BaseMapperX { default void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .set(ProductCommentDO::getReplied, Boolean.TRUE) + .set(ProductCommentDO::getReplyStatus, Boolean.TRUE) .set(ProductCommentDO::getReplyTime, LocalDateTime.now()) .set(ProductCommentDO::getReplyUserId, loginUserId) .set(ProductCommentDO::getReplyContent, replyVO.getReplyContent()) @@ -82,6 +72,7 @@ public interface ProductCommentMapper extends BaseMapperX { update(null, lambdaUpdateWrapper); } + // TODO @puhui999:使用 select 替代 find default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { return selectOne(new LambdaQueryWrapperX() .eq(ProductCommentDO::getUserId, userId) @@ -89,15 +80,7 @@ public interface ProductCommentMapper extends BaseMapperX { .eq(ProductCommentDO::getSpuId, spuId)); } - default void additionalComment(AppCommentAdditionalReqVO createReqVO) { - LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .set(ProductCommentDO::getAdditionalTime, LocalDateTime.now()) - .set(ProductCommentDO::getAdditionalPicUrls, createReqVO.getAdditionalPicUrls(), "javaType=List,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler") - .set(ProductCommentDO::getAdditionalContent, createReqVO.getAdditionalContent()) - .eq(ProductCommentDO::getId, createReqVO.getId()); - update(null, lambdaUpdateWrapper); - } - + // TODO @puhui999:selectCountBySpuId 即可 default Long selectTabCount(Long spuId, Boolean visible, Integer type) { LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() .eqIfPresent(ProductCommentDO::getSpuId, spuId) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 0c315b94f..7bf9ccb36 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -1,11 +1,9 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; @@ -38,11 +36,12 @@ public interface ProductCommentService { */ void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO); + // TODO @puhui999:replyComment /** * 商家回复 * * @param replyVO 商家回复 - * @param loginUserId 管理后台商家登陆人ID + * @param loginUserId 管理后台商家登陆人 ID */ void commentReply(ProductCommentReplyVO replyVO, Long loginUserId); @@ -64,19 +63,12 @@ public interface ProductCommentService { void createComment(ProductCommentDO productComment, Boolean system); /** - * 追加商品评论 - * - * @param user 用户相关信息 - * @param createReqVO 创建实体 - */ - void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO); - - /** - * 评论页面标签数 + * 获得商品的评价统计 * * @param spuId spu id * @param visible 是否可见 - * @return 获得商品评价分页 tab count + * @return 评价统计 */ Map getCommentPageTabsCount(Long spuId, Boolean visible); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index a54afe2b3..1f1156e1c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; @@ -17,7 +15,6 @@ import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; @@ -25,13 +22,11 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; -// TODO @芋艿:详细 review 下 /** * 商品评论 Service 实现类 * @@ -43,6 +38,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Resource private ProductCommentMapper productCommentMapper; + @Resource private TradeOrderApi tradeOrderApi; @@ -59,6 +55,8 @@ public class ProductCommentServiceImpl implements ProductCommentService { // 校验评论是否存在 validateCommentExists(updateReqVO.getId()); + // 更新可见状态 + // TODO @puhui999:直接使用 update 操作 productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible()); } @@ -67,6 +65,8 @@ public class ProductCommentServiceImpl implements ProductCommentService { // 校验评论是否存在 validateCommentExists(replyVO.getId()); + // 回复评论 + // TODO @puhui999:直接使用 update 操作 productCommentMapper.commentReply(replyVO, loginUserId); } @@ -90,12 +90,14 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { + // TODO @puhui999:逻辑可以在 controller 做哈。让 service 简介一点;因为是 view 需要不展示昵称 PageResult result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); result.getList().forEach(item -> { // 判断用户是否选择匿名 if (ObjectUtil.equal(item.getAnonymous(), true)) { item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME); } + // TODO @puhui999:直接插入的时候,计算到 scores 字段里;这样就去掉 finalScore 字段哈 // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores()); BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN); @@ -127,30 +129,11 @@ public class ProductCommentServiceImpl implements ProductCommentService { productCommentMapper.insert(productComment); } - @Override - public void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO) { - // 校验评论是否存在 - ProductCommentDO productComment = validateCommentExists(createReqVO.getId()); - - // 判断是否是同一用户追加评论 - if (!Objects.equals(productComment.getUserId(), user.getId())) { - throw exception(COMMENT_ERROR_OPT); - } - - // 判断是否已经追加评论过了 - if (StringUtils.hasText(productComment.getAdditionalContent())) { - throw exception(COMMENT_ADDITIONAL_EXISTS); - } - - productCommentMapper.additionalComment(createReqVO); - } - - private ProductCommentDO validateCommentExists(Long id) { + private void validateCommentExists(Long id) { ProductCommentDO productComment = productCommentMapper.selectById(id); if (productComment == null) { throw exception(COMMENT_NOT_EXISTS); } - return productComment; } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 15ee74cfd..6754f3ba0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -82,7 +82,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setUserNickname("王二狗"); o.setSpuName("感冒药"); o.setScores(ProductCommentScoresEnum.FOUR.getScores()); - o.setReplied(Boolean.TRUE); + o.setReplyStatus(Boolean.TRUE); o.setVisible(Boolean.TRUE); o.setId(generateId()); o.setUserId(generateId()); @@ -118,7 +118,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { // 测试 scores 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); // 测试 replied 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE))); + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplyStatus(Boolean.FALSE))); // 测试 visible 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE))); From dde89d51d5598bd5e34c6ccb63877b0b627e63cf Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 10 Jun 2023 00:15:57 +0800 Subject: [PATCH 093/232] =?UTF-8?q?=E7=89=A9=E6=B5=81=E8=BF=90=E8=B4=B9?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=20review=20=E4=BF=AE=E6=94=B9=20+=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 6 +- .../DeliveryExpressTemplateConvert.java | 6 + .../DeliveryExpressTemplateService.java | 5 +- .../DeliveryExpressTemplateServiceImpl.java | 56 +++--- .../bo/DeliveryExpressTemplateChargeBO.java | 29 +++ .../bo/DeliveryExpressTemplateFreeBO.java | 26 +++ .../bo/SpuDeliveryExpressTemplateRespBO.java | 21 +-- .../price/bo/TradePriceCalculateRespBO.java | 9 + .../TradeDeliveryPriceCalculator.java | 70 ++++---- .../TradePriceCalculatorHelper.java | 3 +- .../TradeDeliveryPriceCalculatorTest.java | 168 ++++++++++++++++++ 11 files changed, 304 insertions(+), 95 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 37306465f..43a9d62e6 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -50,8 +50,10 @@ public interface ErrorCodeConstants { // TODO @jason:最好每个模块一段哈。express 一个;exmpresstemplate 一个;pickup 一个 ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); - ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003002, "已经存在该运费模板名"); - ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003003, "自提门店不存在"); + ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); + ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); + ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003006, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index aadaf42f3..6ac562658 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -47,6 +49,8 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo); + DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); + default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); } @@ -57,6 +61,8 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo); + DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); + List convertTemplateChargeList(List list); List convertTemplateFreeList(List list); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 3480f4072..e037dbc29 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -83,14 +83,13 @@ public interface DeliveryExpressTemplateService { */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); - // TODO @jason 方法名可以改成 getExpressTemplateMapBySpuIdsAndArea /** * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 * - * @param ids SPU 编号列表 // TODO @jason:模版编号? + * @param spuIds SPU 编号列表 * @param areaId 区域编号 * @return Map (spuId -> 运费模板设置) */ - Map getExpressTemplateBySpuIdsAndArea(Collection ids, Integer areaId); + Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 07e80b5f3..7aa591388 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -15,6 +15,8 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateMapper; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,8 +26,7 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressTemplateConvert.INSTANCE; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NAME_DUPLICATE; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_TEMPLATE_NOT_EXISTS; @@ -227,7 +228,7 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } @Override - public Map getExpressTemplateBySpuIdsAndArea(Collection spuIds, Integer areaId) { + public Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId) { Assert.notNull(areaId, "区域编号 {} 不能为空", areaId); List spuList = productSpuApi.getSpuList(spuIds); if (CollUtil.isEmpty(spuList)) { @@ -237,43 +238,32 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla List templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet()); Map result = new HashMap<>(templateList.size()); templateList.forEach(item -> { - // TODO @jason:if return ,更简洁哈; - if (spuMap.containsKey(item.getId())) { - ProductSpuRespDTO spu = spuMap.get(item.getId()); - SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() - .setSpuId(spu.getId()).setAreaId(areaId) - .setChargeMode(item.getChargeMode()) - // TODO @jason:是不是只要查询到一个,就不用查询下一个了;TemplateCharge 和 TemplateFree - .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) - .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); - result.put(spu.getId(), bo); + ProductSpuRespDTO spu = spuMap.get(item.getId()); + if (spu == null) { + return; } + SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() + .setChargeMode(item.getChargeMode()) + // TODO @jason:是不是只要查询到一个,就不用查询下一个了;TemplateCharge 和 TemplateFree + // @芋艿 包邮的优先级> 费用的优先级 所以两个都要查询 + .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) + .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); + result.put(spu.getId(), bo); }); return result; } - private DeliveryExpressTemplateChargeDO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { - List list = expressTemplateChargeMapper.selectListByTemplateId(templateId); - // TODO @jason:可以使用 CollectionUtils.findFirst() - for (DeliveryExpressTemplateChargeDO item : list) { - // 第一个匹配的返回。 areaId 不能重复 - if (item.getAreaIds().contains(areaId)) { - return item; - } - } - return null; + private DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { + return INSTANCE.convertTemplateCharge(findFirst( + expressTemplateChargeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) + ) + ); } - private DeliveryExpressTemplateFreeDO findMatchExpressTemplateFree(Long templateId, Integer areaId) { - List list = expressTemplateFreeMapper.selectListByTemplateId(templateId); - // TODO @jason:可以使用 CollectionUtils.findFirst() - for (DeliveryExpressTemplateFreeDO item : list) { - // 第一个匹配的返回。 areaId 不能重复 - if (item.getAreaIds().contains(areaId)) { - return item; - } - } - return null; + private DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree(Long templateId, Integer areaId) { + return INSTANCE.convertTemplateFree(findFirst( + expressTemplateFreeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) + )); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java new file mode 100644 index 000000000..9dd908c41 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.trade.service.delivery.bo; + +import lombok.Data; + +/** + * 快递运费模板费用配置 BO + * + * @author jason + */ +@Data +public class DeliveryExpressTemplateChargeBO { + + /** + * 首件数量(件数,重量,或体积) + */ + private Double startCount; + /** + * 起步价,单位:分 + */ + private Integer startPrice; + /** + * 续件数量(件, 重量,或体积) + */ + private Double extraCount; + /** + * 额外价,单位:分 + */ + private Integer extraPrice; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java new file mode 100644 index 000000000..6bccb038e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.trade.service.delivery.bo; + +import lombok.Data; + +/** + * 快递运费模板包邮配置 BO + * + * @author jason + */ +@Data +public class DeliveryExpressTemplateFreeBO { + + /** + * 包邮金额,单位:分 + * + * 订单总金额 > 包邮金额时,才免运费 + */ + private Integer freePrice; + + /** + * 包邮件数 + * + * 订单总件数 > 包邮件数时,才免运费 + */ + private Integer freeCount; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java index 2d5568915..5fd11f030 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.trade.service.delivery.bo; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import lombok.Data; @@ -13,8 +11,6 @@ import lombok.Data; @Data public class SpuDeliveryExpressTemplateRespBO { - // TODO @jason:是不是可以简单一点;是否包邮;然后直接把 templateCharge、templateFree 需要的字段平铺开 - /** * 配送计费方式 * @@ -25,24 +21,11 @@ public class SpuDeliveryExpressTemplateRespBO { /** * 运费模板快递运费设置 */ - private DeliveryExpressTemplateChargeDO templateCharge; + private DeliveryExpressTemplateChargeBO templateCharge; /** * 运费模板包邮设置 */ - private DeliveryExpressTemplateFreeDO templateFree; - - // TODO @jason:下面两个字段不用返回也可以呀 - /** - * SPU 编号 - *

- * 关联 ProductSpuDO 的 id 编号 - */ - private Long spuId; - - /** - * 区域编号 - */ - private Integer areaId; + private DeliveryExpressTemplateFreeBO templateFree; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index fb006b44b..5a6a762a9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -164,6 +164,15 @@ public class TradePriceCalculateRespBO { */ private Integer payPrice; + /** + * 商品重量,单位:kg 千克 + */ + private Double weight; + /** + * 商品体积,单位:m^3 平米 + */ + private Double volume; + // ========== 商品信息 ========== /** * 商品名 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 95e45182d..222acab9e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -4,17 +4,16 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +22,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND; /** * 运费的 {@link TradePriceCalculator} 实现类 @@ -32,13 +34,12 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. */ @Component @Order(TradePriceCalculator.ORDER_DELIVERY) +@Slf4j public class TradeDeliveryPriceCalculator implements TradePriceCalculator { @Resource private AddressApi addressApi; @Resource - private ProductSkuApi productSkuApi; - @Resource private DeliveryExpressTemplateService deliveryExpressTemplateService; @Override @@ -47,10 +48,10 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { return; } - // 1.2 得到收件地址区域 if (param.getAddressId() == null) { - return; + throw exception(DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY); } + // 1.2 得到收件地址区域 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); @@ -58,33 +59,27 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { List selectedItem = filterList(result.getItems(), OrderItem::getSelected); Set spuIds = convertSet(selectedItem, OrderItem::getSpuId); Map spuExpressTemplateMap = - deliveryExpressTemplateService.getExpressTemplateBySpuIdsAndArea(spuIds, address.getAreaId()); - + deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(spuIds, address.getAreaId()); // 3. 计算配送费用 - // TODO @jason:这里应该不能判断空;如果找不到模版,就要报错;不然配送费就亏了 - if (CollUtil.isNotEmpty(spuExpressTemplateMap)) { - calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); + if (CollUtil.isEmpty(spuExpressTemplateMap)) { + log.error("找不到商品 SPU ID {}, area Id {} ,对应的运费模板", spuIds, address.getAreaId()); + throw exception(PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND); } + calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); } private void calculateDeliveryPrice(List selectedSkus, Map spuExpressTemplateMap, TradePriceCalculateRespBO result) { - // 得到 SKU 详情 - // TODO @jason:可以去掉这里的读取;在 TradePriceCalculateRespBO 初始化的时候,把 weight、volume 拿到 - Set skuIds = convertSet(selectedSkus, OrderItem::getSkuId); - Map skuRespMap = convertMap(productSkuApi.getSkuList(skuIds), ProductSkuRespDTO::getId); // 按 SPU 来计算商品的运费:一个 spuId 可能对应多条订单商品 SKU Map> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId); - // 依次计算每个 SPU 的快递运费 for (Map.Entry> entry : spuIdItemMap.entrySet()) { Long spuId = entry.getKey(); List orderItems = entry.getValue(); - // TODO @jason:如果找不到,则打印 error log SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId); if (templateBO == null) { - // 记录错误日志 + log.error("不能计算快递运费。不能找到 spuId : {}. 对应的运费模板配置 Resp BO", spuId); continue; } // 总件数, 总金额, 总重量, 总体积 @@ -93,22 +88,16 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { double totalWeight = 0; double totalVolume = 0; for (OrderItem orderItem : orderItems) { - totalCount += orderItem.getCount(); - totalPrice += orderItem.getPayPrice(); // 先按应付总金额来算,后面确认一下 TODO @jason:是的哈 - ProductSkuRespDTO skuResp = skuRespMap.get(orderItem.getSkuId()); - // TODO @jason:是不是要保持风格统一,都用 += - totalWeight = totalWeight + skuResp.getWeight() * orderItem.getCount(); - totalVolume = totalVolume + skuResp.getVolume() * orderItem.getCount(); + totalCount += orderItem.getCount(); + totalPrice += orderItem.getPayPrice(); + totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount(); + totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount(); } // 优先判断是否包邮. 如果包邮不计算快递运费 - if (checkExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, + if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, totalVolume, totalPrice, templateBO.getTemplateFree())) { continue; } - // TODO @jason:这块判断,可以收到 calculateExpressFeeByChargeMode 里;另外找不到,要打 error log - if (templateBO.getTemplateCharge() == null) { - continue; - } // 计算快递运费 calculateExpressFeeByChargeMode(totalCount, totalWeight, totalVolume, templateBO.getChargeMode(), templateBO.getTemplateCharge(), orderItems); @@ -128,8 +117,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品项目 */ private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume, - int chargeMode, DeliveryExpressTemplateChargeDO templateCharge, + int chargeMode, DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { + if (templateCharge == null) { + log.error("计算快递运费时,不能找到对应的快递运费模板费用配置。无法计算以下商品 SKU 项目运费: {}", orderItems); + return; + } DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); switch (chargeModeEnum) { case PIECE: { @@ -154,7 +147,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateCharge 快递运费配置 * @param orderItems SKU 商品项目 */ - private void calculateExpressFee(double total, DeliveryExpressTemplateChargeDO templateCharge, List orderItems) { + private void calculateExpressFee(double total, DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { int deliveryPrice; if (total <= templateCharge.getStartCount()) { deliveryPrice = templateCharge.getStartPrice(); @@ -176,11 +169,14 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品 */ private void divideDeliveryPrice(int deliveryPrice, List orderItems) { - // TODO @jason:分摊的话,是不是要按照比例呀?重量、价格、数量等等 + // TODO @jason:分摊的话,是不是要按照比例呀?重量、价格、数量等等, + // 按比例是不是有点复杂。后面看看是否需要 int dividePrice = deliveryPrice / orderItems.size(); for (OrderItem item : orderItems) { // 更新快递运费 item.setDeliveryPrice(dividePrice); + + TradePriceCalculatorHelper.recountPayPrice(item); } } @@ -194,9 +190,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param totalPrice 总金额 * @param templateFree 包邮配置 */ - // TODO @jason:isExpressFree 更合适;因为 check 是一种校验,往往抛出异常; - private boolean checkExpressFree(Integer chargeMode, int totalCount, double totalWeight, - double totalVolume, int totalPrice, DeliveryExpressTemplateFreeDO templateFree) { + private boolean isExpressFree(Integer chargeMode, int totalCount, double totalWeight, + double totalVolume, int totalPrice, DeliveryExpressTemplateFreeBO templateFree) { if (templateFree == null) { return false; } @@ -211,6 +206,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { case WEIGHT: // freeCount 是不是应该是 double ?? // TODO @jason:要不配置的时候,把它的单位和商品对齐?到底是 kg、还是斤 + // TODO @芋艿 目前 包邮 件数/重量/体积 都用的是这个字段 if (totalWeight >= templateFree.getFreeCount() && totalPrice >= templateFree.getFreePrice()) { return true; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index d171e50cf..7945c72eb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -53,7 +53,8 @@ public class TradePriceCalculatorHelper { orderItem.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * item.getCount()) .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); // sku 信息 - orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()); + orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()) + .setWeight(sku.getWeight()).setVolume(sku.getVolume()); // spu 信息 orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()); if (orderItem.getPicUrl() == null) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java new file mode 100644 index 000000000..e6af92430 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java @@ -0,0 +1,168 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.member.api.address.AddressApi; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum.PIECE; +import static cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum.EXPRESS; +import static java.util.Arrays.asList; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author jason + */ +public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradeDeliveryPriceCalculator calculator; + @Mock + private AddressApi addressApi; + @Mock + private DeliveryExpressTemplateService deliveryExpressTemplateService; + + private TradePriceCalculateReqBO reqBO; + private TradePriceCalculateRespBO resultBO; + private AddressRespDTO addressResp; + private DeliveryExpressTemplateChargeBO chargeBO; + private DeliveryExpressTemplateFreeBO freeBO; + private SpuDeliveryExpressTemplateRespBO spuTemplateRespBO; + + @BeforeEach + public void init(){ + // 准备参数 + reqBO = new TradePriceCalculateReqBO() + .setDeliveryType(EXPRESS.getMode()) + .setAddressId(10L) + .setUserId(1L) + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(10).setSelected(true), + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(false) + )); + resultBO = new TradePriceCalculateRespBO() + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(10L).setCount(2).setSelected(true) + .setWeight(10d).setVolume(10d).setPrice(100), + new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(20L).setCount(10).setSelected(true) + .setWeight(10d).setVolume(10d).setPrice(200), + new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(30L).setCount(1).setSelected(false) + .setWeight(10d).setVolume(10d).setPrice(300) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(resultBO.getItems()); + TradePriceCalculatorHelper.recountAllPrice(resultBO); + // 准备收件地址数据 + addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); + // 准备运费模板费用配置数据 + chargeBO = randomPojo(DeliveryExpressTemplateChargeBO.class, + item -> item.setStartCount(10D).setStartPrice(1000).setExtraCount(10D).setExtraPrice(2000)); + // 准备运费模板包邮配置数据 订单总件数 < 包邮件数时 12 < 20 + freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + item -> item.setFreeCount(20).setFreePrice(100)); + // 准备 SP 运费模板 数据 + spuTemplateRespBO = randomPojo(SpuDeliveryExpressTemplateRespBO.class, + item -> item.setChargeMode(PIECE.getType()) + .setTemplateCharge(chargeBO).setTemplateFree(freeBO)); + } + + @Test + @DisplayName("按件计算运费不包邮的情况") + public void testCalculateByExpressTemplateCharge() { + // SKU 1 : 100 * 2 = 200 + // SKU 2 :200 * 10 = 2000 + // 运费 首件 1000 + 续件 2000 = 3000 + Map respMap = new HashMap<>(); + respMap.put(1L, spuTemplateRespBO); + + // mock 方法 + when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); + when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + .thenReturn(respMap); + + calculator.calculate(reqBO, resultBO); + + TradePriceCalculateRespBO.Price price = resultBO.getPrice(); + + assertThat(price) + .extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice") + .containsExactly(2200, 0, 0, 0, 3000, 5200); + // 断言:SKU + assertThat(resultBO.getItems()).hasSize(3); + // SKU1 + assertThat(resultBO.getItems().get(0)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(100, 2, 0, 0, 0, 1500, 1700); + // SKU2 + assertThat(resultBO.getItems().get(1)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(200, 10, 0, 0, 0, 1500, 3500); + // SKU3 未选中 + assertThat(resultBO.getItems().get(2)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(300, 1, 0, 0, 0, 0, 300); + } + + @Test + @DisplayName("按件计算运费包邮的情况") + public void testCalculateByExpressTemplateFree() { + // SKU 1 : 100 * 2 = 200 + // SKU 2 :200 * 10 = 2000 + // 运费 0 + Map respMap = new HashMap<>(); + respMap.put(1L, spuTemplateRespBO); + // 准备运费模板包邮配置数据 包邮 订单总件数 > 包邮件数时 12 > 10 + freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + item -> item.setFreeCount(10).setFreePrice(1000)); + spuTemplateRespBO.setTemplateFree(freeBO); + // mock 方法 + when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); + when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + .thenReturn(respMap); + + calculator.calculate(reqBO, resultBO); + + TradePriceCalculateRespBO.Price price = resultBO.getPrice(); + + // 断言price + assertThat(price) + .extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice") + .containsExactly(2200, 0, 0, 0, 0, 2200); + // 断言:SKU + assertThat(resultBO.getItems()).hasSize(3); + // SKU1 + assertThat(resultBO.getItems().get(0)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(100, 2, 0, 0, 0, 0, 200); + // SKU2 + assertThat(resultBO.getItems().get(1)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(200, 10, 0, 0, 0, 0, 2000); + // SKU3 未选中 + assertThat(resultBO.getItems().get(2)) + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") + .containsExactly(300, 1, 0, 0, 0, 0, 300); + } +} \ No newline at end of file From bb8e44a26840d5b6ad9a39d55ce7478cd54dcf81 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 Jun 2023 00:17:22 +0800 Subject: [PATCH 094/232] =?UTF-8?q?mall=20+=20product=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=AF=84=E8=AE=BA=20mock=20=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/comment/AppCommentController.java | 78 ++++++++++++++++++- .../app/comment/vo/AppCommentBaseVO.java | 6 +- .../app/comment/vo/AppCommentRespVO.java | 10 --- .../dataobject/comment/ProductCommentDO.java | 2 +- 4 files changed, 80 insertions(+), 16 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java index 7d05161e7..3c9359412 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.app.comment; +import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; @@ -7,16 +8,20 @@ import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.Map; +import java.time.LocalDateTime; +import java.util.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -34,6 +39,66 @@ public class AppCommentController { @Resource private MemberUserApi memberUserApi; + @GetMapping("/list") + @Operation(summary = "获得最近的 n 条商品评价") + @Parameters({ + @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"), + @Parameter(name = "count", description = "数量", required = true, example = "10") + }) + public CommonResult> getCommentList(@RequestParam("spuId") Long spuId, + @RequestParam(value = "count", defaultValue = "10") Integer count) { + + List list = new ArrayList<>(); + + AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO(); + item1.setPropertyId(1L); + item1.setPropertyName("颜色"); + item1.setValueId(1024L); + item1.setValueName("红色"); + list.add(item1); + + AppProductPropertyValueDetailRespVO item2 = new AppProductPropertyValueDetailRespVO(); + item2.setPropertyId(2L); + item2.setPropertyName("尺寸"); + item2.setValueId(2048L); + item2.setValueName("大号"); + list.add(item2); + + AppProductPropertyValueDetailRespVO item3 = new AppProductPropertyValueDetailRespVO(); + item3.setPropertyId(3L); + item3.setPropertyName("重量"); + item3.setValueId(3072L); + item3.setValueName("500克"); + list.add(item3); + + // TODO 生成 mock 的数据 + AppCommentRespVO appCommentRespVO = new AppCommentRespVO(); + appCommentRespVO.setUserId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setUserNickname("用户" + new Random().nextInt(100)); + appCommentRespVO.setUserAvatar("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); + appCommentRespVO.setId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setAnonymous(new Random().nextBoolean()); + appCommentRespVO.setOrderId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setOrderItemId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setReplyStatus(new Random().nextBoolean()); + appCommentRespVO.setReplyUserId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setReplyContent("回复内容" + new Random().nextInt(100)); + appCommentRespVO.setReplyTime(LocalDateTime.now().minusDays(new Random().nextInt(30))); + appCommentRespVO.setCreateTime(LocalDateTime.now().minusDays(new Random().nextInt(30))); + appCommentRespVO.setFinalScore(new Random().nextInt(5) + 1); + appCommentRespVO.setSpuId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setSpuName("商品" + new Random().nextInt(100)); + appCommentRespVO.setSkuId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setSkuProperties(list); + appCommentRespVO.setScores(new Random().nextInt(5) + 1); + appCommentRespVO.setDescriptionScores(new Random().nextInt(5) + 1); + appCommentRespVO.setBenefitScores(new Random().nextInt(5) + 1); + appCommentRespVO.setContent("评论内容" + new Random().nextInt(100)); + appCommentRespVO.setPicUrls(Arrays.asList("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg")); + + return success(Arrays.asList(appCommentRespVO)); + } + @GetMapping("/page") @Operation(summary = "获得商品评价分页") public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { @@ -41,10 +106,15 @@ public class AppCommentController { } // TODO @puhui999:方法名改成 getCommentStatistics?然后搞个对应的 vo?想了下,这样更优雅 - @GetMapping("/get-count") + @GetMapping("/statistics") @Operation(summary = "获得商品的评价统计") // TODO @puhui999:@RequestParam 哈,针对 spuId - public CommonResult> getCommentPage(@Valid Long spuId) { - return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); + public CommonResult> getCommentStatistics(@Valid Long spuId) { + // TODO 生成 mock 的数据 + if (true) { + return success(MapUtil.builder("allCount", 10L).put("goodPercent", "10.33").build()); + } + return null; +// return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); } @PostMapping(value = "/create") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java index 2cbefad01..12910f25e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.app.comment.vo; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -7,7 +8,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.List; -// TODO @puhui999:把 Product 前缀给补下哈 +// TODO @puhui999:C 端可以不要 base 哈。 @Data public class AppCommentBaseVO { @@ -23,6 +24,9 @@ public class AppCommentBaseVO { @NotNull(message = "商品SKU编号不能为空") private Long skuId; + @Schema(description = "商品 SKU 属性", required = true) + private List skuProperties; // TODO puhui999:这个需要从数据库查询哈 + @Schema(description = "评分星级 1-5分", required = true) @NotNull(message = "评分星级 1-5分不能为空") private Integer scores; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java index 77c419b96..69456030b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java @@ -6,7 +6,6 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -import java.util.List; @Schema(description = "用户APP - 商品评价 Response VO") @Data @@ -49,15 +48,6 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "商家回复时间") private LocalDateTime replyTime; - @Schema(description = "追加评价内容") - private String additionalContent; - - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") - private List additionalPicUrls; - - @Schema(description = "追加评价时间") - private LocalDateTime additionalTime; - @Schema(description = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index cf7b47051..5082b2da9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -35,7 +35,7 @@ public class ProductCommentDO extends BaseDO { private Long id; /** - * 评价人 用户编号 + * 评价人的用户编号 * * 关联 MemberUserDO 的 id 编号 */ From 9e894e04306bdd37ef0de348a3818d6b01ea231d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 Jun 2023 09:57:37 +0800 Subject: [PATCH 095/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=BC=98=E6=83=A0=E5=8A=B5=E7=9A=84=20mock=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductCommentServiceImplTest.java | 27 ------ .../app/coupon/AppCouponController.java | 28 +++++++ .../coupon/AppCouponTemplateController.java | 84 +++++++++++++++++++ .../coupon/vo/coupon/AppCouponTakeReqVO.java | 16 ++++ .../template/AppCouponTemplatePageReqVO.java | 19 +++++ .../vo/template/AppCouponTemplateRespVO.java | 68 +++++++++++++++ 6 files changed, 215 insertions(+), 27 deletions(-) create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponTakeReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 6754f3ba0..520555141 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -4,12 +4,10 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; @@ -93,12 +91,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setSkuId(generateId()); o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores()); o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores()); - o.setDeliveryScores(ProductCommentScoresEnum.FOUR.getScores()); o.setContent("真好吃"); o.setReplyUserId(generateId()); o.setReplyContent("确实"); o.setReplyTime(LocalDateTime.now()); - o.setAdditionalTime(LocalDateTime.now()); o.setCreateTime(LocalDateTime.now()); o.setUpdateTime(LocalDateTime.now()); }); @@ -196,27 +192,4 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals("测试", productCommentDO.getReplyContent()); } - @Test - public void testCreateComment_success() { - // mock 测试 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { - o.setAdditionalContent(""); - }); - - productCommentService.createComment(productComment, Boolean.TRUE); - - MemberUserRespDTO user = new MemberUserRespDTO(); - user.setId(productComment.getUserId()); - - AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO(); - createReqVO.setId(productComment.getId()); - createReqVO.setAdditionalContent("追加"); - createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls()); - - productCommentService.additionalComment(user, createReqVO); - ProductCommentDO exist = productCommentMapper.selectById(productComment.getId()); - - assertEquals("追加", exist.getAdditionalContent()); - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java new file mode 100755 index 000000000..a0804079b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.controller.app.coupon; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplatePageReqVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 App - 优惠劵") +@RestController +@RequestMapping("/promotion/coupon") +@Validated +public class AppCouponController { + + // TODO 芋艿:待实现 + @PostMapping("/take") + @Operation(description = "领取优惠劵") + public CommonResult takeCoupon(@RequestBody AppCouponTemplatePageReqVO pageReqVO) { + return success(1L); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java new file mode 100755 index 000000000..f08bd0d74 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.promotion.controller.app.coupon; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplatePageReqVO; +import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplateRespVO; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 App - 优惠劵模板") +@RestController +@RequestMapping("/promotion/coupon-template") +@Validated +public class AppCouponTemplateController { + + @Resource + private CouponTemplateService couponTemplateService; + + // TODO 芋艿:待实现 + @GetMapping("/list") + @Operation(description = "获得优惠劵模版列表") // 目前主要给商品详情使用 + @Parameters({ + @Parameter(name = "spuId", description = "商品 SPU 编号", required = true), + @Parameter(name = "useType", description = "使用类型"), + @Parameter(name = "count", description = "数量", required = true) + }) + public CommonResult> getCouponTemplateList(@RequestParam("spuId") Long spuId, + @RequestParam(value = "useType", required = false) Integer useType) { + List list = new ArrayList<>(); + Random random = new Random(); + for (int i = 0; i < 10; i++) { + AppCouponTemplateRespVO vo = new AppCouponTemplateRespVO(); + vo.setId(i + 1L); + vo.setName("优惠劵" + (i + 1)); + vo.setTakeLimitCount(random.nextInt(10) + 1); + vo.setUsePrice(random.nextInt(100) * 100); + vo.setValidityType(random.nextInt(2) + 1); + if (vo.getValidityType() == 1) { + vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10))); + vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10)); + } else { + vo.setFixedStartTerm(random.nextInt(10)); + vo.setFixedEndTerm(random.nextInt(10) + vo.getFixedStartTerm() + 1); + } + vo.setDiscountType(random.nextInt(2) + 1); + if (vo.getDiscountType() == 1) { + vo.setDiscountPercent(null); + vo.setDiscountPrice(random.nextInt(50) * 100); + vo.setDiscountLimitPrice(null); + } else { + vo.setDiscountPercent(random.nextInt(90) + 10); + vo.setDiscountPrice(null); + vo.setDiscountLimitPrice(random.nextInt(200) * 100); + } + vo.setTakeStatus(random.nextBoolean()); + list.add(vo); + } + return success(list); + } + + // TODO 芋艿:待实现 + @GetMapping("/page") + @Operation(description = "获得优惠劵模版分页") + public CommonResult> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) { + return null; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponTakeReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponTakeReqVO.java new file mode 100644 index 000000000..0f71fe2bf --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponTakeReqVO.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 App - 优惠劵领取 Request VO") +@Data +public class AppCouponTakeReqVO { + + @Schema(description = "优惠劵模板编号", example = "1") + @NotNull(message = "优惠劵模板编号不能为空") + private Long templateId; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java new file mode 100644 index 000000000..6eda32167 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "用户 App - 优惠劵模板分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCouponTemplatePageReqVO extends PageParam { + + @Schema(description = "使用类型", example = "1") + // TODO 芋艿:这里要限制下枚举的使用 + private Integer useType; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java new file mode 100755 index 000000000..5e8aa86ef --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Min; +import java.time.LocalDateTime; + +@Schema(description = "用户 App - 优惠劵模板 Response VO") +@Data +public class AppCouponTemplateRespVO { + + @Schema(description = "优惠劵模板编号", required = true, example = "1") + private Long id; + + @Schema(description = "优惠劵名", required = true, example = "春节送送送") + private String name; + + @Schema(description = "每人限领个数", required = true, example = "66") // -1 - 则表示不限制 + private Integer takeLimitCount; + + @Schema(description = "是否设置满多少金额可用", required = true, example = "100") // 单位:分;0 - 不限制 + private Integer usePrice; + + // TODO 芋艿:这两要改的 +// @Schema(description = "商品范围", required = true, example = "1") +// @InEnum(PromotionProductScopeEnum.class) +// private Integer productScope; +// +// @Schema(description = "商品 SPU 编号的数组", example = "1,3") +// private List productSpuIds; + + @Schema(description = "生效日期类型", required = true, example = "1") + private Integer validityType; + + @Schema(description = "固定日期 - 生效开始时间") + private LocalDateTime validStartTime; + + @Schema(description = "固定日期 - 生效结束时间") + private LocalDateTime validEndTime; + + @Schema(description = "领取日期 - 开始天数") + @Min(value = 0L, message = "开始天数必须大于 0") + private Integer fixedStartTerm; + + @Schema(description = "领取日期 - 结束天数") + @Min(value = 1L, message = "开始天数必须大于 1") + private Integer fixedEndTerm; + + @Schema(description = "优惠类型", required = true, example = "1") + private Integer discountType; + + @Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80 + private Integer discountPercent; + + @Schema(description = "优惠金额", example = "10") + @Min(value = 0, message = "优惠金额需要大于等于 0") + private Integer discountPrice; + + @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用 + private Integer discountLimitPrice; + + // ========== 用户相关字段 ========== + + @Schema(description = "是否已领取", required = true, example = "true") + private Boolean takeStatus; + +} From 4f5ac0edbbf925a2aaa865dcad3b357207488038 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 Jun 2023 17:51:15 +0800 Subject: [PATCH 096/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8=E7=9A=84=20mock?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/query/LambdaQueryWrapperX.java | 1 - .../app/spu/AppProductSpuController.java | 21 ++++-- .../app/spu/vo/AppProductSpuDetailRespVO.java | 5 ++ .../app/spu/vo/AppProductSpuPageReqVO.java | 3 +- ...spVO.java => AppProductSpuPageRespVO.java} | 9 ++- .../convert/spu/ProductSpuConvert.java | 31 ++++----- .../dal/mysql/spu/ProductSpuMapper.java | 36 +++++++--- .../service/spu/ProductSpuService.java | 9 +++ .../service/spu/ProductSpuServiceImpl.java | 5 ++ .../enums/common/PromotionTypeEnum.java | 12 ++-- .../app/AppMarketTestController.java | 24 ------- .../app/activity/AppActivityController.java | 65 +++++++++++++++++++ .../app/activity/vo/AppActivityRespVO.java | 27 ++++++++ .../trade/enums/order/TradeOrderTypeEnum.java | 6 +- 14 files changed, 186 insertions(+), 68 deletions(-) rename yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/{AppProductSpuPageItemRespVO.java => AppProductSpuPageRespVO.java} (81%) delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java index 342fa4611..4fe20bd4b 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.query; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 693e8e911..5d79ba7d1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.controller.app.spu; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -40,12 +40,23 @@ public class AppProductSpuController { private ProductSpuService productSpuService; @Resource private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; + + @GetMapping("/list") + @Operation(summary = "获得商品 SPU 列表") + @Parameters({ + @Parameter(name = "recommendType", description = "推荐类型", required = true), // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量 + @Parameter(name = "count", description = "数量", required = true) + }) + public CommonResult> getSpuList( + @RequestParam("recommendType") String recommendType, + @RequestParam(value = "count", defaultValue = "10") Integer count) { + List list = productSpuService.getSpuList(recommendType, count); + return success(ProductSpuConvert.INSTANCE.convertListForGetSpuList(list)); + } @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") - public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { + public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { PageResult pageResult = productSpuService.getSpuPage(pageVO); return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index a543f0af2..60f1c6c57 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -39,6 +39,11 @@ public class AppProductSpuDetailRespVO { @Schema(description = "单位名", required = true, example = "个") private String unitName; + // ========== 营销相关字段 ========= + + @Schema(description = "活动排序数组", required = true, example = "1024") + private List activityOrders; + // ========== SKU 相关字段 ========= @Schema(description = "规格类型", required = true, example = "true") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java index 5050561d6..653ca5215 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java @@ -20,6 +20,7 @@ public class AppProductSpuPageReqVO extends PageParam { public static final String SORT_FIELD_SALES_COUNT = "salesCount"; public static final String RECOMMEND_TYPE_HOT = "hot"; + public static final String RECOMMEND_TYPE_GOOD = "good"; @Schema(description = "分类编号", example = "1") private Long categoryId; @@ -33,7 +34,7 @@ public class AppProductSpuPageReqVO extends PageParam { @Schema(description = "排序方式", example = "true") private Boolean sortAsc; - @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常亮 + @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量 private String recommendType; @AssertTrue(message = "排序字段不合法") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java similarity index 81% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java index 68812b754..85658b0e7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java @@ -5,9 +5,9 @@ import lombok.Data; import java.util.List; -@Schema(description = "用户 App - 商品 SPU 分页项 Response VO") +@Schema(description = "用户 App - 商品 SPU Response VO") @Data -public class AppProductSpuPageItemRespVO { +public class AppProductSpuPageRespVO { @Schema(description = "商品 SPU 编号", required = true, example = "1") private Long id; @@ -35,6 +35,11 @@ public class AppProductSpuPageItemRespVO { @Schema(description = "库存", required = true, example = "666") private Integer stock; + // ========== 营销相关字段 ========= + + @Schema(description = "活动排序数组", required = true, example = "1024") + private List activityOrders; + // ========== 统计相关字段 ========= @Schema(description = "商品销量", required = true, example = "1024") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 80902660c..f525f3134 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -1,14 +1,12 @@ package cn.iocoder.yudao.module.product.convert.spu; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; @@ -80,14 +78,15 @@ public interface ProductSpuConvert { // ========== 用户 App 相关 ========== - default PageResult convertPageForGetSpuPage(PageResult page) { - // 累加虚拟销量 - page.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); - // 然后进行转换 - return convertPageForGetSpuPage0(page); - } + PageResult convertPageForGetSpuPage(PageResult page); - PageResult convertPageForGetSpuPage0(PageResult page); + default List convertListForGetSpuList(List list) { + // 处理虚拟销量 + list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); + return convertListForGetSpuList0(list); + } + @Named("convertListForGetSpuList0") + List convertListForGetSpuList0(List list); default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus) { // 处理 SPU @@ -109,15 +108,9 @@ public interface ProductSpuConvert { List convertListForGetSpuDetail(List skus); default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus) { - ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu); - // skus 为空直接返回 - if (CollUtil.isEmpty(skus)) { - return productSpuDetailRespVO; - } - List skuVOs = ProductSkuConvert.INSTANCE.convertList(skus); - // fix: 因为现在已改为 sku 属性列表 属性 已包含 属性名字 属性值名字 所以不需要再额外处理,属性更新时更新 sku 中的属性相关冗余即可 - productSpuDetailRespVO.setSkus(skuVOs); - return productSpuDetailRespVO; + ProductSpuDetailRespVO detailRespVO = convert03(spu); + detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus)); + return detailRespVO; } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 27a393ee6..9c237fa9f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; @@ -66,7 +67,10 @@ public interface ProductSpuMapper extends BaseMapperX { // 推荐类型的过滤条件 if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { query.eq(ProductSpuDO::getRecommendHot, true); + } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) { + query.eq(ProductSpuDO::getRecommendGood, true); } + // 排序逻辑 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC", @@ -80,6 +84,21 @@ public interface ProductSpuMapper extends BaseMapperX { return selectPage(pageReqVO, query); } + default List selectListByRecommendType(String recommendType, Integer count) { + QueryWrapperX query = new QueryWrapperX<>(); + // 上架状态 且有库存 + query.eq("status", ProductSpuStatusEnum.ENABLE.getStatus()).gt("stock", 0); + // 推荐类型的过滤条件 + if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { + query.eq("recommend_hot", true); + } else if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) { + query.eq("recommend_good", true); + } + // 设置最大长度 + query.limitN(count); + return selectList(query); + } + /** * 更新商品 SPU 库存 * @@ -111,33 +130,34 @@ public interface ProductSpuMapper extends BaseMapperX { } /** - * 验证选项卡类型构建条件 + * 添加后台 Tab 选项的查询条件 * * @param tabType 标签类型 - * @param queryWrapper 查询条件 + * @param query 查询条件 */ - static void appendTabQuery(Integer tabType, LambdaQueryWrapperX queryWrapper) { + static void appendTabQuery(Integer tabType, LambdaQueryWrapperX query) { // 出售中商品 if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) { - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); } // 仓储中商品 if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) { - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); } // 已售空商品 if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) { - queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0); + query.eqIfPresent(ProductSpuDO::getStock, 0); } // 警戒库存 if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) { - queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) + query.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示 .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } // 回收站 if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) { - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); } } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 102b5e1fa..f381e6de6 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -98,6 +98,15 @@ public interface ProductSpuService { */ PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO); + /** + * 获得商品 SPU 列表,提供给用户 App 使用 + * + * @param recommendType 推荐类型 + * @param count 数量 + * @return 商品 SPU 列表 + */ + List getSpuList(String recommendType, Integer count); + /** * 更新商品 SPU 库存(增量) * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 297259509..3ada0be78 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -201,6 +201,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { return productSpuMapper.selectPage(pageReqVO, categoryIds); } + @Override + public List getSpuList(String recommendType, Integer count) { + return productSpuMapper.selectListByRecommendType(recommendType, count); + } + @Override @Transactional(rollbackFor = Exception.class) public void updateSpuStock(Map stockIncrCounts) { diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java index ee87306bf..874651ea3 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java @@ -15,11 +15,15 @@ import java.util.Arrays; @AllArgsConstructor public enum PromotionTypeEnum implements IntArrayValuable { - DISCOUNT_ACTIVITY(1, "限时折扣"), - REWARD_ACTIVITY(2, "满减送"), + SECKILL_ACTIVITY(1, "秒杀活动"), + BARGAIN_ACTIVITY(2, "拼团活动"), + COMBINATION_ACTIVITY(3, "砍价活动"), - MEMBER(3, "会员折扣"), // TODO 芋艿:待实现 StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice) - COUPON(4, "优惠劵") + DISCOUNT_ACTIVITY(4, "限时折扣"), + REWARD_ACTIVITY(5, "满减送"), + + MEMBER(6, "会员折扣"), + COUPON(7, "优惠劵") ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java deleted file mode 100644 index cafddecf5..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.app; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "用户 App - 营销") -@RestController -@RequestMapping("/market/test") -@Validated -public class AppMarketTestController { - - @GetMapping("/get") - @Operation(summary = "获取 market 信息") - public CommonResult get() { - return success("true"); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java new file mode 100644 index 000000000..a616bfeda --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.promotion.controller.app.activity; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.app.activity.vo.AppActivityRespVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 营销活动") // 用于提供跨多个活动的 HTTP 接口 +@RestController +@RequestMapping("/promotion/activity") +@Validated +public class AppActivityController { + + @GetMapping("/list-by-spu-id") + @Operation(summary = "获得单个商品,近期参与的每个活动") // 每种活动,只返回一个 + @Parameter(name = "spuId", description = "商品编号", required = true) + public CommonResult> getActivityListBySpuId(@RequestParam("spuId") Long spuId) { + // TODO 芋艿,实现 + List randomList = new ArrayList<>(); + Random random = new Random(); + for (int i = 0; i < 3; i++) { // 生成5个随机对象 + AppActivityRespVO vo = new AppActivityRespVO(); + vo.setId(random.nextLong()); // 随机生成一个长整型 ID + vo.setType(i + 1); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一 + vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数 + vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位) + vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位) + randomList.add(vo); + } + return success(randomList); + } + + @GetMapping("/list-by-spu-ids") + @Operation(summary = "获得多个商品,近期参与的每个活动") // 每种活动,只返回一个;key 为 SPU 编号 + @Parameter(name = "spuIds", description = "商品编号数组", required = true) + public CommonResult>> getActivityListBySpuIds(@RequestParam("spuIds") List spuIds) { + // TODO 芋艿,实现 + List randomList = new ArrayList<>(); + Random random = new Random(); + for (int i = 0; i < 5; i++) { // 生成5个随机对象 + AppActivityRespVO vo = new AppActivityRespVO(); + vo.setId(random.nextLong()); // 随机生成一个长整型 ID + vo.setType(random.nextInt(3)); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一 + vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数 + vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位) + vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位) + randomList.add(vo); + } + Map> map = new HashMap<>(); + map.put(109L, randomList); + return success(map); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java new file mode 100644 index 000000000..064cc21a2 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.controller.app.activity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "用户 App - 营销活动 Response VO") +@Data +public class AppActivityRespVO { + + @Schema(description = "活动编号", required = true, example = "1024") + private Long id; + + @Schema(description = "活动类型", required = true, example = "1") // 对应 PromotionTypeEnum 枚举 + private Integer type; + + @Schema(description = "活动名称", required = true, example = "618 大促") + private String name; + + @Schema(description = "活动开始时间", required = true) + private LocalDateTime startTime; + + @Schema(description = "活动结束时间", required = true) + private LocalDateTime endTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java index 34e47a12e..27596197f 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java @@ -17,10 +17,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { NORMAL(0, "普通订单"), SECKILL(1, "秒杀订单"), - // TODO 芋艿:如下三个字段,名字需要改下,等后面表设计完成后。 - KANJIA(2, "砍价订单"), - PINTUAN(3, "拼团订单"), - YUSHOU(4, "预售订单"), + BARGAIN(2, "砍价订单"), + COMBINATION(3, "拼团订单"), ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); From 73d0e9d08aa241e5b314c57b45bdec60a7179baf Mon Sep 17 00:00:00 2001 From: xiaqing Date: Sat, 10 Jun 2023 20:44:31 +0800 Subject: [PATCH 097/232] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E6=A8=A1=E5=9D=97=201.=E7=A7=AF=E5=88=86=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=AE=A1=E7=90=86=202.=E7=A7=AF=E5=88=86=E7=AD=BE?= =?UTF-8?q?=E5=88=B0=E8=A7=84=E5=88=99=E7=AE=A1=E7=90=86=203.=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=A7=AF=E5=88=86=E8=AE=B0=E5=BD=95=E7=AE=A1=E7=90=86?= =?UTF-8?q?=204.=E7=94=A8=E6=88=B7=E7=AD=BE=E5=88=B0=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-point/pom.xml | 19 ++ .../yudao-module-point-api/pom.xml | 28 +++ .../point/enums/ErrorCodeConstants.java | 27 +++ .../yudao-module-point-biz/pom.xml | 57 ++++++ .../pointconfig/PointConfigController.java | 102 ++++++++++ .../pointconfig/vo/PointConfigBaseVO.java | 30 +++ .../vo/PointConfigCreateReqVO.java | 14 ++ .../pointconfig/vo/PointConfigExcelVO.java | 45 +++++ .../vo/PointConfigExportReqVO.java | 15 ++ .../pointconfig/vo/PointConfigPageReqVO.java | 17 ++ .../pointconfig/vo/PointConfigRespVO.java | 22 +++ .../vo/PointConfigUpdateReqVO.java | 18 ++ .../pointrecord/PointRecordController.java | 102 ++++++++++ .../pointrecord/vo/PointRecordBaseVO.java | 67 +++++++ .../vo/PointRecordCreateReqVO.java | 14 ++ .../pointrecord/vo/PointRecordExcelVO.java | 65 +++++++ .../vo/PointRecordExportReqVO.java | 27 +++ .../pointrecord/vo/PointRecordPageReqVO.java | 29 +++ .../pointrecord/vo/PointRecordRespVO.java | 19 ++ .../vo/PointRecordUpdateReqVO.java | 18 ++ .../signinconfig/SignInConfigController.java | 102 ++++++++++ .../signinconfig/vo/SignInConfigBaseVO.java | 23 +++ .../vo/SignInConfigCreateReqVO.java | 14 ++ .../signinconfig/vo/SignInConfigExcelVO.java | 28 +++ .../vo/SignInConfigExportReqVO.java | 15 ++ .../vo/SignInConfigPageReqVO.java | 17 ++ .../signinconfig/vo/SignInConfigRespVO.java | 19 ++ .../vo/SignInConfigUpdateReqVO.java | 18 ++ .../signinrecord/SignInRecordController.java | 102 ++++++++++ .../signinrecord/vo/SignInRecordBaseVO.java | 26 +++ .../vo/SignInRecordCreateReqVO.java | 14 ++ .../signinrecord/vo/SignInRecordExcelVO.java | 34 ++++ .../vo/SignInRecordExportReqVO.java | 26 +++ .../vo/SignInRecordPageReqVO.java | 28 +++ .../signinrecord/vo/SignInRecordRespVO.java | 19 ++ .../vo/SignInRecordUpdateReqVO.java | 18 ++ .../pointconfig/PointConfigConvert.java | 34 ++++ .../pointrecord/PointRecordConvert.java | 34 ++++ .../signinconfig/SignInConfigConvert.java | 34 ++++ .../signinrecord/SignInRecordConvert.java | 34 ++++ .../dataobject/pointconfig/PointConfigDO.java | 51 +++++ .../dataobject/pointrecord/PointRecordDO.java | 82 ++++++++ .../signinconfig/SignInConfigDO.java | 39 ++++ .../signinrecord/SignInRecordDO.java | 43 ++++ .../mysql/pointconfig/PointConfigMapper.java | 32 +++ .../mysql/pointrecord/PointRecordMapper.java | 40 ++++ .../signinconfig/SignInConfigMapper.java | 41 ++++ .../signinrecord/SignInRecordMapper.java | 36 ++++ .../pointconfig/PointConfigService.java | 70 +++++++ .../pointconfig/PointConfigServiceImpl.java | 92 +++++++++ .../pointrecord/PointRecordService.java | 70 +++++++ .../pointrecord/PointRecordServiceImpl.java | 82 ++++++++ .../signinconfig/SignInConfigService.java | 70 +++++++ .../signinconfig/SignInConfigServiceImpl.java | 102 ++++++++++ .../signinrecord/SignInRecordService.java | 70 +++++++ .../signinrecord/SignInRecordServiceImpl.java | 82 ++++++++ .../mapper/pointconfig/PointConfigMapper.xml | 12 ++ .../mapper/pointrecord/PointRecordMapper.xml | 12 ++ .../signinconfig/SignInConfigMapper.xml | 12 ++ .../signinrecord/SignInRecordMapper.xml | 12 ++ .../PointConfigServiceImplTest.java | 152 +++++++++++++++ .../PointRecordServiceImplTest.java | 183 ++++++++++++++++++ .../SignInConfigServiceImplTest.java | 152 +++++++++++++++ .../SignInRecordServiceImplTest.java | 167 ++++++++++++++++ yudao-server/pom.xml | 40 ++-- 65 files changed, 3101 insertions(+), 17 deletions(-) create mode 100644 yudao-module-point/pom.xml create mode 100644 yudao-module-point/yudao-module-point-api/pom.xml create mode 100644 yudao-module-point/yudao-module-point-api/src/main/java/cn/iocoder/yudao/module/point/enums/ErrorCodeConstants.java create mode 100644 yudao-module-point/yudao-module-point-biz/pom.xml create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/PointRecordController.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordBaseVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordCreateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExcelVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExportReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordPageReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordRespVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordUpdateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/SignInConfigController.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigBaseVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigCreateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExcelVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExportReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigPageReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigRespVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigUpdateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/SignInRecordController.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordBaseVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordCreateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExcelVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExportReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordPageReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordRespVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordUpdateReqVO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointrecord/PointRecordConvert.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinconfig/SignInConfigConvert.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinrecord/SignInRecordConvert.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointrecord/PointRecordDO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinconfig/SignInConfigDO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinrecord/SignInRecordDO.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointrecord/PointRecordMapper.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinconfig/SignInConfigMapper.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinrecord/SignInRecordMapper.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordService.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImpl.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigService.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImpl.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordService.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImpl.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml create mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml create mode 100644 yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImplTest.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImplTest.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImplTest.java create mode 100644 yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImplTest.java diff --git a/yudao-module-point/pom.xml b/yudao-module-point/pom.xml new file mode 100644 index 000000000..f0361dd60 --- /dev/null +++ b/yudao-module-point/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + cn.iocoder.boot + yudao + ${revision} + + + yudao-module-point + pom + + yudao-module-point-api + + + + \ No newline at end of file diff --git a/yudao-module-point/yudao-module-point-api/pom.xml b/yudao-module-point/yudao-module-point-api/pom.xml new file mode 100644 index 000000000..83898557f --- /dev/null +++ b/yudao-module-point/yudao-module-point-api/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + cn.iocoder.boot + yudao-module-point + ${revision} + + + yudao-module-point-api + jar + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + \ No newline at end of file diff --git a/yudao-module-point/yudao-module-point-api/src/main/java/cn/iocoder/yudao/module/point/enums/ErrorCodeConstants.java b/yudao-module-point/yudao-module-point-api/src/main/java/cn/iocoder/yudao/module/point/enums/ErrorCodeConstants.java new file mode 100644 index 000000000..8d4daf0fc --- /dev/null +++ b/yudao-module-point/yudao-module-point-api/src/main/java/cn/iocoder/yudao/module/point/enums/ErrorCodeConstants.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.point.enums; + + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Pay 错误码 Core 枚举类 + * + * pay 系统,使用 1-007-000-000 段 + */ +public interface ErrorCodeConstants { + + ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(499, "积分设置不存在"); + + ErrorCode CONFIG_EXISTS = new ErrorCode(499, "积分设置已存在,只允配置一条记录"); + + + ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(499, "签到天数规则不存在"); + ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(499, "签到天数规则已存在"); + + ErrorCode RECORD_NOT_EXISTS = new ErrorCode( 499, "用户积分记录不存在"); + + ErrorCode SIGN_IN_RECORD_NOT_EXISTS = new ErrorCode(499, "用户签到积分不存在"); + + + +} diff --git a/yudao-module-point/yudao-module-point-biz/pom.xml b/yudao-module-point/yudao-module-point-biz/pom.xml new file mode 100644 index 000000000..fc4561441 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + cn.iocoder.boot + yudao-module-point + ${revision} + + + yudao-module-point-biz + jar + + + + cn.iocoder.boot + yudao-module-point-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + \ No newline at end of file diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java new file mode 100644 index 000000000..137d03050 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; +import cn.iocoder.yudao.module.point.convert.pointconfig.PointConfigConvert; +import cn.iocoder.yudao.module.point.service.pointconfig.PointConfigService; + +@Tag(name = "管理后台 - 积分设置") +@RestController +@RequestMapping("/point/config") +@Validated +public class PointConfigController { + + @Resource + private PointConfigService configService; + + @PostMapping("/create") + @Operation(summary = "创建积分设置") + @PreAuthorize("@ss.hasPermission('point:config:create')") + public CommonResult createConfig(@Valid @RequestBody PointConfigCreateReqVO createReqVO) { + return success(configService.createConfig(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新积分设置") + @PreAuthorize("@ss.hasPermission('point:config:update')") + public CommonResult updateConfig(@Valid @RequestBody PointConfigUpdateReqVO updateReqVO) { + configService.updateConfig(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除积分设置") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('point:config:delete')") + public CommonResult deleteConfig(@RequestParam("id") Integer id) { + configService.deleteConfig(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得积分设置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('point:config:query')") + public CommonResult getConfig(@RequestParam("id") Integer id) { + PointConfigDO config = configService.getConfig(id); + return success(PointConfigConvert.INSTANCE.convert(config)); + } + + @GetMapping("/list") + @Operation(summary = "获得积分设置列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('point:config:query')") + public CommonResult> getConfigList(@RequestParam("ids") Collection ids) { + List list = configService.getConfigList(ids); + return success(PointConfigConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得积分设置分页") + @PreAuthorize("@ss.hasPermission('point:config:query')") + public CommonResult> getConfigPage(@Valid PointConfigPageReqVO pageVO) { + PageResult pageResult = configService.getConfigPage(pageVO); + return success(PointConfigConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出积分设置 Excel") + @PreAuthorize("@ss.hasPermission('point:config:export')") + @OperateLog(type = EXPORT) + public void exportConfigExcel(@Valid PointConfigExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = configService.getConfigList(exportReqVO); + // 导出 Excel + List datas = PointConfigConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "积分设置.xls", "数据", PointConfigExcelVO.class, datas); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java new file mode 100644 index 000000000..d1e900cc2 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import javax.validation.constraints.*; + +/** + * 积分设置 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class PointConfigBaseVO { + + @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") + private Integer tradeDeductEnable; + + @Schema(description = "积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元)", example = "13506") + private BigDecimal tradeDeductUnitPrice; + + @Schema(description = "积分抵扣最大值", example = "32428") + private Long tradeDeductMaxPrice; + + @Schema(description = "1元赠送多少分") + private Long tradeGivePoint; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java new file mode 100644 index 000000000..4284f5e34 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 积分设置创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointConfigCreateReqVO extends PointConfigBaseVO { + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java new file mode 100644 index 000000000..0d01c7a5c --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + + +/** + * 积分设置 Excel VO + * + * @author QingX + */ +@Data +public class PointConfigExcelVO { + + @ExcelProperty("自增主键") + private Integer id; + + @ExcelProperty(value = "1 开启积分抵扣 0 关闭积分抵扣", converter = DictConvert.class) + @DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 + private Integer tradeDeductEnable; + + @ExcelProperty("积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元)") + private BigDecimal tradeDeductUnitPrice; + + @ExcelProperty("积分抵扣最大值") + private Long tradeDeductMaxPrice; + + @ExcelProperty("1元赠送多少分") + private Long tradeGivePoint; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @ExcelProperty("变更时间") + private LocalDateTime updateTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java new file mode 100644 index 000000000..bcc712d29 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 积分设置 Excel 导出 Request VO,参数和 PointConfigPageReqVO 是一致的") +@Data +public class PointConfigExportReqVO { + + @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") + private Integer tradeDeductEnable; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java new file mode 100644 index 000000000..cc994837c --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 积分设置分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointConfigPageReqVO extends PageParam { + + @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") + private Integer tradeDeductEnable; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java new file mode 100644 index 000000000..a8efe57b4 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 积分设置 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointConfigRespVO extends PointConfigBaseVO { + + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20937") + private Integer id; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "变更时间") + private LocalDateTime updateTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java new file mode 100644 index 000000000..9b50f259d --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 积分设置更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointConfigUpdateReqVO extends PointConfigBaseVO { + + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20937") + @NotNull(message = "自增主键不能为空") + private Integer id; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/PointRecordController.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/PointRecordController.java new file mode 100644 index 000000000..14c115a35 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/PointRecordController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; +import cn.iocoder.yudao.module.point.convert.pointrecord.PointRecordConvert; +import cn.iocoder.yudao.module.point.service.pointrecord.PointRecordService; + +@Tag(name = "管理后台 - 用户积分记录") +@RestController +@RequestMapping("/point/record") +@Validated +public class PointRecordController { + + @Resource + private PointRecordService recordService; + + @PostMapping("/create") + @Operation(summary = "创建用户积分记录") + @PreAuthorize("@ss.hasPermission('point:record:create')") + public CommonResult createRecord(@Valid @RequestBody PointRecordCreateReqVO createReqVO) { + return success(recordService.createRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新用户积分记录") + @PreAuthorize("@ss.hasPermission('point:record:update')") + public CommonResult updateRecord(@Valid @RequestBody PointRecordUpdateReqVO updateReqVO) { + recordService.updateRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除用户积分记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('point:record:delete')") + public CommonResult deleteRecord(@RequestParam("id") Long id) { + recordService.deleteRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得用户积分记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('point:record:query')") + public CommonResult getRecord(@RequestParam("id") Long id) { + PointRecordDO record = recordService.getRecord(id); + return success(PointRecordConvert.INSTANCE.convert(record)); + } + + @GetMapping("/list") + @Operation(summary = "获得用户积分记录列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('point:record:query')") + public CommonResult> getRecordList(@RequestParam("ids") Collection ids) { + List list = recordService.getRecordList(ids); + return success(PointRecordConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得用户积分记录分页") + @PreAuthorize("@ss.hasPermission('point:record:query')") + public CommonResult> getRecordPage(@Valid PointRecordPageReqVO pageVO) { + PageResult pageResult = recordService.getRecordPage(pageVO); + return success(PointRecordConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出用户积分记录 Excel") + @PreAuthorize("@ss.hasPermission('point:record:export')") + @OperateLog(type = EXPORT) + public void exportRecordExcel(@Valid PointRecordExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = recordService.getRecordList(exportReqVO); + // 导出 Excel + List datas = PointRecordConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "用户积分记录.xls", "数据", PointRecordExcelVO.class, datas); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordBaseVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordBaseVO.java new file mode 100644 index 000000000..0337aac8e --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordBaseVO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import javax.validation.constraints.*; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 用户积分记录 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class PointRecordBaseVO { + + @Schema(description = "业务编码", example = "22706") + @NotNull(message = "业务编码不能为空") + private String bizId; + + @Schema(description = "业务类型", example = "1") + @NotNull(message = "业务类型不能为空") + private String bizType; + + @Schema(description = "1增加 0扣减", example = "1") + @NotNull(message = "操作类型不能为空") + private String type; + + @Schema(description = "积分标题") + @NotNull(message = "积分标题不能为空") + private String title; + + @Schema(description = "积分描述", example = "你猜") + private String description; + + @Schema(description = "积分") + @NotNull(message = "操作积分不能为空") + private Integer point; + + @Schema(description = "变动后的积分", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotNull(message = "变动后的积分不能为空") + private Integer totalPoint; + + @Schema(description = "状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款) ", example = "1") + @NotNull(message = "积分状态不能为空") + private Integer status; + + @Schema(description = "用户id", example = "31169") + @NotNull(message = "用户ID不能为空") + private Integer userId; + + @Schema(description = "冻结时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @NotNull(message = "冻结时间不能为空") + private LocalDateTime freezingTime; + + @Schema(description = "解冻时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @NotNull(message = "解冻时间不能为空") + private LocalDateTime thawingTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordCreateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordCreateReqVO.java new file mode 100644 index 000000000..7062109d2 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 用户积分记录创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointRecordCreateReqVO extends PointRecordBaseVO { + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExcelVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExcelVO.java new file mode 100644 index 000000000..3db1573fc --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExcelVO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + + +/** + * 用户积分记录 Excel VO + * + * @author QingX + */ +@Data +public class PointRecordExcelVO { + + @ExcelProperty("自增主键") + private Long id; + + @ExcelProperty("业务编码") + private String bizId; + + @ExcelProperty(value = "业务类型", converter = DictConvert.class) + @DictFormat("biz_type") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 + private String bizType; + + @ExcelProperty("1增加 0扣减") + private String type; + + @ExcelProperty("积分标题") + private String title; + + @ExcelProperty("积分描述") + private String description; + + @ExcelProperty("积分") + private Integer point; + + @ExcelProperty("变动后的积分") + private Integer totalPoint; + + @ExcelProperty(value = "状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款) ", converter = DictConvert.class) + @DictFormat("point_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 + private Integer status; + + @ExcelProperty("用户id") + private Integer userId; + + @ExcelProperty("冻结时间") + private LocalDateTime freezingTime; + + @ExcelProperty("解冻时间") + private LocalDateTime thawingTime; + + @ExcelProperty("发生时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExportReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExportReqVO.java new file mode 100644 index 000000000..d57ade55a --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordExportReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 用户积分记录 Excel 导出 Request VO,参数和 PointRecordPageReqVO 是一致的") +@Data +public class PointRecordExportReqVO { + + @Schema(description = "业务编码", example = "22706") + private String bizId; + + @Schema(description = "业务类型", example = "1") + private String bizType; + + @Schema(description = "1增加 0扣减", example = "1") + private String type; + + @Schema(description = "积分标题") + private String title; + + @Schema(description = "状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款) ", example = "1") + private Integer status; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordPageReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordPageReqVO.java new file mode 100644 index 000000000..b4570c618 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordPageReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 用户积分记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointRecordPageReqVO extends PageParam { + + @Schema(description = "业务编码", example = "22706") + private String bizId; + + @Schema(description = "业务类型", example = "1") + private String bizType; + + @Schema(description = "1增加 0扣减", example = "1") + private String type; + + @Schema(description = "积分标题") + private String title; + + @Schema(description = "状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款) ", example = "1") + private Integer status; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordRespVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordRespVO.java new file mode 100644 index 000000000..d40dee6ee --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 用户积分记录 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointRecordRespVO extends PointRecordBaseVO { + + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "31457") + private Long id; + + @Schema(description = "发生时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordUpdateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordUpdateReqVO.java new file mode 100644 index 000000000..d053e0a0e --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointrecord/vo/PointRecordUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 用户积分记录更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PointRecordUpdateReqVO extends PointRecordBaseVO { + + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "31457") + @NotNull(message = "自增主键不能为空") + private Long id; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/SignInConfigController.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/SignInConfigController.java new file mode 100644 index 000000000..2ca25dd5a --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/SignInConfigController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; +import cn.iocoder.yudao.module.point.convert.signinconfig.SignInConfigConvert; +import cn.iocoder.yudao.module.point.service.signinconfig.SignInConfigService; + +@Tag(name = "管理后台 - 积分签到规则") +@RestController +@RequestMapping("/point/sign-in-config") +@Validated +public class SignInConfigController { + + @Resource + private SignInConfigService signInConfigService; + + @PostMapping("/create") + @Operation(summary = "创建积分签到规则") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:create')") + public CommonResult createSignInConfig(@Valid @RequestBody SignInConfigCreateReqVO createReqVO) { + return success(signInConfigService.createSignInConfig(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新积分签到规则") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:update')") + public CommonResult updateSignInConfig(@Valid @RequestBody SignInConfigUpdateReqVO updateReqVO) { + signInConfigService.updateSignInConfig(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除积分签到规则") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('point:sign-in-config:delete')") + public CommonResult deleteSignInConfig(@RequestParam("id") Integer id) { + signInConfigService.deleteSignInConfig(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得积分签到规则") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:query')") + public CommonResult getSignInConfig(@RequestParam("id") Integer id) { + SignInConfigDO signInConfig = signInConfigService.getSignInConfig(id); + return success(SignInConfigConvert.INSTANCE.convert(signInConfig)); + } + + @GetMapping("/list") + @Operation(summary = "获得积分签到规则列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:query')") + public CommonResult> getSignInConfigList(@RequestParam("ids") Collection ids) { + List list = signInConfigService.getSignInConfigList(ids); + return success(SignInConfigConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得积分签到规则分页") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:query')") + public CommonResult> getSignInConfigPage(@Valid SignInConfigPageReqVO pageVO) { + PageResult pageResult = signInConfigService.getSignInConfigPage(pageVO); + return success(SignInConfigConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出积分签到规则 Excel") + @PreAuthorize("@ss.hasPermission('point:sign-in-config:export')") + @OperateLog(type = EXPORT) + public void exportSignInConfigExcel(@Valid SignInConfigExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = signInConfigService.getSignInConfigList(exportReqVO); + // 导出 Excel + List datas = SignInConfigConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "积分签到规则.xls", "数据", SignInConfigExcelVO.class, datas); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigBaseVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigBaseVO.java new file mode 100644 index 000000000..4c2160dde --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigBaseVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import javax.validation.constraints.*; + +/** + * 积分签到规则 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class SignInConfigBaseVO { + + @Schema(description = "签到第x天", example = "7") + private Integer day; + + @Schema(description = "签到天数对应分数", example = "10") + private Integer point; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigCreateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigCreateReqVO.java new file mode 100644 index 000000000..39098c192 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 积分签到规则创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInConfigCreateReqVO extends SignInConfigBaseVO { + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExcelVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExcelVO.java new file mode 100644 index 000000000..8d066f2ae --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExcelVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; + +/** + * 积分签到规则 Excel VO + * + * @author QingX + */ +@Data +public class SignInConfigExcelVO { + + @ExcelProperty("签到第x天") + private Integer day; + + @ExcelProperty("签到天数对应分数") + private Integer point; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExportReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExportReqVO.java new file mode 100644 index 000000000..473fe1153 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigExportReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 积分签到规则 Excel 导出 Request VO,参数和 SignInConfigPageReqVO 是一致的") +@Data +public class SignInConfigExportReqVO { + + @Schema(description = "签到第x天", example = "7") + private Integer day; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigPageReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigPageReqVO.java new file mode 100644 index 000000000..892d1f2e8 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigPageReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +@Schema(description = "管理后台 - 积分签到规则分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInConfigPageReqVO extends PageParam { + + @Schema(description = "签到第x天", example = "7") + private Integer day; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigRespVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigRespVO.java new file mode 100644 index 000000000..a78816c3f --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 积分签到规则 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInConfigRespVO extends SignInConfigBaseVO { + + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20937") + private Integer id; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigUpdateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigUpdateReqVO.java new file mode 100644 index 000000000..cf6c788e1 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinconfig/vo/SignInConfigUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 积分签到规则更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInConfigUpdateReqVO extends SignInConfigBaseVO { + + @Schema(description = "规则自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "13653") + @NotNull(message = "规则自增主键不能为空") + private Integer id; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/SignInRecordController.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/SignInRecordController.java new file mode 100644 index 000000000..a2a639c5d --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/SignInRecordController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; +import cn.iocoder.yudao.module.point.convert.signinrecord.SignInRecordConvert; +import cn.iocoder.yudao.module.point.service.signinrecord.SignInRecordService; + +@Tag(name = "管理后台 - 用户签到积分") +@RestController +@RequestMapping("/point/sign-in-record") +@Validated +public class SignInRecordController { + + @Resource + private SignInRecordService signInRecordService; + + @PostMapping("/create") + @Operation(summary = "创建用户签到积分") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:create')") + public CommonResult createSignInRecord(@Valid @RequestBody SignInRecordCreateReqVO createReqVO) { + return success(signInRecordService.createSignInRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新用户签到积分") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:update')") + public CommonResult updateSignInRecord(@Valid @RequestBody SignInRecordUpdateReqVO updateReqVO) { + signInRecordService.updateSignInRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除用户签到积分") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('point:sign-in-record:delete')") + public CommonResult deleteSignInRecord(@RequestParam("id") Long id) { + signInRecordService.deleteSignInRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得用户签到积分") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:query')") + public CommonResult getSignInRecord(@RequestParam("id") Long id) { + SignInRecordDO signInRecord = signInRecordService.getSignInRecord(id); + return success(SignInRecordConvert.INSTANCE.convert(signInRecord)); + } + + @GetMapping("/list") + @Operation(summary = "获得用户签到积分列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:query')") + public CommonResult> getSignInRecordList(@RequestParam("ids") Collection ids) { + List list = signInRecordService.getSignInRecordList(ids); + return success(SignInRecordConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得用户签到积分分页") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:query')") + public CommonResult> getSignInRecordPage(@Valid SignInRecordPageReqVO pageVO) { + PageResult pageResult = signInRecordService.getSignInRecordPage(pageVO); + return success(SignInRecordConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出用户签到积分 Excel") + @PreAuthorize("@ss.hasPermission('point:sign-in-record:export')") + @OperateLog(type = EXPORT) + public void exportSignInRecordExcel(@Valid SignInRecordExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = signInRecordService.getSignInRecordList(exportReqVO); + // 导出 Excel + List datas = SignInRecordConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "用户签到积分.xls", "数据", SignInRecordExcelVO.class, datas); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordBaseVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordBaseVO.java new file mode 100644 index 000000000..9cefa4a18 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordBaseVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import javax.validation.constraints.*; + +/** + * 用户签到积分 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class SignInRecordBaseVO { + + @Schema(description = "签到用户", example = "6507") + private Integer userId; + + @Schema(description = "第几天签到") + private Integer day; + + @Schema(description = "签到的分数") + private Integer point; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordCreateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordCreateReqVO.java new file mode 100644 index 000000000..9635b3076 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 用户签到积分创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInRecordCreateReqVO extends SignInRecordBaseVO { + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExcelVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExcelVO.java new file mode 100644 index 000000000..de9ebf605 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExcelVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; + +/** + * 用户签到积分 Excel VO + * + * @author 芋道源码 + */ +@Data +public class SignInRecordExcelVO { + + @ExcelProperty("签到自增id") + private Long id; + + @ExcelProperty("签到用户") + private Integer userId; + + @ExcelProperty("第几天签到") + private Integer day; + + @ExcelProperty("签到的分数") + private Integer point; + + @ExcelProperty("签到时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExportReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExportReqVO.java new file mode 100644 index 000000000..673042306 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordExportReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import java.time.LocalDateTime; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 用户签到积分 Excel 导出 Request VO,参数和 SignInRecordPageReqVO 是一致的") +@Data +public class SignInRecordExportReqVO { + + @Schema(description = "签到用户", example = "6507") + private Integer userId; + + @Schema(description = "第几天签到") + private Integer day; + + @Schema(description = "签到时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordPageReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordPageReqVO.java new file mode 100644 index 000000000..49218aafa --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordPageReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 用户签到积分分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInRecordPageReqVO extends PageParam { + + @Schema(description = "签到用户", example = "6507") + private Integer userId; + + @Schema(description = "第几天签到") + private Integer day; + + @Schema(description = "签到时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordRespVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordRespVO.java new file mode 100644 index 000000000..d4180d1b1 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 用户签到积分 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInRecordRespVO extends SignInRecordBaseVO { + + @Schema(description = "签到自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11903") + private Long id; + + @Schema(description = "签到时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordUpdateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordUpdateReqVO.java new file mode 100644 index 000000000..81392d088 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/signinrecord/vo/SignInRecordUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 用户签到积分更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SignInRecordUpdateReqVO extends SignInRecordBaseVO { + + @Schema(description = "签到自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11903") + @NotNull(message = "签到自增id不能为空") + private Long id; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java new file mode 100644 index 000000000..56b96cf75 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.point.convert.pointconfig; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; + +/** + * 积分设置 Convert + * + * @author QingX + */ +@Mapper +public interface PointConfigConvert { + + PointConfigConvert INSTANCE = Mappers.getMapper(PointConfigConvert.class); + + PointConfigDO convert(PointConfigCreateReqVO bean); + + PointConfigDO convert(PointConfigUpdateReqVO bean); + + PointConfigRespVO convert(PointConfigDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointrecord/PointRecordConvert.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointrecord/PointRecordConvert.java new file mode 100644 index 000000000..556c154f8 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointrecord/PointRecordConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.point.convert.pointrecord; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; + +/** + * 用户积分记录 Convert + * + * @author QingX + */ +@Mapper +public interface PointRecordConvert { + + PointRecordConvert INSTANCE = Mappers.getMapper(PointRecordConvert.class); + + PointRecordDO convert(PointRecordCreateReqVO bean); + + PointRecordDO convert(PointRecordUpdateReqVO bean); + + PointRecordRespVO convert(PointRecordDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinconfig/SignInConfigConvert.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinconfig/SignInConfigConvert.java new file mode 100644 index 000000000..a602fd399 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinconfig/SignInConfigConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.point.convert.signinconfig; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; + +/** + * 积分签到规则 Convert + * + * @author QingX + */ +@Mapper +public interface SignInConfigConvert { + + SignInConfigConvert INSTANCE = Mappers.getMapper(SignInConfigConvert.class); + + SignInConfigDO convert(SignInConfigCreateReqVO bean); + + SignInConfigDO convert(SignInConfigUpdateReqVO bean); + + SignInConfigRespVO convert(SignInConfigDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinrecord/SignInRecordConvert.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinrecord/SignInRecordConvert.java new file mode 100644 index 000000000..6c3b434cb --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/signinrecord/SignInRecordConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.point.convert.signinrecord; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; + +/** + * 用户签到积分 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface SignInRecordConvert { + + SignInRecordConvert INSTANCE = Mappers.getMapper(SignInRecordConvert.class); + + SignInRecordDO convert(SignInRecordCreateReqVO bean); + + SignInRecordDO convert(SignInRecordUpdateReqVO bean); + + SignInRecordRespVO convert(SignInRecordDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java new file mode 100644 index 000000000..ee30a27d1 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.point.dal.dataobject.pointconfig; + +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 积分设置 DO + * + * @author QingX + */ +@TableName("member_point_config") +@KeySequence("member_point_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PointConfigDO extends BaseDO { + + /** + * 自增主键 + */ + @TableId + private Integer id; + /** + * 1 开启积分抵扣 +0 关闭积分抵扣 + * + * 枚举 {@link TODO infra_boolean_string 对应的类} + */ + private Integer tradeDeductEnable; + /** + * 积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元) + */ + private BigDecimal tradeDeductUnitPrice; + /** + * 积分抵扣最大值 + */ + private Long tradeDeductMaxPrice; + /** + * 1元赠送多少分 + */ + private Long tradeGivePoint; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointrecord/PointRecordDO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointrecord/PointRecordDO.java new file mode 100644 index 000000000..74197e70d --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointrecord/PointRecordDO.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.point.dal.dataobject.pointrecord; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 用户积分记录 DO + * + * @author QingX + */ +@TableName("member_point_record") +@KeySequence("member_point_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PointRecordDO extends BaseDO { + + /** + * 自增主键 + */ + @TableId + private Long id; + /** + * 业务编码 + */ + private String bizId; + /** + * 业务类型 + * + * 枚举 {@link TODO biz_type 对应的类} + */ + private String bizType; + /** + * 1增加 0扣减 + */ + private String type; + /** + * 积分标题 + */ + private String title; + /** + * 积分描述 + */ + private String description; + /** + * 积分 + */ + private Integer point; + /** + * 变动后的积分 + */ + private Integer totalPoint; + /** + * 状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款) + + * + * 枚举 {@link TODO point_status 对应的类} + */ + private Integer status; + /** + * 用户id + */ + private Integer userId; + /** + * 冻结时间 + */ + private LocalDateTime freezingTime; + /** + * 解冻时间 + */ + private LocalDateTime thawingTime; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinconfig/SignInConfigDO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinconfig/SignInConfigDO.java new file mode 100644 index 000000000..9eb07c929 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinconfig/SignInConfigDO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.point.dal.dataobject.signinconfig; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 积分签到规则 DO + * + * @author QingX + */ +@TableName("member_sign_in_config") +@KeySequence("member_sign_in_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SignInConfigDO extends BaseDO { + + /** + * 规则自增主键 + */ + @TableId + private Integer id; + /** + * 签到第x天 + */ + private Integer day; + /** + * 签到天数对应分数 + */ + private Integer point; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinrecord/SignInRecordDO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinrecord/SignInRecordDO.java new file mode 100644 index 000000000..d75a852d3 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/signinrecord/SignInRecordDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.point.dal.dataobject.signinrecord; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 用户签到积分 DO + * + * @author 芋道源码 + */ +@TableName("member_sign_in_record") +@KeySequence("member_sign_in_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SignInRecordDO extends BaseDO { + + /** + * 签到自增id + */ + @TableId + private Long id; + /** + * 签到用户 + */ + private Integer userId; + /** + * 第几天签到 + */ + private Integer day; + /** + * 签到的分数 + */ + private Integer point; + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java new file mode 100644 index 000000000..5d11f9b5b --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.point.dal.mysql.pointconfig; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; + +/** + * 积分设置 Mapper + * + * @author QingX + */ +@Mapper +public interface PointConfigMapper extends BaseMapperX { + + default PageResult selectPage(PointConfigPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(PointConfigDO::getTradeDeductEnable, reqVO.getTradeDeductEnable()) + .orderByDesc(PointConfigDO::getId)); + } + + default List selectList(PointConfigExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(PointConfigDO::getTradeDeductEnable, reqVO.getTradeDeductEnable()) + .orderByDesc(PointConfigDO::getId)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointrecord/PointRecordMapper.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointrecord/PointRecordMapper.java new file mode 100644 index 000000000..005056a30 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointrecord/PointRecordMapper.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.point.dal.mysql.pointrecord; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; + +/** + * 用户积分记录 Mapper + * + * @author QingX + */ +@Mapper +public interface PointRecordMapper extends BaseMapperX { + + default PageResult selectPage(PointRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(PointRecordDO::getBizId, reqVO.getBizId()) + .eqIfPresent(PointRecordDO::getBizType, reqVO.getBizType()) + .eqIfPresent(PointRecordDO::getType, reqVO.getType()) + .eqIfPresent(PointRecordDO::getTitle, reqVO.getTitle()) + .eqIfPresent(PointRecordDO::getStatus, reqVO.getStatus()) + .orderByDesc(PointRecordDO::getId)); + } + + default List selectList(PointRecordExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(PointRecordDO::getBizId, reqVO.getBizId()) + .eqIfPresent(PointRecordDO::getBizType, reqVO.getBizType()) + .eqIfPresent(PointRecordDO::getType, reqVO.getType()) + .eqIfPresent(PointRecordDO::getTitle, reqVO.getTitle()) + .eqIfPresent(PointRecordDO::getStatus, reqVO.getStatus()) + .orderByDesc(PointRecordDO::getId)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinconfig/SignInConfigMapper.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinconfig/SignInConfigMapper.java new file mode 100644 index 000000000..6188d3fef --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinconfig/SignInConfigMapper.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.point.dal.mysql.signinconfig; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; + +/** + * 积分签到规则 Mapper + * + * @author QingX + */ +@Mapper +public interface SignInConfigMapper extends BaseMapperX { + + default PageResult selectPage(SignInConfigPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(SignInConfigDO::getDay, reqVO.getDay()) + .orderByAsc(SignInConfigDO::getDay)); + } + + default List selectList(SignInConfigExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(SignInConfigDO::getDay, reqVO.getDay()) + .orderByDesc(SignInConfigDO::getId)); + } + + // + default long selectSameDayNotSelf(SignInConfigUpdateReqVO reqVO){ + return selectCount(new LambdaQueryWrapperX () + .ne(SignInConfigDO::getId, reqVO.getId()) + .eq(SignInConfigDO::getDay,reqVO.getDay()) + ); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinrecord/SignInRecordMapper.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinrecord/SignInRecordMapper.java new file mode 100644 index 000000000..9d0c1c6eb --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/signinrecord/SignInRecordMapper.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.point.dal.mysql.signinrecord; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; + +/** + * 用户签到积分 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface SignInRecordMapper extends BaseMapperX { + + default PageResult selectPage(SignInRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(SignInRecordDO::getUserId, reqVO.getUserId()) + .eqIfPresent(SignInRecordDO::getDay, reqVO.getDay()) + .betweenIfPresent(SignInRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(SignInRecordDO::getId)); + } + + default List selectList(SignInRecordExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(SignInRecordDO::getUserId, reqVO.getUserId()) + .eqIfPresent(SignInRecordDO::getDay, reqVO.getDay()) + .betweenIfPresent(SignInRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(SignInRecordDO::getId)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java new file mode 100644 index 000000000..d579b7b9d --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.point.service.pointconfig; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 积分设置 Service 接口 + * + * @author QingX + */ +public interface PointConfigService { + + /** + * 创建积分设置 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Integer createConfig(@Valid PointConfigCreateReqVO createReqVO); + + /** + * 更新积分设置 + * + * @param updateReqVO 更新信息 + */ + void updateConfig(@Valid PointConfigUpdateReqVO updateReqVO); + + /** + * 删除积分设置 + * + * @param id 编号 + */ + void deleteConfig(Integer id); + + /** + * 获得积分设置 + * + * @param id 编号 + * @return 积分设置 + */ + PointConfigDO getConfig(Integer id); + + /** + * 获得积分设置列表 + * + * @param ids 编号 + * @return 积分设置列表 + */ + List getConfigList(Collection ids); + + /** + * 获得积分设置分页 + * + * @param pageReqVO 分页查询 + * @return 积分设置分页 + */ + PageResult getConfigPage(PointConfigPageReqVO pageReqVO); + + /** + * 获得积分设置列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 积分设置列表 + */ + List getConfigList(PointConfigExportReqVO exportReqVO); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java new file mode 100644 index 000000000..5cc8185d8 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java @@ -0,0 +1,92 @@ +package cn.iocoder.yudao.module.point.service.pointconfig; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.point.convert.pointconfig.PointConfigConvert; +import cn.iocoder.yudao.module.point.dal.mysql.pointconfig.PointConfigMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; + +/** + * 积分设置 Service 实现类 + * + * @author QingX + */ +@Service +@Validated +public class PointConfigServiceImpl implements PointConfigService { + + @Autowired + private PointConfigMapper configMapper; + + @Override + public Integer createConfig(PointConfigCreateReqVO createReqVO) { + // 插入 + PointConfigDO config = PointConfigConvert.INSTANCE.convert(createReqVO); + //每个租户只允许存在一条记录 + validateConfigExistsOne(); + + configMapper.insert(config); + // 返回 + return config.getId(); + } + + @Override + public void updateConfig(PointConfigUpdateReqVO updateReqVO) { + // 校验存在 + validateConfigExists(updateReqVO.getId()); + // 更新 + PointConfigDO updateObj = PointConfigConvert.INSTANCE.convert(updateReqVO); + configMapper.updateById(updateObj); + } + + @Override + public void deleteConfig(Integer id) { + // 校验存在 + validateConfigExists(id); + // 删除 + configMapper.deleteById(id); + } + + private void validateConfigExists(Integer id) { + if (configMapper.selectById(id) == null) { + throw exception(CONFIG_NOT_EXISTS); + } + } + + private void validateConfigExistsOne() { + if (configMapper.selectCount() > 0) { + throw exception(CONFIG_EXISTS); + } + } + + @Override + public PointConfigDO getConfig(Integer id) { + return configMapper.selectById(id); + } + + @Override + public List getConfigList(Collection ids) { + return configMapper.selectBatchIds(ids); + } + + @Override + public PageResult getConfigPage(PointConfigPageReqVO pageReqVO) { + return configMapper.selectPage(pageReqVO); + } + + @Override + public List getConfigList(PointConfigExportReqVO exportReqVO) { + return configMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordService.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordService.java new file mode 100644 index 000000000..99833ff8d --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.point.service.pointrecord; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 用户积分记录 Service 接口 + * + * @author QingX + */ +public interface PointRecordService { + + /** + * 创建用户积分记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRecord(@Valid PointRecordCreateReqVO createReqVO); + + /** + * 更新用户积分记录 + * + * @param updateReqVO 更新信息 + */ + void updateRecord(@Valid PointRecordUpdateReqVO updateReqVO); + + /** + * 删除用户积分记录 + * + * @param id 编号 + */ + void deleteRecord(Long id); + + /** + * 获得用户积分记录 + * + * @param id 编号 + * @return 用户积分记录 + */ + PointRecordDO getRecord(Long id); + + /** + * 获得用户积分记录列表 + * + * @param ids 编号 + * @return 用户积分记录列表 + */ + List getRecordList(Collection ids); + + /** + * 获得用户积分记录分页 + * + * @param pageReqVO 分页查询 + * @return 用户积分记录分页 + */ + PageResult getRecordPage(PointRecordPageReqVO pageReqVO); + + /** + * 获得用户积分记录列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 用户积分记录列表 + */ + List getRecordList(PointRecordExportReqVO exportReqVO); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImpl.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImpl.java new file mode 100644 index 000000000..a2c0d1ab9 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.point.service.pointrecord; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.point.convert.pointrecord.PointRecordConvert; +import cn.iocoder.yudao.module.point.dal.mysql.pointrecord.PointRecordMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; + +/** + * 用户积分记录 Service 实现类 + * + * @author QingX + */ +@Service +@Validated +public class PointRecordServiceImpl implements PointRecordService { + + @Resource + private PointRecordMapper recordMapper; + + @Override + public Long createRecord(PointRecordCreateReqVO createReqVO) { + // 插入 + PointRecordDO record = PointRecordConvert.INSTANCE.convert(createReqVO); + recordMapper.insert(record); + // 返回 + return record.getId(); + } + + @Override + public void updateRecord(PointRecordUpdateReqVO updateReqVO) { + // 校验存在 + validateRecordExists(updateReqVO.getId()); + // 更新 + PointRecordDO updateObj = PointRecordConvert.INSTANCE.convert(updateReqVO); + recordMapper.updateById(updateObj); + } + + @Override + public void deleteRecord(Long id) { + // 校验存在 + validateRecordExists(id); + // 删除 + recordMapper.deleteById(id); + } + + private void validateRecordExists(Long id) { + if (recordMapper.selectById(id) == null) { + throw exception(RECORD_NOT_EXISTS); + } + } + + @Override + public PointRecordDO getRecord(Long id) { + return recordMapper.selectById(id); + } + + @Override + public List getRecordList(Collection ids) { + return recordMapper.selectBatchIds(ids); + } + + @Override + public PageResult getRecordPage(PointRecordPageReqVO pageReqVO) { + return recordMapper.selectPage(pageReqVO); + } + + @Override + public List getRecordList(PointRecordExportReqVO exportReqVO) { + return recordMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigService.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigService.java new file mode 100644 index 000000000..486f08f49 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.point.service.signinconfig; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 积分签到规则 Service 接口 + * + * @author QingX + */ +public interface SignInConfigService { + + /** + * 创建积分签到规则 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Integer createSignInConfig(@Valid SignInConfigCreateReqVO createReqVO); + + /** + * 更新积分签到规则 + * + * @param updateReqVO 更新信息 + */ + void updateSignInConfig(@Valid SignInConfigUpdateReqVO updateReqVO); + + /** + * 删除积分签到规则 + * + * @param id 编号 + */ + void deleteSignInConfig(Integer id); + + /** + * 获得积分签到规则 + * + * @param id 编号 + * @return 积分签到规则 + */ + SignInConfigDO getSignInConfig(Integer id); + + /** + * 获得积分签到规则列表 + * + * @param ids 编号 + * @return 积分签到规则列表 + */ + List getSignInConfigList(Collection ids); + + /** + * 获得积分签到规则分页 + * + * @param pageReqVO 分页查询 + * @return 积分签到规则分页 + */ + PageResult getSignInConfigPage(SignInConfigPageReqVO pageReqVO); + + /** + * 获得积分签到规则列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 积分签到规则列表 + */ + List getSignInConfigList(SignInConfigExportReqVO exportReqVO); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImpl.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImpl.java new file mode 100644 index 000000000..ac4947ddc --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImpl.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.point.service.signinconfig; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.point.convert.signinconfig.SignInConfigConvert; +import cn.iocoder.yudao.module.point.dal.mysql.signinconfig.SignInConfigMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; + +/** + * 积分签到规则 Service 实现类 + * + * @author QingX + */ +@Service +@Validated +public class SignInConfigServiceImpl implements SignInConfigService { + + @Resource + private SignInConfigMapper signInConfigMapper; + + @Override + public Integer createSignInConfig(SignInConfigCreateReqVO createReqVO) { + // 插入 + SignInConfigDO signInConfig = SignInConfigConvert.INSTANCE.convert(createReqVO); + //判断是否重复插入签到天数 + validateSignInConfigExistsDay(signInConfig.getDay()); + signInConfigMapper.insert(signInConfig); + // 返回 + return signInConfig.getId(); + } + + @Override + public void updateSignInConfig(SignInConfigUpdateReqVO updateReqVO) { + // 校验存在 + validateSignInConfigExists(updateReqVO.getId()); + //判断是否重复插入签到天数 + validateSignInConfigSameDayNotSelf(updateReqVO); + // 判断更新的 + SignInConfigDO updateObj = SignInConfigConvert.INSTANCE.convert(updateReqVO); + + + signInConfigMapper.updateById(updateObj); + } + + @Override + public void deleteSignInConfig(Integer id) { + // 校验存在 + validateSignInConfigExists(id); + // 删除 + signInConfigMapper.deleteById(id); + } + + private void validateSignInConfigExists(Integer id) { + if (signInConfigMapper.selectById(id) == null) { + throw exception(SIGN_IN_CONFIG_NOT_EXISTS); + } + } + //根据签到天数判断是否存在一个相同的天数 + private void validateSignInConfigExistsDay(Integer day) { + if (signInConfigMapper.selectCount(SignInConfigDO::getDay,day)>0) { + throw exception(SIGN_IN_CONFIG_EXISTS); + } + } + + //更新天数时判断是否有重复的天数,需要去除自己 + private void validateSignInConfigSameDayNotSelf(SignInConfigUpdateReqVO reqVO) { + if (signInConfigMapper.selectSameDayNotSelf(reqVO)>0) { + throw exception(SIGN_IN_CONFIG_EXISTS); + } + } + + + @Override + public SignInConfigDO getSignInConfig(Integer id) { + return signInConfigMapper.selectById(id); + } + + @Override + public List getSignInConfigList(Collection ids) { + return signInConfigMapper.selectBatchIds(ids); + } + + @Override + public PageResult getSignInConfigPage(SignInConfigPageReqVO pageReqVO) { + return signInConfigMapper.selectPage(pageReqVO); + } + + @Override + public List getSignInConfigList(SignInConfigExportReqVO exportReqVO) { + return signInConfigMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordService.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordService.java new file mode 100644 index 000000000..8910eec7f --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.point.service.signinrecord; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 用户签到积分 Service 接口 + * + * @author 芋道源码 + */ +public interface SignInRecordService { + + /** + * 创建用户签到积分 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createSignInRecord(@Valid SignInRecordCreateReqVO createReqVO); + + /** + * 更新用户签到积分 + * + * @param updateReqVO 更新信息 + */ + void updateSignInRecord(@Valid SignInRecordUpdateReqVO updateReqVO); + + /** + * 删除用户签到积分 + * + * @param id 编号 + */ + void deleteSignInRecord(Long id); + + /** + * 获得用户签到积分 + * + * @param id 编号 + * @return 用户签到积分 + */ + SignInRecordDO getSignInRecord(Long id); + + /** + * 获得用户签到积分列表 + * + * @param ids 编号 + * @return 用户签到积分列表 + */ + List getSignInRecordList(Collection ids); + + /** + * 获得用户签到积分分页 + * + * @param pageReqVO 分页查询 + * @return 用户签到积分分页 + */ + PageResult getSignInRecordPage(SignInRecordPageReqVO pageReqVO); + + /** + * 获得用户签到积分列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 用户签到积分列表 + */ + List getSignInRecordList(SignInRecordExportReqVO exportReqVO); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImpl.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImpl.java new file mode 100644 index 000000000..00ff4967e --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.point.service.signinrecord; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.point.convert.signinrecord.SignInRecordConvert; +import cn.iocoder.yudao.module.point.dal.mysql.signinrecord.SignInRecordMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; + +/** + * 用户签到积分 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class SignInRecordServiceImpl implements SignInRecordService { + + @Resource + private SignInRecordMapper signInRecordMapper; + + @Override + public Long createSignInRecord(SignInRecordCreateReqVO createReqVO) { + // 插入 + SignInRecordDO signInRecord = SignInRecordConvert.INSTANCE.convert(createReqVO); + signInRecordMapper.insert(signInRecord); + // 返回 + return signInRecord.getId(); + } + + @Override + public void updateSignInRecord(SignInRecordUpdateReqVO updateReqVO) { + // 校验存在 + validateSignInRecordExists(updateReqVO.getId()); + // 更新 + SignInRecordDO updateObj = SignInRecordConvert.INSTANCE.convert(updateReqVO); + signInRecordMapper.updateById(updateObj); + } + + @Override + public void deleteSignInRecord(Long id) { + // 校验存在 + validateSignInRecordExists(id); + // 删除 + signInRecordMapper.deleteById(id); + } + + private void validateSignInRecordExists(Long id) { + if (signInRecordMapper.selectById(id) == null) { + throw exception(SIGN_IN_RECORD_NOT_EXISTS); + } + } + + @Override + public SignInRecordDO getSignInRecord(Long id) { + return signInRecordMapper.selectById(id); + } + + @Override + public List getSignInRecordList(Collection ids) { + return signInRecordMapper.selectBatchIds(ids); + } + + @Override + public PageResult getSignInRecordPage(SignInRecordPageReqVO pageReqVO) { + return signInRecordMapper.selectPage(pageReqVO); + } + + @Override + public List getSignInRecordList(SignInRecordExportReqVO exportReqVO) { + return signInRecordMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml new file mode 100644 index 000000000..963afd6c8 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml new file mode 100644 index 000000000..cc09cce4b --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml new file mode 100644 index 000000000..2e665c01a --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml new file mode 100644 index 000000000..bd9d58976 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImplTest.java b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImplTest.java new file mode 100644 index 000000000..d012d03fe --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImplTest.java @@ -0,0 +1,152 @@ +package cn.iocoder.yudao.module.point.service.pointconfig; + +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; +import cn.iocoder.yudao.module.point.dal.mysql.pointconfig.PointConfigMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link PointConfigServiceImpl} 的单元测试类 + * + * @author QingX + */ +@Import(PointConfigServiceImpl.class) +public class PointConfigServiceImplTest extends BaseDbUnitTest { + + @Resource + private PointConfigServiceImpl configService; + + @Resource + private PointConfigMapper configMapper; + + @Test + public void testCreateConfig_success() { + // 准备参数 + PointConfigCreateReqVO reqVO = randomPojo(PointConfigCreateReqVO.class); + + // 调用 + Integer configId = configService.createConfig(reqVO); + // 断言 + assertNotNull(configId); + // 校验记录的属性是否正确 + PointConfigDO config = configMapper.selectById(configId); + assertPojoEquals(reqVO, config); + } + + @Test + public void testUpdateConfig_success() { + // mock 数据 + PointConfigDO dbConfig = randomPojo(PointConfigDO.class); + configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PointConfigUpdateReqVO reqVO = randomPojo(PointConfigUpdateReqVO.class, o -> { + o.setId(dbConfig.getId()); // 设置更新的 ID + }); + + // 调用 + configService.updateConfig(reqVO); + // 校验是否更新正确 + PointConfigDO config = configMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, config); + } + + @Test + public void testUpdateConfig_notExists() { + // 准备参数 + PointConfigUpdateReqVO reqVO = randomPojo(PointConfigUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> configService.updateConfig(reqVO), CONFIG_NOT_EXISTS); + } + + @Test + public void testDeleteConfig_success() { + // mock 数据 + PointConfigDO dbConfig = randomPojo(PointConfigDO.class); + configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Integer id = dbConfig.getId(); + + // 调用 + configService.deleteConfig(id); + // 校验数据不存在了 + assertNull(configMapper.selectById(id)); + } + + @Test + public void testDeleteConfig_notExists() { + // 准备参数 + Integer id = RandomUtils.randomInteger(); + + // 调用, 并断言异常 + assertServiceException(() -> configService.deleteConfig(id), CONFIG_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetConfigPage() { + // mock 数据 + PointConfigDO dbConfig = randomPojo(PointConfigDO.class, o -> { // 等会查询到 + o.setTradeDeductEnable(null); + }); + configMapper.insert(dbConfig); + // 测试 tradeDeductEnable 不匹配 + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setTradeDeductEnable(null))); + // 准备参数 + PointConfigPageReqVO reqVO = new PointConfigPageReqVO(); + reqVO.setTradeDeductEnable(null); + + // 调用 + PageResult pageResult = configService.getConfigPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbConfig, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetConfigList() { + // mock 数据 + PointConfigDO dbConfig = randomPojo(PointConfigDO.class, o -> { // 等会查询到 + o.setTradeDeductEnable(null); + }); + configMapper.insert(dbConfig); + // 测试 tradeDeductEnable 不匹配 + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setTradeDeductEnable(null))); + // 准备参数 + PointConfigExportReqVO reqVO = new PointConfigExportReqVO(); + reqVO.setTradeDeductEnable(null); + + // 调用 + List list = configService.getConfigList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbConfig, list.get(0)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImplTest.java b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImplTest.java new file mode 100644 index 000000000..32a7740f0 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/pointrecord/PointRecordServiceImplTest.java @@ -0,0 +1,183 @@ +package cn.iocoder.yudao.module.point.service.pointrecord; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.point.controller.admin.pointrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.pointrecord.PointRecordDO; +import cn.iocoder.yudao.module.point.dal.mysql.pointrecord.PointRecordMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link PointRecordServiceImpl} 的单元测试类 + * + * @author QingX + */ +@Import(PointRecordServiceImpl.class) +public class PointRecordServiceImplTest extends BaseDbUnitTest { + + @Resource + private PointRecordServiceImpl recordService; + + @Resource + private PointRecordMapper recordMapper; + + @Test + public void testCreateRecord_success() { + // 准备参数 + PointRecordCreateReqVO reqVO = randomPojo(PointRecordCreateReqVO.class); + + // 调用 + Long recordId = recordService.createRecord(reqVO); + // 断言 + assertNotNull(recordId); + // 校验记录的属性是否正确 + PointRecordDO record = recordMapper.selectById(recordId); + assertPojoEquals(reqVO, record); + } + + @Test + public void testUpdateRecord_success() { + // mock 数据 + PointRecordDO dbRecord = randomPojo(PointRecordDO.class); + recordMapper.insert(dbRecord);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PointRecordUpdateReqVO reqVO = randomPojo(PointRecordUpdateReqVO.class, o -> { + o.setId(dbRecord.getId()); // 设置更新的 ID + }); + + // 调用 + recordService.updateRecord(reqVO); + // 校验是否更新正确 + PointRecordDO record = recordMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, record); + } + + @Test + public void testUpdateRecord_notExists() { + // 准备参数 + PointRecordUpdateReqVO reqVO = randomPojo(PointRecordUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> recordService.updateRecord(reqVO), RECORD_NOT_EXISTS); + } + + @Test + public void testDeleteRecord_success() { + // mock 数据 + PointRecordDO dbRecord = randomPojo(PointRecordDO.class); + recordMapper.insert(dbRecord);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbRecord.getId(); + + // 调用 + recordService.deleteRecord(id); + // 校验数据不存在了 + assertNull(recordMapper.selectById(id)); + } + + @Test + public void testDeleteRecord_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> recordService.deleteRecord(id), RECORD_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetRecordPage() { + // mock 数据 + PointRecordDO dbRecord = randomPojo(PointRecordDO.class, o -> { // 等会查询到 + o.setBizId(null); + o.setBizType(null); + o.setType(null); + o.setTitle(null); + o.setStatus(null); + }); + recordMapper.insert(dbRecord); + // 测试 bizId 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setBizId(null))); + // 测试 bizType 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setBizType(null))); + // 测试 type 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setType(null))); + // 测试 title 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setTitle(null))); + // 测试 status 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setStatus(null))); + // 准备参数 + PointRecordPageReqVO reqVO = new PointRecordPageReqVO(); + reqVO.setBizId(null); + reqVO.setBizType(null); + reqVO.setType(null); + reqVO.setTitle(null); + reqVO.setStatus(null); + + // 调用 + PageResult pageResult = recordService.getRecordPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbRecord, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetRecordList() { + // mock 数据 + PointRecordDO dbRecord = randomPojo(PointRecordDO.class, o -> { // 等会查询到 + o.setBizId(null); + o.setBizType(null); + o.setType(null); + o.setTitle(null); + o.setStatus(null); + }); + recordMapper.insert(dbRecord); + // 测试 bizId 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setBizId(null))); + // 测试 bizType 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setBizType(null))); + // 测试 type 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setType(null))); + // 测试 title 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setTitle(null))); + // 测试 status 不匹配 + recordMapper.insert(cloneIgnoreId(dbRecord, o -> o.setStatus(null))); + // 准备参数 + PointRecordExportReqVO reqVO = new PointRecordExportReqVO(); + reqVO.setBizId(null); + reqVO.setBizType(null); + reqVO.setType(null); + reqVO.setTitle(null); + reqVO.setStatus(null); + + // 调用 + List list = recordService.getRecordList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbRecord, list.get(0)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImplTest.java b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImplTest.java new file mode 100644 index 000000000..e0bd5a2b2 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinconfig/SignInConfigServiceImplTest.java @@ -0,0 +1,152 @@ +package cn.iocoder.yudao.module.point.service.signinconfig; + +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.point.controller.admin.signinconfig.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinconfig.SignInConfigDO; +import cn.iocoder.yudao.module.point.dal.mysql.signinconfig.SignInConfigMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link SignInConfigServiceImpl} 的单元测试类 + * + * @author QingX + */ +@Import(SignInConfigServiceImpl.class) +public class SignInConfigServiceImplTest extends BaseDbUnitTest { + + @Resource + private SignInConfigServiceImpl signInConfigService; + + @Resource + private SignInConfigMapper signInConfigMapper; + + @Test + public void testCreateSignInConfig_success() { + // 准备参数 + SignInConfigCreateReqVO reqVO = randomPojo(SignInConfigCreateReqVO.class); + + // 调用 + Integer signInConfigId = signInConfigService.createSignInConfig(reqVO); + // 断言 + assertNotNull(signInConfigId); + // 校验记录的属性是否正确 + SignInConfigDO signInConfig = signInConfigMapper.selectById(signInConfigId); + assertPojoEquals(reqVO, signInConfig); + } + + @Test + public void testUpdateSignInConfig_success() { + // mock 数据 + SignInConfigDO dbSignInConfig = randomPojo(SignInConfigDO.class); + signInConfigMapper.insert(dbSignInConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + SignInConfigUpdateReqVO reqVO = randomPojo(SignInConfigUpdateReqVO.class, o -> { + o.setId(dbSignInConfig.getId()); // 设置更新的 ID + }); + + // 调用 + signInConfigService.updateSignInConfig(reqVO); + // 校验是否更新正确 + SignInConfigDO signInConfig = signInConfigMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, signInConfig); + } + + @Test + public void testUpdateSignInConfig_notExists() { + // 准备参数 + SignInConfigUpdateReqVO reqVO = randomPojo(SignInConfigUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> signInConfigService.updateSignInConfig(reqVO), SIGN_IN_CONFIG_NOT_EXISTS); + } + + @Test + public void testDeleteSignInConfig_success() { + // mock 数据 + SignInConfigDO dbSignInConfig = randomPojo(SignInConfigDO.class); + signInConfigMapper.insert(dbSignInConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Integer id = dbSignInConfig.getId(); + + // 调用 + signInConfigService.deleteSignInConfig(id); + // 校验数据不存在了 + assertNull(signInConfigMapper.selectById(id)); + } + + @Test + public void testDeleteSignInConfig_notExists() { + // 准备参数 + Integer id = RandomUtils.randomInteger(); + + // 调用, 并断言异常 + assertServiceException(() -> signInConfigService.deleteSignInConfig(id), SIGN_IN_CONFIG_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSignInConfigPage() { + // mock 数据 + SignInConfigDO dbSignInConfig = randomPojo(SignInConfigDO.class, o -> { // 等会查询到 + o.setDay(null); + }); + signInConfigMapper.insert(dbSignInConfig); + // 测试 day 不匹配 + signInConfigMapper.insert(cloneIgnoreId(dbSignInConfig, o -> o.setDay(null))); + // 准备参数 + SignInConfigPageReqVO reqVO = new SignInConfigPageReqVO(); + reqVO.setDay(null); + + // 调用 + PageResult pageResult = signInConfigService.getSignInConfigPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbSignInConfig, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSignInConfigList() { + // mock 数据 + SignInConfigDO dbSignInConfig = randomPojo(SignInConfigDO.class, o -> { // 等会查询到 + o.setDay(null); + }); + signInConfigMapper.insert(dbSignInConfig); + // 测试 day 不匹配 + signInConfigMapper.insert(cloneIgnoreId(dbSignInConfig, o -> o.setDay(null))); + // 准备参数 + SignInConfigExportReqVO reqVO = new SignInConfigExportReqVO(); + reqVO.setDay(null); + + // 调用 + List list = signInConfigService.getSignInConfigList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbSignInConfig, list.get(0)); + } + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImplTest.java b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImplTest.java new file mode 100644 index 000000000..267bfcd40 --- /dev/null +++ b/yudao-module-point/yudao-module-point-biz/src/test/java/cn/iocoder/yudao/module/point/service/signinrecord/SignInRecordServiceImplTest.java @@ -0,0 +1,167 @@ +package cn.iocoder.yudao.module.point.service.signinrecord; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.point.controller.admin.signinrecord.vo.*; +import cn.iocoder.yudao.module.point.dal.dataobject.signinrecord.SignInRecordDO; +import cn.iocoder.yudao.module.point.dal.mysql.signinrecord.SignInRecordMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link SignInRecordServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(SignInRecordServiceImpl.class) +public class SignInRecordServiceImplTest extends BaseDbUnitTest { + + @Resource + private SignInRecordServiceImpl signInRecordService; + + @Resource + private SignInRecordMapper signInRecordMapper; + + @Test + public void testCreateSignInRecord_success() { + // 准备参数 + SignInRecordCreateReqVO reqVO = randomPojo(SignInRecordCreateReqVO.class); + + // 调用 + Long signInRecordId = signInRecordService.createSignInRecord(reqVO); + // 断言 + assertNotNull(signInRecordId); + // 校验记录的属性是否正确 + SignInRecordDO signInRecord = signInRecordMapper.selectById(signInRecordId); + assertPojoEquals(reqVO, signInRecord); + } + + @Test + public void testUpdateSignInRecord_success() { + // mock 数据 + SignInRecordDO dbSignInRecord = randomPojo(SignInRecordDO.class); + signInRecordMapper.insert(dbSignInRecord);// @Sql: 先插入出一条存在的数据 + // 准备参数 + SignInRecordUpdateReqVO reqVO = randomPojo(SignInRecordUpdateReqVO.class, o -> { + o.setId(dbSignInRecord.getId()); // 设置更新的 ID + }); + + // 调用 + signInRecordService.updateSignInRecord(reqVO); + // 校验是否更新正确 + SignInRecordDO signInRecord = signInRecordMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, signInRecord); + } + + @Test + public void testUpdateSignInRecord_notExists() { + // 准备参数 + SignInRecordUpdateReqVO reqVO = randomPojo(SignInRecordUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> signInRecordService.updateSignInRecord(reqVO), SIGN_IN_RECORD_NOT_EXISTS); + } + + @Test + public void testDeleteSignInRecord_success() { + // mock 数据 + SignInRecordDO dbSignInRecord = randomPojo(SignInRecordDO.class); + signInRecordMapper.insert(dbSignInRecord);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSignInRecord.getId(); + + // 调用 + signInRecordService.deleteSignInRecord(id); + // 校验数据不存在了 + assertNull(signInRecordMapper.selectById(id)); + } + + @Test + public void testDeleteSignInRecord_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> signInRecordService.deleteSignInRecord(id), SIGN_IN_RECORD_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSignInRecordPage() { + // mock 数据 + SignInRecordDO dbSignInRecord = randomPojo(SignInRecordDO.class, o -> { // 等会查询到 + o.setUserId(null); + o.setDay(null); + o.setCreateTime(null); + }); + signInRecordMapper.insert(dbSignInRecord); + // 测试 userId 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setUserId(null))); + // 测试 day 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setDay(null))); + // 测试 createTime 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setCreateTime(null))); + // 准备参数 + SignInRecordPageReqVO reqVO = new SignInRecordPageReqVO(); + reqVO.setUserId(null); + reqVO.setDay(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = signInRecordService.getSignInRecordPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbSignInRecord, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSignInRecordList() { + // mock 数据 + SignInRecordDO dbSignInRecord = randomPojo(SignInRecordDO.class, o -> { // 等会查询到 + o.setUserId(null); + o.setDay(null); + o.setCreateTime(null); + }); + signInRecordMapper.insert(dbSignInRecord); + // 测试 userId 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setUserId(null))); + // 测试 day 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setDay(null))); + // 测试 createTime 不匹配 + signInRecordMapper.insert(cloneIgnoreId(dbSignInRecord, o -> o.setCreateTime(null))); + // 准备参数 + SignInRecordExportReqVO reqVO = new SignInRecordExportReqVO(); + reqVO.setUserId(null); + reqVO.setDay(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + List list = signInRecordService.getSignInRecordList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbSignInRecord, list.get(0)); + } + +} diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index f32144fb5..f38a73ce9 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -54,11 +54,11 @@ - - cn.iocoder.boot - yudao-module-pay-biz - ${revision} - + + + + + @@ -68,19 +68,25 @@ + + + + + + + + + + + + + + + + cn.iocoder.boot - yudao-module-promotion-biz - ${revision} - - - cn.iocoder.boot - yudao-module-product-biz - ${revision} - - - cn.iocoder.boot - yudao-module-trade-biz + yudao-module-point-biz ${revision} @@ -111,7 +117,7 @@ org.springframework.boot spring-boot-maven-plugin - 2.7.10 + 2.7.11 true From 5f64fe052b873393896517769858779cc49e778c Mon Sep 17 00:00:00 2001 From: xiaqing Date: Sat, 10 Jun 2023 20:45:31 +0800 Subject: [PATCH 098/232] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/menu.sql | 230 ++++++++++++++++++++++++++++++++++++++++++++ sql/mysql/point.sql | 152 +++++++++++++++++++++++++++++ 2 files changed, 382 insertions(+) create mode 100644 sql/mysql/menu.sql create mode 100644 sql/mysql/point.sql diff --git a/sql/mysql/menu.sql b/sql/mysql/menu.sql new file mode 100644 index 000000000..704979b78 --- /dev/null +++ b/sql/mysql/menu.sql @@ -0,0 +1,230 @@ +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + '积分设置管理', '', 2, 0, 2162, + 'config', '', 'point/config/index', 0, 'PointConfig' +); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分设置查询', 'point:config:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分设置创建', 'point:config:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分设置更新', 'point:config:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分设置删除', 'point:config:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分设置导出', 'point:config:export', 3, 5, @parentId, + '', '', '', 0 +); + + + +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + '积分签到规则管理', '', 2, 0, 2162, + 'sign-in-config', '', 'point/signInConfig/index', 0, 'SignInConfig' +); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分签到规则查询', 'point:sign-in-config:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分签到规则创建', 'point:sign-in-config:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分签到规则更新', 'point:sign-in-config:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分签到规则删除', 'point:sign-in-config:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '积分签到规则导出', 'point:sign-in-config:export', 3, 5, @parentId, + '', '', '', 0 +); + + +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + '用户积分记录管理', '', 2, 0, 2162, + 'record', '', 'point/record/index', 0, 'PointRecord' +); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户积分记录查询', 'point:record:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户积分记录创建', 'point:record:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户积分记录更新', 'point:record:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户积分记录删除', 'point:record:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户积分记录导出', 'point:record:export', 3, 5, @parentId, + '', '', '', 0 +); + + + +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + '用户签到积分管理', '', 2, 0, 2162, + 'sign-in-record', '', 'point/signInRecord/index', 0, 'SignInRecord' +); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户签到积分查询', 'point:sign-in-record:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户签到积分创建', 'point:sign-in-record:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户签到积分更新', 'point:sign-in-record:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户签到积分删除', 'point:sign-in-record:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '用户签到积分导出', 'point:sign-in-record:export', 3, 5, @parentId, + '', '', '', 0 +); + + diff --git a/sql/mysql/point.sql b/sql/mysql/point.sql new file mode 100644 index 000000000..dfa625940 --- /dev/null +++ b/sql/mysql/point.sql @@ -0,0 +1,152 @@ +/* + Navicat Premium Data Transfer + + Source Server : docer-master-root(3308) + Source Server Type : MySQL + Source Server Version : 80030 + Source Host : 10.211.55.5:3308 + Source Schema : mall + + Target Server Type : MySQL + Target Server Version : 80030 + File Encoding : 65001 + + Date: 10/06/2023 20:13:57 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for member_point_config +-- ---------------------------- +DROP TABLE IF EXISTS `member_point_config`; +CREATE TABLE `member_point_config` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '自增主键', + `trade_deduct_enable` int DEFAULT NULL COMMENT '1 开启积分抵扣\n0 关闭积分抵扣', + `trade_deduct_unit_price` decimal(10,2) DEFAULT NULL COMMENT '积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元)', + `trade_deduct_max_price` bigint DEFAULT NULL COMMENT '积分抵扣最大值', + `trade_give_point` bigint DEFAULT NULL COMMENT '1元赠送多少分', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '变更时间', + `tenant_id` varchar(255) DEFAULT NULL COMMENT '租户id', + `deleted` int DEFAULT '0' COMMENT '是否被删除 0 未删除 1已删除', + `creator` varchar(255) DEFAULT NULL COMMENT '创建人', + `updater` varchar(255) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='积分设置'; + +-- ---------------------------- +-- Records of member_point_config +-- ---------------------------- +BEGIN; +INSERT INTO `member_point_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (1, 1, 0.01, 10000, 1, '2023-06-10 10:57:22', '2023-06-10 03:06:58', '1', 1, '1', '1'); +INSERT INTO `member_point_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (2, 1, 0.01, 10000, 10, '2023-06-10 11:07:12', '2023-06-10 11:07:12', '1', 0, '1', '1'); +INSERT INTO `member_point_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (3, 1, 12.00, 12, 12, '2023-06-10 16:09:26', '2023-06-10 08:10:53', '1', 1, '1', '1'); +COMMIT; + +-- ---------------------------- +-- Table structure for member_point_record +-- ---------------------------- +DROP TABLE IF EXISTS `member_point_record`; +CREATE TABLE `member_point_record` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键', + `biz_id` varchar(255) DEFAULT NULL COMMENT '业务编码', + `biz_type` varchar(255) DEFAULT NULL COMMENT '业务类型', + `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '1增加 0扣减', + `title` varchar(255) DEFAULT NULL COMMENT '积分标题', + `description` varchar(5000) DEFAULT NULL COMMENT '积分描述', + `point` int DEFAULT NULL COMMENT '积分', + `total_point` int NOT NULL COMMENT '变动后的积分', + `status` int DEFAULT NULL COMMENT '状态:1-订单创建,2-冻结期,3-完成,4-失效(订单退款)\n', + `user_id` int DEFAULT NULL COMMENT '用户id', + `freezing_time` datetime DEFAULT NULL COMMENT '冻结时间', + `thawing_time` datetime DEFAULT NULL COMMENT '解冻时间', + `create_time` datetime DEFAULT NULL COMMENT '发生时间', + `tenant_id` varchar(255) DEFAULT NULL COMMENT '租户', + `deleted` int DEFAULT '0' COMMENT '是否删除', + `creator` varchar(255) DEFAULT NULL COMMENT '创建用户', + `updater` varchar(255) DEFAULT NULL COMMENT '更新用户', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `index_userId` (`user_id`), + KEY `index_title` (`title`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户积分记录'; + +-- ---------------------------- +-- Records of member_point_record +-- ---------------------------- +BEGIN; +INSERT INTO `member_point_record` (`id`, `biz_id`, `biz_type`, `type`, `title`, `description`, `point`, `total_point`, `status`, `user_id`, `freezing_time`, `thawing_time`, `create_time`, `tenant_id`, `deleted`, `creator`, `updater`, `update_time`) VALUES (1, '1', '1', '1', '12', NULL, 212, 12, 1, 12, '2023-06-13 00:00:00', '2023-06-20 00:00:00', '2023-06-10 12:38:48', '1', 1, '1', '1', '2023-06-10 04:42:24'); +INSERT INTO `member_point_record` (`id`, `biz_id`, `biz_type`, `type`, `title`, `description`, `point`, `total_point`, `status`, `user_id`, `freezing_time`, `thawing_time`, `create_time`, `tenant_id`, `deleted`, `creator`, `updater`, `update_time`) VALUES (2, '12', '1', '0', NULL, NULL, 1212, 12, 2, 12, '2023-06-28 00:00:00', NULL, '2023-06-10 12:42:48', '1', 0, '1', '1', '2023-06-10 12:43:04'); +INSERT INTO `member_point_record` (`id`, `biz_id`, `biz_type`, `type`, `title`, `description`, `point`, `total_point`, `status`, `user_id`, `freezing_time`, `thawing_time`, `create_time`, `tenant_id`, `deleted`, `creator`, `updater`, `update_time`) VALUES (3, '12', '1', '1', '12', NULL, 12, 12, 1, 12, '2023-06-27 00:00:00', '2023-06-23 00:00:00', '2023-06-10 20:06:48', '1', 0, '1', '1', '2023-06-10 20:06:48'); +COMMIT; + +-- ---------------------------- +-- Table structure for member_sign_in_config +-- ---------------------------- +DROP TABLE IF EXISTS `member_sign_in_config`; +CREATE TABLE `member_sign_in_config` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '规则自增主键', + `day` int DEFAULT NULL COMMENT '签到第x天', + `point` int DEFAULT NULL COMMENT '签到天数对应分数', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '变更时间', + `tenant_id` varchar(255) DEFAULT NULL COMMENT '租户id', + `deleted` int DEFAULT '0' COMMENT '是否删除', + `creator` varchar(255) DEFAULT NULL COMMENT '创建人', + `updater` varchar(255) DEFAULT NULL COMMENT '变更人', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='积分签到规则'; + +-- ---------------------------- +-- Records of member_sign_in_config +-- ---------------------------- +BEGIN; +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (1, 1, 10, '2023-06-10 11:34:43', '2023-06-10 11:34:43', '1', 0, '1', '1'); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (2, 2, 20, '2023-06-10 11:34:59', '2023-06-10 03:55:35', '1', 1, '1', '1'); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (3, 7, 1001, '2023-06-10 17:47:45', '2023-06-10 19:54:37', '1', 0, '1', '1'); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (4, 6, 12121, '2023-06-10 17:47:55', '2023-06-10 19:48:37', '1', 0, '1', '1'); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (5, 2, 12, '2023-06-10 19:54:52', '2023-06-10 19:54:52', '1', 0, '1', '1'); +COMMIT; + +-- ---------------------------- +-- Table structure for member_sign_in_record +-- ---------------------------- +DROP TABLE IF EXISTS `member_sign_in_record`; +CREATE TABLE `member_sign_in_record` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '签到自增id', + `user_id` int DEFAULT NULL COMMENT '签到用户', + `day` int DEFAULT NULL COMMENT '第几天签到', + `point` int DEFAULT NULL COMMENT '签到的分数', + `create_time` datetime DEFAULT NULL COMMENT '签到时间', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '变更时间', + `tenant_id` varchar(255) DEFAULT NULL COMMENT '租户id', + `deleted` int DEFAULT '0' COMMENT '是否删除', + `creator` varchar(255) DEFAULT NULL COMMENT '创建人', + `updater` varchar(255) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户签到积分'; + +-- ---------------------------- +-- Records of member_sign_in_record +-- ---------------------------- +BEGIN; +INSERT INTO `member_sign_in_record` (`id`, `user_id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (1, 121, 1, 123, '2023-06-10 12:58:18', '2023-06-10 04:59:00', '1', 1, '1', '1'); +INSERT INTO `member_sign_in_record` (`id`, `user_id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (2, 12, 12, 12, '2023-06-10 19:56:39', '2023-06-10 11:56:45', '1', 1, '1', '1'); +INSERT INTO `member_sign_in_record` (`id`, `user_id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (3, 12, 12, 1212, '2023-06-10 20:01:17', '2023-06-10 12:01:23', '1', 1, '1', '1'); +INSERT INTO `member_sign_in_record` (`id`, `user_id`, `day`, `point`, `create_time`, `update_time`, `tenant_id`, `deleted`, `creator`, `updater`) VALUES (4, 12, 12, 1212, '2023-06-10 20:01:27', '2023-06-10 20:01:27', '1', 0, '1', '1'); +COMMIT; + +SET FOREIGN_KEY_CHECKS = 1; + + +INSERT INTO `mall`.`system_dict_type` ( `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ( '积分业务类型', 'point_biz_type', 0, '', '1', '2023-06-10 12:15:00', '1', '2023-06-10 04:25:07', b'0', '1970-01-01 00:00:00'); +INSERT INTO `mall`.`system_dict_type` ( `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ( '积分订单状态', 'point_status', 0, '', '1', '2023-06-10 12:16:27', '1', '2023-06-10 12:16:27', b'0', '1970-01-01 00:00:00'); + +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 1, '购物', '1', 'point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:27', '1', '2023-06-10 04:25:15', b'0'); +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 2, '签到', '2', 'point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:48', '1', '2023-06-10 04:25:18', b'0'); +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 1, '订单创建', '1', 'point_status', 0, '', '', '', '1', '2023-06-10 12:16:42', '1', '2023-06-10 12:16:42', b'0'); +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 2, '冻结期', '2', 'point_status', 0, '', '', '', '1', '2023-06-10 12:16:58', '1', '2023-06-10 12:16:58', b'0'); +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 3, '完成', '3', 'point_status', 0, '', '', '', '1', '2023-06-10 12:17:07', '1', '2023-06-10 12:17:07', b'0'); +INSERT INTO `mall`.`system_dict_data` ( `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( 4, '失效(订单退款)', '4', 'point_status', 0, '', '', '', '1', '2023-06-10 12:17:21', '1', '2023-06-10 12:17:21', b'0'); From 5ffc1ac9f34d32c13ddb26711dd21797e286e9ad Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 Jun 2023 00:22:45 +0800 Subject: [PATCH 099/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=A7=92=E6=9D=80=E6=B4=BB=E5=8A=A8=E7=9A=84=20mock?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/coupon/AppCouponController.java | 2 +- .../coupon/AppCouponTemplateController.java | 4 +- .../seckill/AppSeckillActivityController.java | 67 +++++++++++++++++++ .../vo/AppSeckillActivitiDetailRespVO.java | 51 ++++++++++++++ .../seckillactivity/SeckillActivityDO.java | 2 +- .../seckillactivity/SeckillProductDO.java | 6 +- .../app/order/AppTradeOrderController.java | 2 +- 7 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java index a0804079b..481ced4b4 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java @@ -20,7 +20,7 @@ public class AppCouponController { // TODO 芋艿:待实现 @PostMapping("/take") - @Operation(description = "领取优惠劵") + @Operation(summary = "领取优惠劵") public CommonResult takeCoupon(@RequestBody AppCouponTemplatePageReqVO pageReqVO) { return success(1L); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java index f08bd0d74..8c6521803 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java @@ -34,7 +34,7 @@ public class AppCouponTemplateController { // TODO 芋艿:待实现 @GetMapping("/list") - @Operation(description = "获得优惠劵模版列表") // 目前主要给商品详情使用 + @Operation(summary = "获得优惠劵模版列表") // 目前主要给商品详情使用 @Parameters({ @Parameter(name = "spuId", description = "商品 SPU 编号", required = true), @Parameter(name = "useType", description = "使用类型"), @@ -76,7 +76,7 @@ public class AppCouponTemplateController { // TODO 芋艿:待实现 @GetMapping("/page") - @Operation(description = "获得优惠劵模版分页") + @Operation(summary = "获得优惠劵模版分页") public CommonResult> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) { return null; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java new file mode 100644 index 000000000..22d4f76bd --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.promotion.controller.app.seckill; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.AppSeckillActivitiDetailRespVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 App - 秒杀活动") +@RestController +@RequestMapping("/promotion/seckill-activity") +@Validated +public class AppSeckillActivityController { + + @GetMapping("/get-detail") + @Operation(summary = "获得秒杀活动明细") + @Parameter(name = "id", description = "活动编号", required = true, example = "1024") + public CommonResult getSeckillActivity(@RequestParam("id") Long id) { + // TODO 芋艿:如果禁用的时候,需要抛出异常; + AppSeckillActivitiDetailRespVO obj = new AppSeckillActivitiDetailRespVO(); + // 设置其属性的值 + obj.setId(id); + obj.setName("晚九点限时秒杀"); + obj.setStatus(1); + obj.setStartTime(LocalDateTime.of(2023, 6, 10, 0, 0, 0)); + obj.setEndTime(LocalDateTime.of(2023, 6, 10, 23, 59, 0)); + obj.setSpuId(633L); + // 创建一个Product对象的列表 + List productList = new ArrayList<>(); + // 创建三个新的Product对象并设置其属性的值 + AppSeckillActivitiDetailRespVO.Product product1 = new AppSeckillActivitiDetailRespVO.Product(); + product1.setSkuId(4096L); + product1.setSeckillPrice(100); + product1.setQuota(50); + // 将第一个Product对象添加到列表中 + productList.add(product1); + // 创建第二个Product对象并设置其属性的值 + AppSeckillActivitiDetailRespVO.Product product2 = new AppSeckillActivitiDetailRespVO.Product(); + product2.setSkuId(4097L); + product2.setSeckillPrice(200); + product2.setQuota(100); + // 将第二个Product对象添加到列表中 + productList.add(product2); + // 创建第三个Product对象并设置其属性的值 + AppSeckillActivitiDetailRespVO.Product product3 = new AppSeckillActivitiDetailRespVO.Product(); + product3.setSkuId(4098L); + product3.setSeckillPrice(300); + product3.setQuota(150); + // 将第三个Product对象添加到列表中 + productList.add(product3); + // 将Product列表设置为对象的属性值 + obj.setProducts(productList); + return success(obj); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java new file mode 100644 index 000000000..62cdf9b4f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "用户 App - 秒杀活动 Response VO") +@Data +public class AppSeckillActivitiDetailRespVO { + + @Schema(description = "秒杀活动编号", required = true, example = "1024") + private Long id; + + @Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀") + private String name; + + @Schema(description = "活动状态", required = true, example = "1") + private Integer status; + + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; + + @Schema(description = "活动开始时间", required = true) + private LocalDateTime startTime; + + @Schema(description = "活动结束时间", required = true) + private LocalDateTime endTime; + + @Schema(description = "商品 SPU 编号", required = true, example = "2048") + private Long spuId; + + @Schema(description = "商品 SPU 名字", required = true) + private List products; + + @Schema(description = "商品信息") + @Data + public static class Product { + + @Schema(description = "商品 SKU 编号", required = true, example = "4096") + private Long skuId; + + @Schema(description = "秒杀金额,单位:分", required = true, example = "100") + private Integer seckillPrice; + + @Schema(description = "秒杀限量库存", required = true, example = "50") + private Integer quota; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java index 1d3b6da27..2a0dcd70b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java @@ -37,7 +37,7 @@ public class SeckillActivityDO extends BaseDO { private String name; /** * 活动状态 - *

+ * * 枚举 {@link PromotionActivityStatusEnum 对应的类} */ private Integer status; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java index 3783d6dda..2adc0acfd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java @@ -53,6 +53,7 @@ public class SeckillProductDO extends BaseDO { */ private Integer seckillPrice; + // TODO @芋艿:改成 quota 限量库存;每次购买时,需要减小; /** * 秒杀库存 */ @@ -61,5 +62,6 @@ public class SeckillProductDO extends BaseDO { /** * 每人限购 */ - private Integer limitBuyCount; -} \ No newline at end of file + private Integer limitCount; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index e3008fdd6..49bc63986 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -64,7 +64,7 @@ public class AppTradeOrderController { } @PostMapping("/update-paid") - @Operation(description = "更新订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @Operation(summary = "更新订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob public CommonResult updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { tradeOrderService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId()); From 45e5578cb44392e8e59c2da4296034365e25148c Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 11 Jun 2023 10:22:33 +0800 Subject: [PATCH 100/232] =?UTF-8?q?=E5=BF=AB=E9=80=92=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E3=80=81=20=E9=80=9A=E8=BF=87=E5=BF=AB=E9=80=92=E9=B8=9F?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/config/YudaoWebAutoConfiguration.java | 12 ++ .../trade/enums/ErrorCodeConstants.java | 3 +- .../config/TradeExpressQueryProperties.java | 65 +++++++++ .../delivery/core/ExpressQueryClient.java | 21 +++ .../delivery/core/ExpressQueryProvider.java | 20 +++ .../core/ExpressQueryProviderEnum.java | 28 ++++ .../core/ExpressQueryProviderFactory.java | 14 ++ .../core/convert/ExpressQueryConvert.java | 20 +++ .../delivery/core/dto/ExpressQueryReqDTO.java | 30 ++++ .../core/dto/ExpressQueryRespDTO.java | 22 +++ .../kdniao/KdNiaoExpressQueryReqDTO.java | 32 +++++ .../kdniao/KdNiaoExpressQueryRespDTO.java | 75 ++++++++++ .../core/impl/ExpressQueryClientImpl.java | 53 +++++++ .../impl/ExpressQueryProviderFactoryImpl.java | 45 ++++++ .../core/impl/Kd100ExpressQueryProvider.java | 30 ++++ .../core/impl/KdNiaoExpressQueryProvider.java | 129 ++++++++++++++++++ .../impl/KdNiaoExpressQueryProviderTest.java | 52 +++++++ .../application-trade-delivery-query.yaml | 15 ++ 18 files changed, 665 insertions(+), 1 deletion(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java index b20565eca..110eb80bb 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java @@ -10,11 +10,14 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @@ -107,6 +110,15 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER); } + /** + * 创建 RestTemplate 实例 + * @param restTemplateBuilder {@link RestTemplateAutoConfiguration#restTemplateBuilder} + */ + @Bean + public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){ + return restTemplateBuilder.build(); + } + public static FilterRegistrationBean createFilterBean(T filter, Integer order) { FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); bean.setOrder(order); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 43a9d62e6..4d74a3695 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -53,7 +53,8 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); - ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003006, "自提门店不存在"); + ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003006, "快递接口查询失败"); + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003007, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java new file mode 100644 index 000000000..c0705b74b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.config; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; + +/** + * 交易快递查询的配置项 + * + * @author jason + */ +@Component +@ConfigurationProperties(prefix = "yudao.trade.express.query") +@Data +@Validated +public class TradeExpressQueryProperties { + + /** + * 快递查询服务商, 如果未配置,默认使用快递鸟 + */ + private ExpressQueryProviderEnum expressQueryProvider; + /** + * 快递鸟配置 + */ + @Valid + private KdNiaoConfig kdNiao; + /** + * 快递 100 配置 + */ + @Valid + private Kd100Config kd100; + + /** + * 快递鸟配置项目 + */ + @Data + public static class KdNiaoConfig { + + /** + * 快递鸟用户 ID + */ + @NotEmpty(message = "快递鸟用户 ID 配置项不能为空") + private String businessId; + + /** + * 快递鸟 API Key + */ + @NotEmpty(message = "快递鸟 Api Key 配置项不能为空") + private String apiKey; + } + + /** + * 快递100 配置项 TODO + */ + public static class Kd100Config { + + } + + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java new file mode 100644 index 000000000..d43429d72 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; + +import java.util.List; + +/** + * 快递查询客户端 + * + * @author jason + */ +public interface ExpressQueryClient { + + /** + * 快递实时查询 + * + * @param reqDTO 查询请求参数 + */ + List realTimeQuery(ExpressQueryReqDTO reqDTO); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java new file mode 100644 index 000000000..6fb0a4179 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; + +import java.util.List; + +/** + * 快递查询服务商 + * + * @author jason + */ +public interface ExpressQueryProvider { + /** + * 快递实时查询 + * + * @param reqDTO 查询请求参数 + */ + List realTimeQueryExpress(ExpressQueryReqDTO reqDTO); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java new file mode 100644 index 000000000..094848ba6 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core; + +import lombok.Getter; + +/** + * 快递查询服务商枚举 + * + * @author jason + */ +@Getter +public enum ExpressQueryProviderEnum { + KD_NIAO("kd-niao", "快递鸟"), + KD_100("kd-100", "快递100"); + /** + * 快递服务商唯一编码 + */ + private final String code; + + /** + * 快递服务商名称 + */ + private final String name; + + ExpressQueryProviderEnum(String code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java new file mode 100644 index 000000000..87504faa3 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core; + +/** + * 快递服务商工厂, 用于创建和缓存快递服务商服务 + * @author jason + */ +public interface ExpressQueryProviderFactory { + + /** + * 通过枚举获取快递查询服务商, 如果不存在。就创建一个对应的快递查询服务商 + * @param queryProviderEnum 快递服务商枚举 + */ + ExpressQueryProvider getOrCreateExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java new file mode 100644 index 000000000..834c6170e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.convert; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface ExpressQueryConvert { + + ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class); + + List convertList(List expressTrackList); + + KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java new file mode 100644 index 000000000..7315aea07 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto; + +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; +import lombok.Data; + +/** + * 快递查询 Req DTO + * + * @author jason + */ +@Data +public class ExpressQueryReqDTO { + + /** + * 快递公司编码 + * + * 对应 {@link DeliveryExpressDO#getCode()} } + */ + private String expressCompanyCode; + + /** + * 发货快递单号 + */ + private String logisticsNo; + + /** + * 收、寄件人的电话号码 + */ + private String phone; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java new file mode 100644 index 000000000..feb06ea96 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto; + +import lombok.Data; + +/** + * 快递查询 Resp DTO + * + * @author jason + */ +@Data +public class ExpressQueryRespDTO { + + /** + * 发生时间 + */ + private String time; + + /** + * 快递状态 + */ + private String state; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java new file mode 100644 index 000000000..3f0faae49 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 快递鸟快递查询 Req DTO + * + * @author jason + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class KdNiaoExpressQueryReqDTO { + /** + * 快递公司编码 + */ + @JsonProperty("ShipperCode") + private String expressCompanyCode; + + /** + * 快递单号 + */ + @JsonProperty("LogisticCode") + private String logisticsNo; + + /** + * 订单编号 + */ + @JsonProperty("OrderCode") + private String orderNo; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java new file mode 100644 index 000000000..3e8883bbd --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * 快递鸟快递查询 Resp DTO 参见 快递鸟接口文档 + * + * @author jason + */ +@Data +public class KdNiaoExpressQueryRespDTO { + + /** + * 快递公司编码 + */ + @JsonProperty("ShipperCode") + private String expressCompanyCode; + + /** + * 快递单号 + */ + @JsonProperty("LogisticCode") + private String logisticsNo; + + /** + * 订单编号 + */ + @JsonProperty("OrderCode") + private String orderNo; + + @JsonProperty("EBusinessID") + private String businessId; + @JsonProperty("State") + private String state; + /** + * 成功与否 + */ + @JsonProperty("Success") + private Boolean success; + /** + * 失败原因 + */ + @JsonProperty("Reason") + private String reason; + + @JsonProperty("Traces") + private List tracks; + + @Data + public static class ExpressTrack { + /** + * 轨迹发生时间 + */ + @JsonProperty("AcceptTime") + private String time; + /** + * 轨迹描述 + */ + @JsonProperty("AcceptStation") + private String state; + } + +// { +// "EBusinessID": "1237100", +// "Traces": [], +// "State": "0", +// "ShipperCode": "STO", +// "LogisticCode": "638650888018", +// "Success": true, +// "Reason": "暂无轨迹信息" +// } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java new file mode 100644 index 000000000..cbf29cd4e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderFactory; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum.KD_NIAO; + +/** + * 快递查询客户端实现 + * + * @author jason + */ +@Component +@Slf4j +public class ExpressQueryClientImpl implements ExpressQueryClient { + @Resource + private ExpressQueryProviderFactory expressQueryProviderFactory; + @Resource + private TradeExpressQueryProperties tradeExpressQueryProperties; + + private ExpressQueryProvider expressQueryProvider; + @PostConstruct + private void init(){ + ExpressQueryProviderEnum queryProvider = tradeExpressQueryProperties.getExpressQueryProvider(); + if (queryProvider == null) { + // 如果未设置,默认使用快递鸟 + queryProvider = KD_NIAO; + } + expressQueryProvider = expressQueryProviderFactory.getOrCreateExpressQueryProvider(queryProvider); + if (expressQueryProvider == null) { + // 记录错误日志 + log.error("获取创建快递查询服务商{}失败,请检查相关配置", queryProvider); + } + Assert.notNull(expressQueryProvider, "快递查询服务商不能为空"); + + } + @Override + public List realTimeQuery(ExpressQueryReqDTO reqDTO) { + return expressQueryProvider.realTimeQueryExpress(reqDTO); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java new file mode 100644 index 000000000..3060cb21c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author jason + */ +@Component +public class ExpressQueryProviderFactoryImpl implements ExpressQueryProviderFactory { + + private final Map providerMap = new ConcurrentHashMap<>(8); + @Resource + private TradeExpressQueryProperties tradeExpressQueryProperties; + @Resource + private RestTemplate restTemplate; + + @Override + public ExpressQueryProvider getOrCreateExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum) { + return providerMap.computeIfAbsent(queryProviderEnum, + provider -> createExpressQueryProvider(provider, tradeExpressQueryProperties)); + } + + private ExpressQueryProvider createExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum, + TradeExpressQueryProperties tradeExpressQueryProperties) { + ExpressQueryProvider result = null; + switch (queryProviderEnum) { + case KD_NIAO: + result = new KdNiaoExpressQueryProvider(restTemplate, tradeExpressQueryProperties.getKdNiao()); + break; + case KD_100: + result = new Kd100ExpressQueryProvider(restTemplate, tradeExpressQueryProperties.getKd100()); + break; + } + return result; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java new file mode 100644 index 000000000..12a2fe653 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import org.springframework.web.client.RestTemplate; + +import java.util.List; + +/** + * 快递 100 服务商 TODO + * @author jason + */ +public class Kd100ExpressQueryProvider implements ExpressQueryProvider { + + private final RestTemplate restTemplate; + + private final TradeExpressQueryProperties.Kd100Config config; + + public Kd100ExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.Kd100Config config) { + this.restTemplate = restTemplate; + this.config = config; + } + + @Override + public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { + return null; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java new file mode 100644 index 000000000..00a2f8b24 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java @@ -0,0 +1,129 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.net.URLEncodeUtil; +import cn.hutool.crypto.digest.DigestUtil; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; +import com.fasterxml.jackson.core.type.TypeReference; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; +import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; + +/** + * 快递鸟服务商 + * + * @author jason + */ +@Slf4j +public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { + private static final String REAL_TIME_QUERY_URL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"; + /** + * 快递鸟即时查询免费版 RequestType + */ + private static final String REAL_TIME_FREE_REQ_TYPE = "1002"; + private final RestTemplate restTemplate; + private final TradeExpressQueryProperties.KdNiaoConfig config; + + public KdNiaoExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.KdNiaoConfig config) { + this.restTemplate = restTemplate; + this.config = config; + } + + /** + * 快递鸟即时查询免费版本 参见 快递鸟接口文档 + * @param reqDTO 查询请求参数 + */ + @Override + public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { + KdNiaoExpressQueryReqDTO kdNiaoReqData = INSTANCE.convert(reqDTO); + // 快递公司编码需要转成大写 + kdNiaoReqData.setExpressCompanyCode(reqDTO.getExpressCompanyCode().toUpperCase()); + KdNiaoExpressQueryRespDTO respDTO = sendKdNiaoApiRequest(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, + kdNiaoReqData, KdNiaoExpressQueryRespDTO.class); + log.debug("快递鸟即时查询接口返回 {}", respDTO); + if (respDTO.getSuccess() && CollUtil.isNotEmpty(respDTO.getTracks())) { + return INSTANCE.convertList(respDTO.getTracks()); + }else{ + return Collections.emptyList(); + } + } + + private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, + Class respClass){ + return sendKdNiaoApiRequest(url, requestType, req, respClass, null); + } + private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, + TypeReference typeRefResp){ + return sendKdNiaoApiRequest(url, requestType, req, null, typeRefResp); + } + + /** + * 快递鸟 通用的 API 请求 + * @param url 请求 url + * @param requestType 对应的请求指令 (快递鸟的RequestType) + * @param req 对应请求的请求参数 + * @param respClass 对应请求的响应 class + * @param typeRefResp 对应请求的响应 TypeReference + * @param 每个请求的请求结构 Req DTO + * @param 每个请求的响应结构 Resp DTO + */ + private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, + Class respClass, TypeReference typeRefResp){ + // 请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + // 请求体 + String reqData = JsonUtils.toJsonString(req); + String dataSign = generateDataSign(reqData, config.getApiKey()); + log.trace("得到快递鸟接口 RequestType : {} 的 签名: {}", requestType, dataSign); + MultiValueMap requestBody = new LinkedMultiValueMap<>(); + requestBody.add("RequestData", reqData); + requestBody.add("DataType", "2"); + requestBody.add("EBusinessID", config.getBusinessId()); + requestBody.add("DataSign", dataSign); + requestBody.add("RequestType", requestType); + log.debug("快递鸟接口 RequestType : {}, 的请求参数 {}", requestType, requestBody); + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + // 发送请求 + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + log.debug("快递鸟接口 RequestType : {}, 的响应结果 {}", requestType, responseEntity); + // 处理响应 + if (responseEntity.getStatusCode().is2xxSuccessful()) { + String response = responseEntity.getBody(); + if (respClass != null && typeRefResp == null) { + return JsonUtils.parseObject(response, respClass); + } else { + return JsonUtils.parseObject(response, typeRefResp); + } + } else { + throw exception(EXPRESS_API_QUERY_FAILED); + } + } + + /** + * 快递鸟生成请求签名 参见 签名说明 + * @param reqData 请求实体 + * @param apiKey api Key + */ + private String generateDataSign(String reqData, String apiKey) { + String plainText = String.format("%s%s", reqData, apiKey); + log.trace("签名前的数据 {}", plainText); + return URLEncodeUtil.encode(Base64.encode(DigestUtil.md5Hex(plainText))); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java new file mode 100644 index 000000000..f64550c77 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +import javax.annotation.Resource; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author jason + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressQueryProviderTest.Application.class) +@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 +public class KdNiaoExpressQueryProviderTest { + @Resource + private RestTemplateBuilder builder; + @Resource + private TradeExpressQueryProperties expressQueryProperties; + + private KdNiaoExpressQueryProvider kdNiaoExpressQueryProvider; + + @BeforeEach + public void init(){ + kdNiaoExpressQueryProvider = new KdNiaoExpressQueryProvider(builder.build(),expressQueryProperties.getKdNiao()); + } + @Test + void queryExpress() { + ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); + reqDTO.setExpressCompanyCode("yto"); + reqDTO.setLogisticsNo("YT1764381060802"); + List expressQueryRespDTOS = kdNiaoExpressQueryProvider.realTimeQueryExpress(reqDTO); + assertNotNull(expressQueryRespDTOS); + } + + @Import({ + RestTemplateAutoConfiguration.class + }) + @EnableConfigurationProperties(TradeExpressQueryProperties.class) + public static class Application { + } +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml new file mode 100644 index 000000000..9922b84b9 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml @@ -0,0 +1,15 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +yudao: + trade: + express: + query: + express-query-provider: kd_niao + kd-niao: + api-key: 8e22d97d-6a3d-442e-b243-2190c9f0cfdd + business-id: 1801700 \ No newline at end of file From 644d976a7855e06b7e947b75a2711e2a664445fa Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 11 Jun 2023 18:15:33 +0800 Subject: [PATCH 101/232] =?UTF-8?q?=E5=BF=AB=E9=80=92100=20=E5=BF=AB?= =?UTF-8?q?=E9=80=92=E6=9F=A5=E8=AF=A2=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/json/JsonUtils.java | 2 + .../trade/enums/ErrorCodeConstants.java | 5 +- .../config/TradeExpressQueryProperties.java | 14 +++- .../core/convert/ExpressQueryConvert.java | 6 ++ .../kd100/Kd100ExpressQueryReqDTO.java | 47 +++++++++++ .../kd100/Kd100ExpressQueryRespDTO.java | 59 ++++++++++++++ .../core/impl/Kd100ExpressQueryProvider.java | 81 ++++++++++++++++++- .../core/impl/KdNiaoExpressQueryProvider.java | 34 +++----- .../impl/Kd100ExpressQueryProviderTest.java | 56 +++++++++++++ .../impl/KdNiaoExpressQueryProviderTest.java | 20 ++--- .../application-trade-delivery-query.yaml | 9 ++- 11 files changed, 293 insertions(+), 40 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java index 86d220638..7a2b1abce 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -29,6 +30,7 @@ public class JsonUtils { static { objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化 } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 4d74a3695..341a02c2b 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -53,8 +53,9 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); - ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003006, "快递接口查询失败"); - ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003007, "自提门店不存在"); + ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003006, "快递查询接口异常"); + ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003007, "快递查询返回失败, 原因:{}"); + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003008, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java index c0705b74b..567e34085 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java @@ -55,10 +55,20 @@ public class TradeExpressQueryProperties { } /** - * 快递100 配置项 TODO + * 快递100 配置项 */ + @Data public static class Kd100Config { - + /** + * 快递 100 授权码 + */ + @NotEmpty(message = "快递 100 授权码配置项不能为空") + private String customer; + /** + * 快递 100 授权 key + */ + @NotEmpty(message = "快递 100 授权 Key 配置项不能为空") + private String key; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java index 834c6170e..d22f61ae5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.convert; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; import org.mapstruct.Mapper; @@ -16,5 +18,9 @@ public interface ExpressQueryConvert { List convertList(List expressTrackList); + List convertList2(List expressTrackList); + KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); + + Kd100ExpressQueryReqDTO convert2(ExpressQueryReqDTO dto); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java new file mode 100644 index 000000000..e2d55db34 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 快递 100 快递查询 Req DTO + * + * @author jason + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Kd100ExpressQueryReqDTO { + + /** + * 快递公司编码 + */ + @JsonProperty("com") + private String expressCompanyCode; + + /** + * 快递单号 + */ + @JsonProperty("num") + private String logisticsNo; + + /** + * 收、寄件人的电话号码 + */ + private String phone; + + /** + * 出发地城市 + */ + private String from; + + /** + * 目的地城市,到达目的地后会加大监控频率 + */ + private String to; + + /** + * 返回结果排序:desc降序(默认),asc 升序 + */ + private String order; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java new file mode 100644 index 000000000..49be06234 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * 快递 100 实时快递查询 Resp DTO 参见 快递 100 文档 + * + * @author jason + */ +@Data +public class Kd100ExpressQueryRespDTO { + + /** + * 快递公司编码 + */ + @JsonProperty("com") + private String expressCompanyCode; + + /** + * 快递单号 + */ + @JsonProperty("nu") + private String logisticsNo; + + /** + * 快递单当前状态 + */ + private String state; + + /** + * 查询结果, 失败返回 "false" + */ + private String result; + + /** + * 查询结果失败时的错误信息 + */ + private String message; + + @JsonProperty("data") + private List tracks; + + @Data + public static class ExpressTrack { + /** + * 轨迹发生时间 + */ + @JsonProperty("time") + private String time; + /** + * 轨迹描述 + */ + @JsonProperty("context") + private String state; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java index 12a2fe653..07a51d0c9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java @@ -1,19 +1,39 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.HexUtil; +import cn.hutool.crypto.digest.DigestUtil; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import java.util.Collections; import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_ERROR; +import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; /** - * 快递 100 服务商 TODO + * 快递 100 服务商 + * * @author jason */ +@Slf4j public class Kd100ExpressQueryProvider implements ExpressQueryProvider { + private static final String REAL_TIME_QUERY_URL = "https://poll.kuaidi100.com/poll/query.do"; private final RestTemplate restTemplate; private final TradeExpressQueryProperties.Kd100Config config; @@ -25,6 +45,63 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { @Override public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { - return null; + Kd100ExpressQueryReqDTO kd100ReqParam = INSTANCE.convert2(reqDTO); + // 快递公司编码需要转成小写 + kd100ReqParam.setExpressCompanyCode(kd100ReqParam.getExpressCompanyCode().toLowerCase()); + Kd100ExpressQueryRespDTO respDTO = sendExpressQueryReq(REAL_TIME_QUERY_URL, kd100ReqParam, + Kd100ExpressQueryRespDTO.class); + log.debug("快递 100 接口 查询接口返回 {}", respDTO); + if (Objects.equals("false", respDTO.getResult())) { + log.error("快递 100 接口 返回失败 {} ", respDTO.getMessage()); + throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage()); + } else { + if (CollUtil.isNotEmpty(respDTO.getTracks())) { + return INSTANCE.convertList2(respDTO.getTracks()); + } else { + return Collections.emptyList(); + } + } + } + + /** + * 发送快递 100 实时快递查询请求,可以作为通用快递 100 通用请求接口。 目前没有其它场景需要使用。暂时放这里 + * @param url 请求 url + * @param req 对应请求的请求参数 + * @param respClass 对应请求的响应 class + * @param 每个请求的请求结构 Req DTO + * @param 每个请求的响应结构 Resp DTO + */ + private Resp sendExpressQueryReq(String url, Req req, Class respClass) { + // 请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + // 生成签名 + String param = JsonUtils.toJsonString(req); + String sign = generateReqSign(param, config.getKey(), config.getCustomer()); + log.debug("快递 100 快递 接口生成签名的: {}", sign); + // 请求体 + MultiValueMap requestBody = new LinkedMultiValueMap<>(); + requestBody.add("customer", config.getCustomer()); + requestBody.add("sign", sign); + requestBody.add("param", param); + log.debug("快递 100 接口的请求参数: {}", requestBody); + + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + // 发送请求 + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + log.debug("快递 100 接口响应结果 {}", responseEntity); + // 处理响应 + if (responseEntity.getStatusCode().is2xxSuccessful()) { + String response = responseEntity.getBody(); + return JsonUtils.parseObject(response, respClass); + } else { + throw exception(EXPRESS_API_QUERY_ERROR); + } + } + + private String generateReqSign(String param, String key, String customer) { + String plainText = String.format("%s%s%s", param, key, customer); + log.debug("快递 100 接口待签名的数据 {}", plainText); + return HexUtil.encodeHexStr(DigestUtil.md5(plainText), false); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java index 00a2f8b24..b911892cd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReq import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; -import com.fasterxml.jackson.core.type.TypeReference; import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.util.LinkedMultiValueMap; @@ -23,6 +22,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_ERROR; import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; /** @@ -57,34 +57,28 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { KdNiaoExpressQueryRespDTO respDTO = sendKdNiaoApiRequest(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, kdNiaoReqData, KdNiaoExpressQueryRespDTO.class); log.debug("快递鸟即时查询接口返回 {}", respDTO); - if (respDTO.getSuccess() && CollUtil.isNotEmpty(respDTO.getTracks())) { - return INSTANCE.convertList(respDTO.getTracks()); + if(!respDTO.getSuccess()){ + throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getReason()); }else{ - return Collections.emptyList(); + if (CollUtil.isNotEmpty(respDTO.getTracks())) { + return INSTANCE.convertList(respDTO.getTracks()); + }else{ + return Collections.emptyList(); + } } } - private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, - Class respClass){ - return sendKdNiaoApiRequest(url, requestType, req, respClass, null); - } - private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, - TypeReference typeRefResp){ - return sendKdNiaoApiRequest(url, requestType, req, null, typeRefResp); - } - /** - * 快递鸟 通用的 API 请求 + * 快递鸟 通用的 API 请求, 暂时没有其他应用场景, 暂时放这里 * @param url 请求 url * @param requestType 对应的请求指令 (快递鸟的RequestType) * @param req 对应请求的请求参数 * @param respClass 对应请求的响应 class - * @param typeRefResp 对应请求的响应 TypeReference * @param 每个请求的请求结构 Req DTO * @param 每个请求的响应结构 Resp DTO */ private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, - Class respClass, TypeReference typeRefResp){ + Class respClass){ // 请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -106,13 +100,9 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { // 处理响应 if (responseEntity.getStatusCode().is2xxSuccessful()) { String response = responseEntity.getBody(); - if (respClass != null && typeRefResp == null) { - return JsonUtils.parseObject(response, respClass); - } else { - return JsonUtils.parseObject(response, typeRefResp); - } + return JsonUtils.parseObject(response, respClass); } else { - throw exception(EXPRESS_API_QUERY_FAILED); + throw exception(EXPRESS_API_QUERY_ERROR); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java new file mode 100644 index 000000000..0d82f745b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +import javax.annotation.Resource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @author jason + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Kd100ExpressQueryProviderTest.Application.class) +@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 +public class Kd100ExpressQueryProviderTest { + @Resource + private RestTemplateBuilder builder; + @Resource + private TradeExpressQueryProperties expressQueryProperties; + + private Kd100ExpressQueryProvider kd100ExpressQueryProvider; + + @BeforeEach + public void init(){ + kd100ExpressQueryProvider = new Kd100ExpressQueryProvider(builder.build(),expressQueryProperties.getKd100()); + } + @Test + @Disabled("需要 授权 key. 暂时忽略") + void testRealTimeQueryExpressFailed() { + ServiceException t = assertThrows(ServiceException.class, () -> { + ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); + reqDTO.setExpressCompanyCode("yto"); + reqDTO.setLogisticsNo("YT9383342193097"); + kd100ExpressQueryProvider.realTimeQueryExpress(reqDTO); + }); + assertEquals(1011003007, t.getCode()); + } + + @Import({ + RestTemplateAutoConfiguration.class + }) + @EnableConfigurationProperties(TradeExpressQueryProperties.class) + public static class Application { + } +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java index f64550c77..cdde6c683 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java @@ -1,9 +1,10 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -13,9 +14,8 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; import javax.annotation.Resource; -import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author jason @@ -35,12 +35,14 @@ public class KdNiaoExpressQueryProviderTest { kdNiaoExpressQueryProvider = new KdNiaoExpressQueryProvider(builder.build(),expressQueryProperties.getKdNiao()); } @Test - void queryExpress() { - ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); - reqDTO.setExpressCompanyCode("yto"); - reqDTO.setLogisticsNo("YT1764381060802"); - List expressQueryRespDTOS = kdNiaoExpressQueryProvider.realTimeQueryExpress(reqDTO); - assertNotNull(expressQueryRespDTOS); + @Disabled("需要 授权 key. 暂时忽略") + void testRealTimeQueryExpressFailed() { + assertThrows(ServiceException.class,() ->{ + ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); + reqDTO.setExpressCompanyCode("yy"); + reqDTO.setLogisticsNo("YT9383342193097"); + kdNiaoExpressQueryProvider.realTimeQueryExpress(reqDTO); + }); } @Import({ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml index 9922b84b9..e01cb1652 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml @@ -3,7 +3,7 @@ spring: lazy-initialization: true # 开启懒加载,加快速度 banner-mode: off # 单元测试,禁用 Banner ---- #################### 数据库相关配置 #################### +--- #################### 交易快递查询相关配置 #################### yudao: trade: @@ -11,5 +11,8 @@ yudao: query: express-query-provider: kd_niao kd-niao: - api-key: 8e22d97d-6a3d-442e-b243-2190c9f0cfdd - business-id: 1801700 \ No newline at end of file + api-key: xxx + business-id: xxxxxxxx + kd100: + customer: xxxx + key: xxxxx From b6c7a940be7e62b1f7054fc018dc48684b41b9aa Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 Jun 2023 23:19:04 +0800 Subject: [PATCH 102/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=A7=92=E6=9D=80=E6=B4=BB=E5=8A=A8=E7=9A=84=20mock?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seckill/vo/activity/SeckillActivityBaseVO.java | 2 +- .../app/seckill/AppSeckillActivityController.java | 13 ++++++++----- .../seckill/vo/AppSeckillActivitiDetailRespVO.java | 3 +++ .../seckillactivity/SeckillActivityConvert.java | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java index 1fa803f71..63f68da1c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java @@ -58,7 +58,7 @@ public class SeckillActivityBaseVO { @Schema(description = "每人限购", example = "10") // 如果为 0 则不限购 @Min(value = 0, message = "每人限购需要大于等于 0") - private Integer limitBuyCount; + private Integer limitCount; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java index 22d4f76bd..4e37a361e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java @@ -33,30 +33,33 @@ public class AppSeckillActivityController { obj.setId(id); obj.setName("晚九点限时秒杀"); obj.setStatus(1); - obj.setStartTime(LocalDateTime.of(2023, 6, 10, 0, 0, 0)); - obj.setEndTime(LocalDateTime.of(2023, 6, 10, 23, 59, 0)); + obj.setStartTime(LocalDateTime.of(2023, 6, 11, 0, 0, 0)); + obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0)); obj.setSpuId(633L); // 创建一个Product对象的列表 List productList = new ArrayList<>(); // 创建三个新的Product对象并设置其属性的值 AppSeckillActivitiDetailRespVO.Product product1 = new AppSeckillActivitiDetailRespVO.Product(); - product1.setSkuId(4096L); + product1.setSkuId(1L); product1.setSeckillPrice(100); product1.setQuota(50); + product1.setLimitCount(3); // 将第一个Product对象添加到列表中 productList.add(product1); // 创建第二个Product对象并设置其属性的值 AppSeckillActivitiDetailRespVO.Product product2 = new AppSeckillActivitiDetailRespVO.Product(); - product2.setSkuId(4097L); + product2.setSkuId(2L); product2.setSeckillPrice(200); product2.setQuota(100); + product2.setLimitCount(4); // 将第二个Product对象添加到列表中 productList.add(product2); // 创建第三个Product对象并设置其属性的值 AppSeckillActivitiDetailRespVO.Product product3 = new AppSeckillActivitiDetailRespVO.Product(); - product3.setSkuId(4098L); + product3.setSkuId(3L); product3.setSeckillPrice(300); product3.setQuota(150); + product3.setLimitCount(5); // 将第三个Product对象添加到列表中 productList.add(product3); // 将Product列表设置为对象的属性值 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java index 62cdf9b4f..0f1408928 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java @@ -46,6 +46,9 @@ public class AppSeckillActivitiDetailRespVO { @Schema(description = "秒杀限量库存", required = true, example = "50") private Integer quota; + @Schema(description = "limitCount", required = true, example = "10") + private Integer limitCount; + } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java index 1a00fdeb6..0294c248b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java @@ -56,7 +56,7 @@ public interface SeckillActivityConvert { && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) - && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); + && ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount()); } /** @@ -71,7 +71,7 @@ public interface SeckillActivityConvert { && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) - && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); + && ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount()); } From e1a8e45ac781bb2948adbabd86dc801ef2595e07 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 Jun 2023 23:40:38 +0800 Subject: [PATCH 103/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E5=BF=AB?= =?UTF-8?q?=E9=80=92=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 4 ++-- .../DeliveryExpressTemplateService.java | 3 ++- .../DeliveryExpressTemplateServiceImpl.java | 3 +-- .../bo/SpuDeliveryExpressTemplateRespBO.java | 2 ++ .../price/bo/TradePriceCalculateRespBO.java | 21 ++++++++++--------- .../TradeDeliveryPriceCalculator.java | 6 ++++-- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 341a02c2b..46ee636a5 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -51,8 +51,8 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); - ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); - ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); + ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); // TODO @jaosn:这个错误码,放到 Price 这块 + ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); // TODO @jaosn:这个错误码,放到 Price 这块 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003006, "快递查询接口异常"); ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003007, "快递查询返回失败, 原因:{}"); ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003008, "自提门店不存在"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index e037dbc29..3c438df12 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -75,7 +75,7 @@ public interface DeliveryExpressTemplateService { /** * 校验快递运费模板 - *

+ * * 如果校验不通过,抛出 {@link cn.iocoder.yudao.framework.common.exception.ServiceException} 异常 * * @param templateId 模板编号 @@ -83,6 +83,7 @@ public interface DeliveryExpressTemplateService { */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); + // TODO @jason:可以把 spuIds 改成传递 ids 么?价格计算那,在 TradePriceCalculateRespBO 冗余好 templateId 字段。目的是,减少重复的查询 /** * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index 7aa591388..c7ddc9da6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -242,10 +242,9 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla if (spu == null) { return; } + // TODO @jason:避免循环查询;最好类似 expressTemplateMapper.selectBatchIds(spuMap.keySet()); 批量查询,内存组合; SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() .setChargeMode(item.getChargeMode()) - // TODO @jason:是不是只要查询到一个,就不用查询下一个了;TemplateCharge 和 TemplateFree - // @芋艿 包邮的优先级> 费用的优先级 所以两个都要查询 .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); result.put(spu.getId(), bo); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java index 5fd11f030..82a0274de 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java @@ -18,6 +18,8 @@ public class SpuDeliveryExpressTemplateRespBO { */ private Integer chargeMode; + // TODO @jaosn:可以把 DeliveryExpressTemplateChargeBO 和 DeliveryExpressTemplateFreeBO 搞成内嵌的类。这样简洁一点 + /** * 运费模板快递运费设置 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index 5a6a762a9..8231621bb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -164,16 +164,7 @@ public class TradePriceCalculateRespBO { */ private Integer payPrice; - /** - * 商品重量,单位:kg 千克 - */ - private Double weight; - /** - * 商品体积,单位:m^3 平米 - */ - private Double volume; - - // ========== 商品信息 ========== + // ========== 商品 SPU 信息 ========== /** * 商品名 */ @@ -189,6 +180,16 @@ public class TradePriceCalculateRespBO { */ private Long categoryId; + // ========== 商品 SKU 信息 ========== + /** + * 商品重量,单位:kg 千克 + */ + private Double weight; + /** + * 商品体积,单位:m^3 平米 + */ + private Double volume; + /** * 商品属性数组 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 222acab9e..9f8e6afa7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -62,7 +62,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(spuIds, address.getAreaId()); // 3. 计算配送费用 if (CollUtil.isEmpty(spuExpressTemplateMap)) { - log.error("找不到商品 SPU ID {}, area Id {} ,对应的运费模板", spuIds, address.getAreaId()); + log.error("[calculate][找不到商品 spuId{} areaId{} 对应的运费模板]", spuIds, address.getAreaId()); throw exception(PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND); } calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); @@ -170,7 +170,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { */ private void divideDeliveryPrice(int deliveryPrice, List orderItems) { // TODO @jason:分摊的话,是不是要按照比例呀?重量、价格、数量等等, - // 按比例是不是有点复杂。后面看看是否需要 + // 按比例是不是有点复杂。后面看看是否需要; + // TODO 可以看看别的项目怎么搞的哈。 int dividePrice = deliveryPrice / orderItems.size(); for (OrderItem item : orderItems) { // 更新快递运费 @@ -207,6 +208,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { // freeCount 是不是应该是 double ?? // TODO @jason:要不配置的时候,把它的单位和商品对齐?到底是 kg、还是斤 // TODO @芋艿 目前 包邮 件数/重量/体积 都用的是这个字段 + // TODO @jason:那要不快递模版也改成 kg?这样是不是就不用 double ? if (totalWeight >= templateFree.getFreeCount() && totalPrice >= templateFree.getFreePrice()) { return true; From dcb1660880064f8357955761fb03011e4a976d4c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 12 Jun 2023 00:20:20 +0800 Subject: [PATCH 104/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Acode=20review?= =?UTF-8?q?=20=E5=BF=AB=E9=80=92=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/config/YudaoWebAutoConfiguration.java | 18 +++++------ .../config/TradeExpressQueryProperties.java | 15 ++++++--- .../delivery/core/ExpressQueryClient.java | 3 ++ .../delivery/core/ExpressQueryProvider.java | 2 ++ .../core/ExpressQueryProviderEnum.java | 5 +++ .../core/ExpressQueryProviderFactory.java | 9 ++++-- .../core/convert/ExpressQueryConvert.java | 1 + .../delivery/core/dto/ExpressQueryReqDTO.java | 4 ++- .../core/dto/ExpressQueryRespDTO.java | 4 ++- .../kd100/Kd100ExpressQueryReqDTO.java | 8 +++-- .../kd100/Kd100ExpressQueryRespDTO.java | 8 ++--- .../kdniao/KdNiaoExpressQueryReqDTO.java | 5 +-- .../core/impl/ExpressQueryClientImpl.java | 22 ++++++++++--- .../impl/ExpressQueryProviderFactoryImpl.java | 3 ++ .../core/impl/Kd100ExpressQueryProvider.java | 32 ++++++++++++------- .../core/impl/KdNiaoExpressQueryProvider.java | 18 +++++++---- .../impl/KdNiaoExpressQueryProviderTest.java | 5 +-- 17 files changed, 111 insertions(+), 51 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java index 110eb80bb..e47619df3 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java @@ -110,19 +110,19 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER); } - /** - * 创建 RestTemplate 实例 - * @param restTemplateBuilder {@link RestTemplateAutoConfiguration#restTemplateBuilder} - */ - @Bean - public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){ - return restTemplateBuilder.build(); - } - public static FilterRegistrationBean createFilterBean(T filter, Integer order) { FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); bean.setOrder(order); return bean; } + /** + * 创建 RestTemplate 实例 + * + * @param restTemplateBuilder {@link RestTemplateAutoConfiguration#restTemplateBuilder} + */ + @Bean + public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { + return restTemplateBuilder.build(); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java index 567e34085..be0f93414 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java @@ -9,6 +9,8 @@ import org.springframework.validation.annotation.Validated; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; +// TODO @jason:TradeExpressProperties;更通用哈 +// TODO @芋艿:未来要不要放数据库中?考虑 saas 多租户时,不同租户使用不同的配置? /** * 交易快递查询的配置项 * @@ -21,9 +23,13 @@ import javax.validation.constraints.NotEmpty; public class TradeExpressQueryProperties { /** - * 快递查询服务商, 如果未配置,默认使用快递鸟 + * 快递查询服务商 + * + * 如果未配置,默认使用快递鸟 */ - private ExpressQueryProviderEnum expressQueryProvider; + // TODO @jason:可以把 expressQueryProvider 改成 client 变量,更简洁一点; + private ExpressQueryProviderEnum expressQueryProvider; // TODO @jaosn:默认值可以通过属性直接赋值哈; + // TODO @jason:需要考虑下,用户只配置了其中一个; /** * 快递鸟配置 */ @@ -46,12 +52,12 @@ public class TradeExpressQueryProperties { */ @NotEmpty(message = "快递鸟用户 ID 配置项不能为空") private String businessId; - /** * 快递鸟 API Key */ @NotEmpty(message = "快递鸟 Api Key 配置项不能为空") private String apiKey; + } /** @@ -59,6 +65,7 @@ public class TradeExpressQueryProperties { */ @Data public static class Kd100Config { + /** * 快递 100 授权码 */ @@ -69,7 +76,7 @@ public class TradeExpressQueryProperties { */ @NotEmpty(message = "快递 100 授权 Key 配置项不能为空") private String key; + } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java index d43429d72..1494bb2e5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRes import java.util.List; +// TODO @jason:可以改成 ExpressClient,未来可能还对接别的接口噢 /** * 快递查询客户端 * @@ -17,5 +18,7 @@ public interface ExpressQueryClient { * * @param reqDTO 查询请求参数 */ + // TODO @jason:可以改成 getExpressTrackList。返回字段可以参考 https://doc.youzanyun.com/detail/API/0/5 响应的 data List realTimeQuery(ExpressQueryReqDTO reqDTO); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java index 6fb0a4179..e741e1426 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java @@ -11,10 +11,12 @@ import java.util.List; * @author jason */ public interface ExpressQueryProvider { + /** * 快递实时查询 * * @param reqDTO 查询请求参数 */ List realTimeQueryExpress(ExpressQueryReqDTO reqDTO); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java index 094848ba6..48dab7eec 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java @@ -8,9 +8,12 @@ import lombok.Getter; * @author jason */ @Getter + public enum ExpressQueryProviderEnum { + KD_NIAO("kd-niao", "快递鸟"), KD_100("kd-100", "快递100"); + /** * 快递服务商唯一编码 */ @@ -21,8 +24,10 @@ public enum ExpressQueryProviderEnum { */ private final String name; + // TODO @jaosn:@AllArgsConstructor 可以替代哈 ExpressQueryProviderEnum(String code, String name) { this.code = code; this.name = name; } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java index 87504faa3..bad2c6a5d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java @@ -1,14 +1,19 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core; /** - * 快递服务商工厂, 用于创建和缓存快递服务商服务 + * 快递服务商工厂,用于创建和缓存快递服务商服务 + * * @author jason */ public interface ExpressQueryProviderFactory { /** - * 通过枚举获取快递查询服务商, 如果不存在。就创建一个对应的快递查询服务商 + * 通过枚举获取快递查询服务商 + * + * 如果不存在,就创建一个对应的快递查询服务商 + * * @param queryProviderEnum 快递服务商枚举 */ ExpressQueryProvider getOrCreateExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java index d22f61ae5..615f84b4e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java @@ -23,4 +23,5 @@ public interface ExpressQueryConvert { KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); Kd100ExpressQueryReqDTO convert2(ExpressQueryReqDTO dto); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java index 7315aea07..ffa72c532 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java @@ -14,8 +14,9 @@ public class ExpressQueryReqDTO { /** * 快递公司编码 * - * 对应 {@link DeliveryExpressDO#getCode()} } + * 对应 {@link DeliveryExpressDO#getCode()} */ + // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 private String expressCompanyCode; /** @@ -27,4 +28,5 @@ public class ExpressQueryReqDTO { * 收、寄件人的电话号码 */ private String phone; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java index feb06ea96..0bdb386c4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java @@ -10,13 +10,15 @@ import lombok.Data; @Data public class ExpressQueryRespDTO { + // TODO @jason:LocalDateTime /** * 发生时间 */ private String time; - + // TODO @jason:其它字段可能要补充下 /** * 快递状态 */ private String state; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java index e2d55db34..d1b72426f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java @@ -13,6 +13,7 @@ import lombok.Data; @JsonInclude(JsonInclude.Include.NON_NULL) public class Kd100ExpressQueryReqDTO { + // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 /** * 快递公司编码 */ @@ -29,19 +30,20 @@ public class Kd100ExpressQueryReqDTO { * 收、寄件人的电话号码 */ private String phone; - /** * 出发地城市 */ private String from; - /** * 目的地城市,到达目的地后会加大监控频率 */ private String to; /** - * 返回结果排序:desc降序(默认),asc 升序 + * 返回结果排序 + * + * desc 降序(默认), asc 升序 */ private String order; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java index 49be06234..f7e5bdf04 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java @@ -18,23 +18,22 @@ public class Kd100ExpressQueryRespDTO { */ @JsonProperty("com") private String expressCompanyCode; - /** * 快递单号 */ @JsonProperty("nu") private String logisticsNo; - /** * 快递单当前状态 */ private String state; /** - * 查询结果, 失败返回 "false" + * 查询结果 + * + * 失败返回 "false" */ private String result; - /** * 查询结果失败时的错误信息 */ @@ -56,4 +55,5 @@ public class Kd100ExpressQueryRespDTO { @JsonProperty("context") private String state; } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java index 3f0faae49..21b1abc58 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java @@ -12,21 +12,22 @@ import lombok.Data; @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class KdNiaoExpressQueryReqDTO { + + // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 /** * 快递公司编码 */ @JsonProperty("ShipperCode") private String expressCompanyCode; - /** * 快递单号 */ @JsonProperty("LogisticCode") private String logisticsNo; - /** * 订单编号 */ @JsonProperty("OrderCode") private String orderNo; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java index cbf29cd4e..59dfc77c1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java @@ -17,6 +17,15 @@ import java.util.List; import static cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum.KD_NIAO; +// TODO @jason:可以把整体包结构调整下;参考 sms client 的方式; +// + config +// + core +// client +// + dto +// + impl:里面可以放 kdniaoclient、kd100client +// ExpressClient +// ExpressClientFactory: 通过它直接获取默认和创建默认的 Client +// enums /** * 快递查询客户端实现 * @@ -24,30 +33,33 @@ import static cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQuery */ @Component @Slf4j -public class ExpressQueryClientImpl implements ExpressQueryClient { +public class ExpressQueryClientImpl implements ExpressQueryClient { + @Resource private ExpressQueryProviderFactory expressQueryProviderFactory; @Resource private TradeExpressQueryProperties tradeExpressQueryProperties; private ExpressQueryProvider expressQueryProvider; + @PostConstruct - private void init(){ + private void init() { + // 如果未设置,默认使用快递鸟 ExpressQueryProviderEnum queryProvider = tradeExpressQueryProperties.getExpressQueryProvider(); if (queryProvider == null) { - // 如果未设置,默认使用快递鸟 queryProvider = KD_NIAO; } + // 创建客户端 expressQueryProvider = expressQueryProviderFactory.getOrCreateExpressQueryProvider(queryProvider); if (expressQueryProvider == null) { - // 记录错误日志 log.error("获取创建快递查询服务商{}失败,请检查相关配置", queryProvider); } Assert.notNull(expressQueryProvider, "快递查询服务商不能为空"); - } + @Override public List realTimeQuery(ExpressQueryReqDTO reqDTO) { return expressQueryProvider.realTimeQueryExpress(reqDTO); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java index 3060cb21c..b6ce8d68a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java @@ -12,12 +12,14 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** + * // TODO @jason:注释不全 * @author jason */ @Component public class ExpressQueryProviderFactoryImpl implements ExpressQueryProviderFactory { private final Map providerMap = new ConcurrentHashMap<>(8); + @Resource private TradeExpressQueryProperties tradeExpressQueryProperties; @Resource @@ -31,6 +33,7 @@ public class ExpressQueryProviderFactoryImpl implements ExpressQueryProviderFact private ExpressQueryProvider createExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum, TradeExpressQueryProperties tradeExpressQueryProperties) { + // TODO @jason:是不是直接 return 就好啦,更简洁一点 ExpressQueryProvider result = null; switch (queryProviderEnum) { case KD_NIAO: diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java index 07a51d0c9..4227cebc8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java @@ -21,10 +21,11 @@ import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_ERROR; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; +// TODO @jason:可以参考 KdNiaoExpressQueryProvider 建议改改哈 /** * 快递 100 服务商 * @@ -34,8 +35,8 @@ import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.Expr public class Kd100ExpressQueryProvider implements ExpressQueryProvider { private static final String REAL_TIME_QUERY_URL = "https://poll.kuaidi100.com/poll/query.do"; - private final RestTemplate restTemplate; + private final RestTemplate restTemplate; private final TradeExpressQueryProperties.Kd100Config config; public Kd100ExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.Kd100Config config) { @@ -45,16 +46,19 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { @Override public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { + // 发起查询 Kd100ExpressQueryReqDTO kd100ReqParam = INSTANCE.convert2(reqDTO); - // 快递公司编码需要转成小写 - kd100ReqParam.setExpressCompanyCode(kd100ReqParam.getExpressCompanyCode().toLowerCase()); + kd100ReqParam.setExpressCompanyCode(kd100ReqParam.getExpressCompanyCode().toLowerCase()); // 快递公司编码需要转成小写 Kd100ExpressQueryRespDTO respDTO = sendExpressQueryReq(REAL_TIME_QUERY_URL, kd100ReqParam, Kd100ExpressQueryRespDTO.class); - log.debug("快递 100 接口 查询接口返回 {}", respDTO); + log.debug("[realTimeQueryExpress][快递 100 接口 查询接口返回 {}]", respDTO); + // 处理结果 if (Objects.equals("false", respDTO.getResult())) { - log.error("快递 100 接口 返回失败 {} ", respDTO.getMessage()); + log.error("[realTimeQueryExpress][快递 100 接口 返回失败 {}]", respDTO.getMessage()); throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage()); + // TODO @json:else 可以不用写哈; } else { + // TODO @jason:convertList2 如果空,应该返回 list 了; if (CollUtil.isNotEmpty(respDTO.getTracks())) { return INSTANCE.convertList2(respDTO.getTracks()); } else { @@ -65,12 +69,14 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { /** * 发送快递 100 实时快递查询请求,可以作为通用快递 100 通用请求接口。 目前没有其它场景需要使用。暂时放这里 + * * @param url 请求 url * @param req 对应请求的请求参数 * @param respClass 对应请求的响应 class * @param 每个请求的请求结构 Req DTO * @param 每个请求的响应结构 Resp DTO */ + // TODO @jason:可以改成 request,发起请求哈; private Resp sendExpressQueryReq(String url, Req req, Class respClass) { // 请求头 HttpHeaders headers = new HttpHeaders(); @@ -78,19 +84,20 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { // 生成签名 String param = JsonUtils.toJsonString(req); String sign = generateReqSign(param, config.getKey(), config.getCustomer()); - log.debug("快递 100 快递 接口生成签名的: {}", sign); // 请求体 MultiValueMap requestBody = new LinkedMultiValueMap<>(); requestBody.add("customer", config.getCustomer()); requestBody.add("sign", sign); requestBody.add("param", param); - log.debug("快递 100 接口的请求参数: {}", requestBody); - - HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + log.debug("[sendExpressQueryReq][快递 100 接口的请求参数: {}]", requestBody); // 发送请求 + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + // TODO @jason:可以使用 restTemplate 的 post 方法哇? ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); - log.debug("快递 100 接口响应结果 {}", responseEntity); + log.debug("[sendExpressQueryReq][快递 100 接口响应结果 {}]", responseEntity); + // 处理响应 + // TODO @jason:if return 原则;if (!responseEntity.getStatusCode().is2xxSuccessful()) 抛出异常;接着处理成功的 if (responseEntity.getStatusCode().is2xxSuccessful()) { String response = responseEntity.getBody(); return JsonUtils.parseObject(response, respClass); @@ -101,7 +108,8 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { private String generateReqSign(String param, String key, String customer) { String plainText = String.format("%s%s%s", param, key, customer); - log.debug("快递 100 接口待签名的数据 {}", plainText); + // TODO @jason:DigestUtil.md5Hex(plainText); return HexUtil.encodeHexStr(DigestUtil.md5(plainText), false); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java index b911892cd..4ca5f6142 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java @@ -32,21 +32,27 @@ import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.Expr */ @Slf4j public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { + private static final String REAL_TIME_QUERY_URL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"; + /** * 快递鸟即时查询免费版 RequestType */ private static final String REAL_TIME_FREE_REQ_TYPE = "1002"; + private final RestTemplate restTemplate; private final TradeExpressQueryProperties.KdNiaoConfig config; + // TODO @jason:可以改成 lombok 哈 public KdNiaoExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.KdNiaoConfig config) { this.restTemplate = restTemplate; this.config = config; } /** - * 快递鸟即时查询免费版本 参见 快递鸟接口文档 + * 快递鸟即时查询免费版本 + * + * @see 快递鸟接口文档 * @param reqDTO 查询请求参数 */ @Override @@ -56,7 +62,7 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { kdNiaoReqData.setExpressCompanyCode(reqDTO.getExpressCompanyCode().toUpperCase()); KdNiaoExpressQueryRespDTO respDTO = sendKdNiaoApiRequest(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, kdNiaoReqData, KdNiaoExpressQueryRespDTO.class); - log.debug("快递鸟即时查询接口返回 {}", respDTO); + log.debug("[realTimeQueryExpress][快递鸟即时查询接口返回 {}]", respDTO); if(!respDTO.getSuccess()){ throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getReason()); }else{ @@ -85,16 +91,16 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { // 请求体 String reqData = JsonUtils.toJsonString(req); String dataSign = generateDataSign(reqData, config.getApiKey()); - log.trace("得到快递鸟接口 RequestType : {} 的 签名: {}", requestType, dataSign); MultiValueMap requestBody = new LinkedMultiValueMap<>(); requestBody.add("RequestData", reqData); requestBody.add("DataType", "2"); requestBody.add("EBusinessID", config.getBusinessId()); requestBody.add("DataSign", dataSign); requestBody.add("RequestType", requestType); - log.debug("快递鸟接口 RequestType : {}, 的请求参数 {}", requestType, requestBody); - HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + log.debug("[sendKdNiaoApiRequest][快递鸟接口 RequestType : {}, 的请求参数 {}]", requestType, requestBody); + // 发送请求 + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); log.debug("快递鸟接口 RequestType : {}, 的响应结果 {}", requestType, responseEntity); // 处理响应 @@ -113,7 +119,7 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { */ private String generateDataSign(String reqData, String apiKey) { String plainText = String.format("%s%s", reqData, apiKey); - log.trace("签名前的数据 {}", plainText); return URLEncodeUtil.encode(Base64.encode(DigestUtil.md5Hex(plainText))); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java index cdde6c683..8f6615678 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java @@ -17,11 +17,12 @@ import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.assertThrows; +// TODO @芋艿:单测最后 review /** * @author jason */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressQueryProviderTest.Application.class) -@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 +@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 TODO @jason:可以直接写到 application-unit-test.yaml 配置文件里 public class KdNiaoExpressQueryProviderTest { @Resource private RestTemplateBuilder builder; @@ -51,4 +52,4 @@ public class KdNiaoExpressQueryProviderTest { @EnableConfigurationProperties(TradeExpressQueryProperties.class) public static class Application { } -} \ No newline at end of file +} From 20100aa78b95cd976ec8180a1a26d9ad1eca6d1c Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 12 Jun 2023 12:08:55 +0800 Subject: [PATCH 105/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=E5=95=86?= =?UTF-8?q?=E5=93=81=E8=AF=84=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/comment/ProductCommentApi.java | 21 +++ .../api/comment/dto/CommentCreateReqDTO.java | 80 ++++++++++ .../api/comment/ProductCommentApiImpl.java | 28 ++++ .../comment/ProductCommentController.java | 8 +- .../comment/vo/ProductCommentBaseVO.java | 20 ++- .../comment/vo/ProductCommentCreateReqVO.java | 14 +- .../comment/vo/ProductCommentPageReqVO.java | 4 +- .../comment/vo/ProductCommentRespVO.java | 2 +- .../app/comment/AppCommentController.java | 60 -------- .../comment/AppProductCommentController.java | 52 +++++++ .../app/comment/vo/AppCommentPageReqVO.java | 36 +---- .../vo/AppCommentStatisticsRespVO.java | 29 ++++ ...seVO.java => AppProductCommentBaseVO.java} | 24 +-- ...java => AppProductCommentCreateReqVO.java} | 10 +- ...spVO.java => AppProductCommentRespVO.java} | 27 ++-- .../app/spu/AppProductSpuController.java | 3 - .../comment/ProductCommentConvert.java | 78 +++++----- .../dataobject/comment/ProductCommentDO.java | 5 + .../mysql/comment/ProductCommentMapper.java | 8 +- .../comment/ProductCommentService.java | 29 ++-- .../comment/ProductCommentServiceImpl.java | 141 +++++++++--------- .../ProductCommentServiceImplTest.java | 44 ++---- .../module/trade/api/order/TradeOrderApi.java | 11 +- .../trade/api/order/TradeOrderApiImpl.java | 16 +- .../app/order/AppTradeOrderController.java | 22 ++- .../AppTradeOrderItemCommentCreateReqVO.java | 71 +++++++++ .../convert/order/TradeOrderConvert.java | 19 ++- 27 files changed, 536 insertions(+), 326 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java rename yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/{AppCommentBaseVO.java => AppProductCommentBaseVO.java} (76%) rename yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/{AppCommentCreateReqVO.java => AppProductCommentCreateReqVO.java} (68%) rename yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/{AppCommentRespVO.java => AppProductCommentRespVO.java} (59%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java new file mode 100644 index 000000000..2daf87d0e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.product.api.comment; + +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; + +/** + * 产品评论 API 接口 + * + * @author HUIHUI + */ +public interface ProductCommentApi { + + /** + * 创建评论 + * + * @param createReqDTO 评论参数 + * @param orderId 订单 id + * @return 返回评论创建后的 id + */ + Long createComment(CommentCreateReqDTO createReqDTO, Long orderId); + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java new file mode 100644 index 000000000..640d04784 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.product.api.comment.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 评论创建请求 DTO + * + * @author HUIHUI + */ +@Data +public class CommentCreateReqDTO { + + /** + * 是否匿名 + */ + private Boolean anonymous; + + /** + * 交易订单项编号 + */ + private Long orderItemId; + + /** + * 商品 SPU 编号 + */ + private Long spuId; + + /** + * 商品 SPU 名称 + */ + private String spuName; + + /** + * 商品 SKU 编号 + */ + private Long skuId; + + /** + * 评分星级 1-5 分 + */ + private Integer scores; + + /** + * 描述星级 1-5 分 + */ + private Integer descriptionScores; + + /** + * 服务星级 1-5 分 + */ + private Integer benefitScores; + + /** + * 评论内容 + */ + private String content; + + /** + * 评论图片地址数组,以逗号分隔最多上传9张 + */ + private List picUrls; + + /** + * 评价人名称 + */ + private String userNickname; + + /** + * 评价人头像 + */ + private String userAvatar; + + /** + * 评价人 + */ + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java new file mode 100644 index 000000000..cd1145c66 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.product.api.comment; + +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 商品评论 API 实现类 + * + * @author HUIHUI + */ +@Service +@Validated +public class ProductCommentApiImpl implements ProductCommentApi { + @Resource + private ProductCommentService productCommentService; + + @Override + public Long createComment(CommentCreateReqDTO createReqDTO, Long orderId) { + ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId); + return productCommentService.createComment(commentDO); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index fb8f8fe34..6a8b12778 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -35,8 +35,7 @@ public class ProductCommentController { return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); } - // TODO @puhui999:update-visible - @PutMapping("/update/visible") + @PutMapping("/update-visible") @Operation(summary = "显示 / 隐藏评论") @PreAuthorize("@ss.hasPermission('product:comment:update')") public CommonResult updateCommentVisible(@Valid @RequestBody ProductCommentUpdateVisibleReqVO updateReqVO) { @@ -48,7 +47,7 @@ public class ProductCommentController { @Operation(summary = "商家回复") @PreAuthorize("@ss.hasPermission('product:comment:update')") public CommonResult commentReply(@Valid @RequestBody ProductCommentReplyVO replyVO) { - productCommentService.commentReply(replyVO, getLoginUserId()); + productCommentService.replyComment(replyVO, getLoginUserId()); return success(true); } @@ -56,8 +55,7 @@ public class ProductCommentController { @Operation(summary = "添加自评") @PreAuthorize("@ss.hasPermission('product:comment:update')") public CommonResult createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) { - // TODO @puhui999:不用 ProductCommentConvert.INSTANCE.convert(createReqVO) 哈;多写一个 create 方法即可; - productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE); + productCommentService.createComment(createReqVO); return success(true); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java index 775801bbc..b934298b7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java @@ -10,17 +10,15 @@ import java.util.List; @Data public class ProductCommentBaseVO { - // TODO @puhui999:把 example 补充下 - - @Schema(description = "评价人名称", required = true, example = "张三") + @Schema(description = "评价人名称", required = true, example = "小姑凉") @NotNull(message = "评价人名称不能为空") private String userNickname; - @Schema(description = "评价人头像", required = true) + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "评价人头像不能为空") private String userAvatar; - @Schema(description = "商品 SPU 编号", required = true, example = "29502") + @Schema(description = "商品 SPU 编号", required = true, example = "清凉丝滑透气小短袖") @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; @@ -28,27 +26,27 @@ public class ProductCommentBaseVO { @NotNull(message = "商品 SPU 名称不能为空") private String spuName; - @Schema(description = "商品 SKU 编号", required = true, example = "3082") + @Schema(description = "商品 SKU 编号", required = true, example = "1") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @Schema(description = "评分星级 1-5分", required = true) + @Schema(description = "评分星级 1-5分", required = true, example = "5") @NotNull(message = "评分星级不能为空") private Integer scores; - @Schema(description = "描述星级 1-5分", required = true) + @Schema(description = "描述星级 1-5分", required = true, example = "5") @NotNull(message = "描述星级不能为空") private Integer descriptionScores; - @Schema(description = "服务星级 1-5分", required = true) + @Schema(description = "服务星级 1-5分", required = true, example = "5") @NotNull(message = "服务星级分不能为空") private Integer benefitScores; - @Schema(description = "评论内容", required = true) + @Schema(description = "评论内容", required = true, example = "穿起来非常丝滑凉快") @NotNull(message = "评论内容不能为空") private String content; - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") @Size(max = 9, message = "评论图片地址数组长度不能超过9张") private List picUrls; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java index 8fd0e7099..1d325e03d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; -import lombok.*; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; @Schema(description = "管理后台 - 商品评价创建 Request VO") @Data @@ -9,4 +13,12 @@ import io.swagger.v3.oas.annotations.media.Schema; @ToString(callSuper = true) public class ProductCommentCreateReqVO extends ProductCommentBaseVO { + @Schema(description = "评价人", required = true, example = "16868") + @NotNull(message = "评价人不能为空") + private Long userId; + + @Schema(description = "评价订单项", required = true, example = "19292") + @NotNull(message = "评价订单项不能为空") + private Long orderItemId; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java index 5a90d1c20..f7da9b5d9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java @@ -31,11 +31,11 @@ public class ProductCommentPageReqVO extends PageParam { @Schema(description = "商品SPU名称", example = "感冒药") private String spuName; - @Schema(description = "评分星级 1-5分") + @Schema(description = "评分星级 1-5分", example = "5") @InEnum(ProductCommentScoresEnum.class) private Integer scores; - @Schema(description = "商家是否回复") + @Schema(description = "商家是否回复", example = "true") private Boolean replied; @Schema(description = "创建时间") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index 400630afd..c9a06d476 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -16,7 +16,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "订单项编号", required = true, example = "24965") private Long id; - @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true) + @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true, example = "false") private Boolean anonymous; @Schema(description = "交易订单编号", required = true, example = "24428") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java deleted file mode 100644 index 7d05161e7..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java +++ /dev/null @@ -1,60 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.comment; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; -import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; -import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -// TODO @puhui999:AppCommentController =》 AppProductCommentController -@Tag(name = "用户 APP - 商品评价") -@RestController -@RequestMapping("/product/comment") -@Validated -public class AppCommentController { - - @Resource - private ProductCommentService productCommentService; - - @Resource - private MemberUserApi memberUserApi; - - @GetMapping("/page") - @Operation(summary = "获得商品评价分页") - public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { - return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); - } - - // TODO @puhui999:方法名改成 getCommentStatistics?然后搞个对应的 vo?想了下,这样更优雅 - @GetMapping("/get-count") - @Operation(summary = "获得商品的评价统计") // TODO @puhui999:@RequestParam 哈,针对 spuId - public CommonResult> getCommentPage(@Valid Long spuId) { - return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); - } - - @PostMapping(value = "/create") - @Operation(summary = "创建商品评价") - public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { - // TODO: 2023/3/20 要不要判断订单、商品是否存在 - // TODO @ouhui999:这个接口,搞到交易那比较合适; - MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); - productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); - return success(true); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java new file mode 100644 index 000000000..6921e6cbf --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.product.controller.app.comment; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 商品评价") +@RestController +@RequestMapping("/product/comment") +@Validated +public class AppProductCommentController { + + @Resource + private ProductCommentService productCommentService; + + @GetMapping("/page") + @Operation(summary = "获得商品评价分页") + public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { + PageResult result = productCommentService.getCommentPage(pageVO, Boolean.TRUE); + result.getList().forEach(item -> { + // 判断用户是否选择匿名 + if (ObjectUtil.equal(item.getAnonymous(), true)) { + item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); + } + }); + return success(result); + } + + @GetMapping("/getCommentStatistics") + @Operation(summary = "获得商品的评价统计") + public CommonResult getCommentPage(@Valid @RequestParam("spuId") Long spuId) { + return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index d2bf4ef99..8799c5c75 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -14,55 +14,21 @@ import javax.validation.constraints.NotNull; @ToString(callSuper = true) public class AppCommentPageReqVO extends PageParam { - // TODO @puhui999:不传递就是 all; - /** - * 所有 - */ - public static final Integer ALL = 0; - - /** - * 所有数量 key - */ - public static final String ALL_COUNT = "allCount"; - - // TODO @puhui999:good 好评; /** * 好评 */ - public static final Integer FAVOURABLE_COMMENT = 1; - - // TODO @puhui999:medium 中评;然后 mediumCount 就好啦; - /** - * 好评数量 key - */ - public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount"; + public static final Integer GOOD_COMMENT = 1; /** * 中评 */ public static final Integer MEDIOCRE_COMMENT = 2; - /** - * 中评数量 key - */ - public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount"; - /** * 差评 */ public static final Integer NEGATIVE_COMMENT = 3; - /** - * 差评数量 key - */ - public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; - - // TODO @puhui999:这个挪到 DO 那没问题的哈;NICKNAME_ANONYMOUS - /** - * 默认匿名昵称 - */ - public static final String ANONYMOUS_NICKNAME = "匿名用户"; - @Schema(description = "商品SPU编号", example = "29502") @NotNull(message = "商品SPU编号不能为空") private Long spuId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java new file mode 100644 index 000000000..0687e5eea --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +/** + * APP 商品评价页评论分类数统计 Response VO + * + * @author HUIHUI + */ +@Schema(description = "APP - 商品评价页评论分类数统计 Response VO") +@Data +@ToString(callSuper = true) +public class AppCommentStatisticsRespVO { + + @Schema(description = "所有评论数量", required = true, example = "15721") + private Long allCount; + + @Schema(description = "好评数量", required = true, example = "15721") + private Long goodCount; + + @Schema(description = "中评数量", required = true, example = "15721") + private Long mediocreCount; + + @Schema(description = "差评数量", required = true, example = "15721") + private Long negativeCount; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java similarity index 76% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java index 2cbefad01..7173844ec 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java @@ -7,39 +7,43 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.List; -// TODO @puhui999:把 Product 前缀给补下哈 +/** + * 商品评论 Base VO + * + * @author HUIHUI + */ @Data -public class AppCommentBaseVO { +public class AppProductCommentBaseVO { - @Schema(description = "商品SPU编号", required = true, example = "29502") + @Schema(description = "商品SPU编号", required = true, example = "91192") @NotNull(message = "商品SPU编号不能为空") private Long spuId; - @Schema(description = "商品SPU名称", required = true, example = "赵六") + @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖") @NotNull(message = "商品SPU名称不能为空") private String spuName; - @Schema(description = "商品SKU编号", required = true, example = "3082") + @Schema(description = "商品SKU编号", required = true, example = "81192") @NotNull(message = "商品SKU编号不能为空") private Long skuId; - @Schema(description = "评分星级 1-5分", required = true) + @Schema(description = "评分星级 1-5分", required = true, example = "5") @NotNull(message = "评分星级 1-5分不能为空") private Integer scores; - @Schema(description = "描述星级 1-5分", required = true) + @Schema(description = "描述星级 1-5分", required = true, example = "5") @NotNull(message = "描述星级 1-5分不能为空") private Integer descriptionScores; - @Schema(description = "服务星级 1-5分", required = true) + @Schema(description = "服务星级 1-5分", required = true, example = "5") @NotNull(message = "服务星级 1-5分不能为空") private Integer benefitScores; - @Schema(description = "评论内容", required = true) + @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") @NotNull(message = "评论内容不能为空") private String content; - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") @Size(max = 9, message = "评论图片地址数组长度不能超过9张") private List picUrls; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java similarity index 68% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java index 6eb8e89e3..42cdc7e5b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java @@ -7,23 +7,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -// TODO @puhui999:不应该继承 AppCommentCreateReqVO +// TODO @puhui999:不应该继承 AppProductCommentCreateReqVO @Schema(description = "用户APP - 商品评价创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class AppCommentCreateReqVO extends AppCommentBaseVO { +public class AppProductCommentCreateReqVO extends AppProductCommentBaseVO { @Schema(description = "是否匿名", required = true, example = "true") @NotNull(message = "是否匿名不能为空") private Boolean anonymous; - // TODO @puhui999:不应该传递 orderId - - @Schema(description = "交易订单编号", required = true, example = "12312") - @NotNull(message = "交易订单编号不能为空") - private Long orderId; - @Schema(description = "交易订单项编号", required = true, example = "2312312") @NotNull(message = "交易订单项编号不能为空") private Long orderItemId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java similarity index 59% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java index 77c419b96..43a4096b0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java @@ -4,17 +4,18 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + @Schema(description = "用户APP - 商品评价 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class AppCommentRespVO extends AppCommentBaseVO { - - // TODO puhui999:把 example 也补充下哈 +public class AppProductCommentRespVO extends AppProductCommentBaseVO { @Schema(description = "评价人的用户编号", required = true, example = "15721") private Long userId; @@ -22,13 +23,13 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "评价人名称", required = true, example = "张三") private String userNickname; - @Schema(description = "评价人头像", required = true) + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png") private String userAvatar; @Schema(description = "订单项编号", required = true, example = "24965") private Long id; - @Schema(description = "是否匿名", required = true) + @Schema(description = "是否匿名", required = true, example = "false") private Boolean anonymous; @Schema(description = "交易订单编号", required = true, example = "24428") @@ -37,31 +38,31 @@ public class AppCommentRespVO extends AppCommentBaseVO { @Schema(description = "交易订单项编号", required = true, example = "8233") private Long orderItemId; - @Schema(description = "商家是否回复", required = true) + @Schema(description = "商家是否回复", required = true, example = "true") private Boolean replyStatus; @Schema(description = "回复管理员编号", example = "22212") private Long replyUserId; - @Schema(description = "商家回复内容") + @Schema(description = "商家回复内容", example = "亲,你的好评就是我的动力(*^▽^*)") private String replyContent; @Schema(description = "商家回复时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime replyTime; - @Schema(description = "追加评价内容") + @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶") private String additionalContent; - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") private List additionalPicUrls; @Schema(description = "追加评价时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime additionalTime; - @Schema(description = "创建时间", required = true) + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; - @Schema(description = "最终评分", required = true) - private Integer finalScore; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 693e8e911..3f3008176 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; @@ -40,8 +39,6 @@ public class AppProductSpuController { private ProductSpuService productSpuService; @Resource private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index 77f208214..ff895f491 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,15 +1,19 @@ package cn.iocoder.yudao.module.product.convert.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; /** @@ -24,50 +28,42 @@ public interface ProductCommentConvert { ProductCommentRespVO convert(ProductCommentDO bean); + @Mapping(target = "allCount", source = "allCount") + @Mapping(target = "goodCount", source = "goodCount") + @Mapping(target = "mediocreCount", source = "mediocreCount") + @Mapping(target = "negativeCount", source = "negativeCount") + AppCommentStatisticsRespVO convert(Long allCount, Long goodCount, Long mediocreCount, Long negativeCount); + List convertList(List list); PageResult convertPage(PageResult page); - PageResult convertPage02(PageResult pageResult); + PageResult convertPage02(PageResult pageResult); - // TODO @puhui999:用 mapstruct 的映射 - default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) { - ProductCommentDO productComment = new ProductCommentDO(); - productComment.setUserId(user.getId()); - productComment.setUserNickname(user.getNickname()); - productComment.setUserAvatar(user.getAvatar()); - productComment.setAnonymous(createReqVO.getAnonymous()); - productComment.setOrderId(createReqVO.getOrderId()); - productComment.setOrderItemId(createReqVO.getOrderItemId()); - productComment.setSpuId(createReqVO.getSpuId()); - productComment.setSpuName(createReqVO.getSpuName()); - productComment.setSkuId(createReqVO.getSkuId()); - productComment.setScores(createReqVO.getScores()); - productComment.setDescriptionScores(createReqVO.getDescriptionScores()); - productComment.setBenefitScores(createReqVO.getBenefitScores()); - productComment.setContent(createReqVO.getContent()); - productComment.setPicUrls(createReqVO.getPicUrls()); - return productComment; + /** + * 计算综合评分 + * + * @param descriptionScores 描述星级 + * @param benefitScores 服务星级 + * @return {@link Integer} + */ + @Named("convertScores") + default Integer convertScores(Integer descriptionScores, Integer benefitScores) { + // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 + BigDecimal sumScore = new BigDecimal(descriptionScores + benefitScores); + BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN); + return divide.intValue(); } - // TODO @puhui999:用 mapstruct 的映射 - default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { - ProductCommentDO productComment = new ProductCommentDO(); - productComment.setUserId(0L); - productComment.setUserNickname(createReq.getUserNickname()); - productComment.setUserAvatar(createReq.getUserAvatar()); - productComment.setAnonymous(Boolean.FALSE); - productComment.setOrderId(0L); - productComment.setOrderItemId(0L); - productComment.setSpuId(createReq.getSpuId()); - productComment.setSpuName(createReq.getSpuName()); - productComment.setSkuId(createReq.getSkuId()); - productComment.setScores(createReq.getScores()); - productComment.setDescriptionScores(createReq.getDescriptionScores()); - productComment.setBenefitScores(createReq.getBenefitScores()); - productComment.setContent(createReq.getContent()); - productComment.setPicUrls(createReq.getPicUrls()); - return productComment; - } + @Mapping(target = "orderId", source = "orderId") + @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") + ProductCommentDO convert(CommentCreateReqDTO createReqDTO, Long orderId); + + @Mapping(target = "userId", constant = "0L") + @Mapping(target = "orderId", constant = "0L") + @Mapping(target = "orderItemId", constant = "0L") + @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)") + @Mapping(target = "scores", expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))") + ProductCommentDO convert(ProductCommentCreateReqVO createReq); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index cf7b47051..07e8fa5b6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -28,6 +28,11 @@ import java.util.List; @AllArgsConstructor public class ProductCommentDO extends BaseDO { + /** + * 默认匿名昵称 + */ + public static final String NICKNAME_ANONYMOUS = "匿名用户"; + /** * 评论编号,主键自增 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index 796a790f4..13c0f47f7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -31,7 +31,7 @@ public interface ProductCommentMapper extends BaseMapperX { // TODO 芋艿:在看看这块 static void appendTabQuery(LambdaQueryWrapperX queryWrapper, Integer type) { // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8 - if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) { + if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) { queryWrapper.apply("(scores + benefit_scores) >= 8"); } // 构建中评查询语句:中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8 @@ -72,16 +72,14 @@ public interface ProductCommentMapper extends BaseMapperX { update(null, lambdaUpdateWrapper); } - // TODO @puhui999:使用 select 替代 find - default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { + default ProductCommentDO selectByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { return selectOne(new LambdaQueryWrapperX() .eq(ProductCommentDO::getUserId, userId) .eq(ProductCommentDO::getOrderId, orderId) .eq(ProductCommentDO::getSpuId, spuId)); } - // TODO @puhui999:selectCountBySpuId 即可 - default Long selectTabCount(Long spuId, Boolean visible, Integer type) { + default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) { LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() .eqIfPresent(ProductCommentDO::getSpuId, spuId) .eqIfPresent(ProductCommentDO::getVisible, visible); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 7bf9ccb36..10592f7b9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -1,17 +1,17 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.util.Map; - /** * 商品评论 Service 接口 * @@ -37,13 +37,14 @@ public interface ProductCommentService { void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO); // TODO @puhui999:replyComment + /** * 商家回复 * * @param replyVO 商家回复 * @param loginUserId 管理后台商家登陆人 ID */ - void commentReply(ProductCommentReplyVO replyVO, Long loginUserId); + void replyComment(ProductCommentReplyVO replyVO, Long loginUserId); /** * 获得商品评价分页 @@ -52,15 +53,23 @@ public interface ProductCommentService { * @param visible 是否可见 * @return 商品评价分页 */ - PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); + PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); /** - * 创建商品评论 + * 创建商品评论 后台管理员创建评论使用 * - * @param productComment 创建实体 - * @param system 是否系统评价 + * @param createReqVO 商品评价创建 Request VO 对象 */ - void createComment(ProductCommentDO productComment, Boolean system); + void createComment(ProductCommentCreateReqVO createReqVO); + + /** + * 创建评论 + * 创建商品评论 APP 端创建商品评论使用 + * + * @param commentDO 评论对象 + * @return 返回评论 id + */ + Long createComment(ProductCommentDO commentDO); /** * 获得商品的评价统计 @@ -69,6 +78,6 @@ public interface ProductCommentService { * @param visible 是否可见 * @return 评价统计 */ - Map getCommentPageTabsCount(Long spuId, Boolean visible); + AppCommentStatisticsRespVO getCommentPageTabsCount(Long spuId, Boolean visible); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 1f1156e1c..6dc67beb8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,31 +1,28 @@ package cn.iocoder.yudao.module.product.service.comment; -import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.HashMap; -import java.util.Map; +import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; /** * 商品评论 Service 实现类 @@ -46,94 +43,96 @@ public class ProductCommentServiceImpl implements ProductCommentService { private ProductSpuService productSpuService; @Override - public PageResult getCommentPage(ProductCommentPageReqVO pageReqVO) { - return productCommentMapper.selectPage(pageReqVO); - } - - @Override + @Transactional(rollbackFor = Exception.class) public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { // 校验评论是否存在 - validateCommentExists(updateReqVO.getId()); + ProductCommentDO productCommentDO = validateCommentExists(updateReqVO.getId()); + productCommentDO.setVisible(updateReqVO.getVisible()); // 更新可见状态 - // TODO @puhui999:直接使用 update 操作 - productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible()); + productCommentMapper.updateById(productCommentDO); } @Override - public void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { + @Transactional(rollbackFor = Exception.class) + public void replyComment(ProductCommentReplyVO replyVO, Long loginUserId) { // 校验评论是否存在 - validateCommentExists(replyVO.getId()); + ProductCommentDO productCommentDO = validateCommentExists(replyVO.getId()); + productCommentDO.setReplyTime(LocalDateTime.now()); + productCommentDO.setReplyUserId(loginUserId); + productCommentDO.setReplyStatus(Boolean.TRUE); + productCommentDO.setReplyContent(replyVO.getReplyContent()); // 回复评论 - // TODO @puhui999:直接使用 update 操作 - productCommentMapper.commentReply(replyVO, loginUserId); + productCommentMapper.updateById(productCommentDO); } @Override - public Map getCommentPageTabsCount(Long spuId, Boolean visible) { - Map countMap = new HashMap<>(4); - // 查询商品 id = spuId 的所有评论数量 - countMap.put(AppCommentPageReqVO.ALL_COUNT, - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL)); - // 查询商品 id = spuId 的所有好评数量 - countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT, - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT)); - // 查询商品 id = spuId 的所有中评数量 - countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT, - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT)); - // 查询商品 id = spuId 的所有差评数量 - countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT, - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)); - return countMap; + @Transactional(rollbackFor = Exception.class) + public void createComment(ProductCommentCreateReqVO createReqVO) { + // 校验订单 + Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId()); + // 校验评论 + validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId); + + ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO); + productCommentMapper.insert(commentDO); } @Override - public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { - // TODO @puhui999:逻辑可以在 controller 做哈。让 service 简介一点;因为是 view 需要不展示昵称 - PageResult result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); - result.getList().forEach(item -> { - // 判断用户是否选择匿名 - if (ObjectUtil.equal(item.getAnonymous(), true)) { - item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME); - } - // TODO @puhui999:直接插入的时候,计算到 scores 字段里;这样就去掉 finalScore 字段哈 - // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 - BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores()); - BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN); - item.setFinalScore(divide.intValue()); - }); - return result; + @Transactional(rollbackFor = Exception.class) + public Long createComment(ProductCommentDO commentDO) { + // 校验评论 + validateComment(commentDO.getSpuId(), commentDO.getUserId(), commentDO.getOrderId()); + + productCommentMapper.insert(commentDO); + return commentDO.getId(); } - @Override - public void createComment(ProductCommentDO productComment, Boolean system) { - // TODO @puhui999:这里不区分是否为 system;直接都校验 - if (!system) { - // TODO 判断订单是否存在 fix; - // TODO @puhui999:改成 order 那有个 comment 接口,哪里校验下;商品评论这里不校验订单是否存在哈 - TradeOrderRespDTO order = tradeOrderApi.getOrder(productComment.getOrderId()); - if (null == order) { - throw exception(ORDER_NOT_FOUND); - } - ProductSpuDO spu = productSpuService.getSpu(productComment.getSpuId()); - if (null == spu) { - throw exception(SPU_NOT_EXISTS); - } - // 判断当前订单的当前商品用户是否评价过 - ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId()); - if (null != exist) { - throw exception(ORDER_SPU_COMMENT_EXISTS); - } + // TODO 只有创建和更新诶 要不要删除接口 + + private void validateComment(Long spuId, Long userId, Long orderId) { + ProductSpuDO spu = productSpuService.getSpu(spuId); + if (null == spu) { + throw exception(SPU_NOT_EXISTS); + } + // 判断当前订单的当前商品用户是否评价过 + ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderIdAndSpuId(userId, orderId, spuId); + if (null != exist) { + throw exception(ORDER_SPU_COMMENT_EXISTS); } - productCommentMapper.insert(productComment); } - private void validateCommentExists(Long id) { + private ProductCommentDO validateCommentExists(Long id) { ProductCommentDO productComment = productCommentMapper.selectById(id); if (productComment == null) { throw exception(COMMENT_NOT_EXISTS); } + return productComment; + } + + @Override + public AppCommentStatisticsRespVO getCommentPageTabsCount(Long spuId, Boolean visible) { + return ProductCommentConvert.INSTANCE.convert( + // 查询商品 id = spuId 的所有评论数量 + productCommentMapper.selectCountBySpuId(spuId, visible, null), + // 查询商品 id = spuId 的所有好评数量 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.GOOD_COMMENT), + // 查询商品 id = spuId 的所有中评数量 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT), + // 查询商品 id = spuId 的所有差评数量 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT) + ); + } + + @Override + public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { + return ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); + } + + @Override + public PageResult getCommentPage(ProductCommentPageReqVO pageReqVO) { + return productCommentMapper.selectPage(pageReqVO); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 6754f3ba0..418562d03 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -4,14 +4,13 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; @@ -26,7 +25,6 @@ import org.springframework.context.annotation.Lazy; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Date; -import java.util.Map; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; @@ -93,12 +91,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setSkuId(generateId()); o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores()); o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores()); - o.setDeliveryScores(ProductCommentScoresEnum.FOUR.getScores()); o.setContent("真好吃"); o.setReplyUserId(generateId()); o.setReplyContent("确实"); o.setReplyTime(LocalDateTime.now()); - o.setAdditionalTime(LocalDateTime.now()); o.setCreateTime(LocalDateTime.now()); o.setUpdateTime(LocalDateTime.now()); }); @@ -139,23 +135,23 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals(8, all.getTotal()); // 测试获取所有商品分页评论数据 - PageResult result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); + PageResult result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); assertEquals(7, result1.getTotal()); // 测试获取所有商品分页中评数据 - PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); + PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); assertEquals(2, result2.getTotal()); // 测试获取指定 spuId 商品分页中评数据 - PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); + PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); assertEquals(2, result3.getTotal()); // 测试分页 tab count - Map tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE); - assertEquals(6, tabsCount.get(AppCommentPageReqVO.ALL_COUNT)); - assertEquals(4, tabsCount.get(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT)); - assertEquals(2, tabsCount.get(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT)); - assertEquals(0, tabsCount.get(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT)); + AppCommentStatisticsRespVO tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE); + assertEquals(6, tabsCount.getAllCount()); + assertEquals(4, tabsCount.getGoodCount()); + assertEquals(2, tabsCount.getMediocreCount()); + assertEquals(0, tabsCount.getNegativeCount()); } @@ -190,7 +186,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { ProductCommentReplyVO replyVO = new ProductCommentReplyVO(); replyVO.setId(productCommentId); replyVO.setReplyContent("测试"); - productCommentService.commentReply(replyVO, 1L); + productCommentService.replyComment(replyVO, 1L); ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); assertEquals("测试", productCommentDO.getReplyContent()); @@ -199,24 +195,6 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { @Test public void testCreateComment_success() { // mock 测试 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { - o.setAdditionalContent(""); - }); - - productCommentService.createComment(productComment, Boolean.TRUE); - - MemberUserRespDTO user = new MemberUserRespDTO(); - user.setId(productComment.getUserId()); - - AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO(); - createReqVO.setId(productComment.getId()); - createReqVO.setAdditionalContent("追加"); - createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls()); - - productCommentService.additionalComment(user, createReqVO); - ProductCommentDO exist = productCommentMapper.selectById(productComment.getId()); - - assertEquals("追加", exist.getAdditionalContent()); } } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java index 8dc2aaced..5f98073d1 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.trade.api.order; -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; - /** * 订单 API 接口 * @@ -10,11 +8,12 @@ import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; public interface TradeOrderApi { /** - * 获取订单通过订单 id + * 验证订单 * - * @param id id - * @return 订单信息 Response DTO + * @param userId 用户 id + * @param orderItemId 订单项 id + * @return 校验通过返回订单 id */ - TradeOrderRespDTO getOrder(Long id); + Long validateOrder(Long userId, Long orderItemId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java index 3abdb2a9d..120b6d054 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java @@ -1,13 +1,15 @@ package cn.iocoder.yudao.module.trade.api.order; -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND; + /** * 订单 API 接口实现类 * @@ -21,8 +23,14 @@ public class TradeOrderApiImpl implements TradeOrderApi { private TradeOrderService tradeOrderService; @Override - public TradeOrderRespDTO getOrder(Long id) { - return TradeOrderConvert.INSTANCE.convert(tradeOrderService.getOrder(id)); + public Long validateOrder(Long userId, Long orderItemId) { + // 校验订单项,订单项存在订单就存在 + TradeOrderItemDO item = tradeOrderService.getOrderItem(userId, orderItemId); + if (item == null) { + throw exception(ORDER_ITEM_NOT_FOUND); + } + + return item.getOrderId(); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index e3008fdd6..112717f54 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -4,9 +4,11 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; +import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -14,6 +16,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import com.google.common.collect.Maps; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -23,14 +26,15 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.HashMap; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND; @Tag(name = "用户 App - 交易订单") @RestController @@ -48,6 +52,9 @@ public class AppTradeOrderController { @Resource private TradeOrderProperties tradeOrderProperties; + @Resource + private ProductCommentApi productCommentApi; + @GetMapping("/settlement") @Operation(summary = "获得订单结算信息") @PreAuthenticated @@ -105,7 +112,7 @@ public class AppTradeOrderController { @GetMapping("/get-count") @Operation(summary = "获得交易订单数量") public CommonResult> getOrderCount() { - Map orderCount = new HashMap<>(); + Map orderCount = Maps.newLinkedHashMapWithExpectedSize(5); // 全部 orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null)); // 待付款(未支付) @@ -129,11 +136,16 @@ public class AppTradeOrderController { return success(TradeOrderConvert.INSTANCE.convert03(item)); } - // TODO 芋艿:待实现 @PostMapping("/item/create-comment") @Operation(summary = "创建交易订单项的评价") - public CommonResult createOrderItemComment() { - return success(0L); + public CommonResult createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) { + // 校验订单项,订单项存在订单就存在 + TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId()); + if (item == null) { + throw exception(ORDER_ITEM_NOT_FOUND); + } + + return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId())); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java new file mode 100644 index 000000000..9fbec0625 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo.item; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 商品评价创建 Request VO + * + * @author HUIHUI + */ +@Schema(description = "用户APP - 商品评价创建 Request VO") +@Data +public class AppTradeOrderItemCommentCreateReqVO { + + @Schema(description = "是否匿名", required = true, example = "true") + @NotNull(message = "是否匿名不能为空") + private Boolean anonymous; + + @Schema(description = "交易订单项编号", required = true, example = "2312312") + @NotNull(message = "交易订单项编号不能为空") + private Long orderItemId; + + @Schema(description = "商品SPU编号", required = true, example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "丝滑飘逸小短裙") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "3082") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "评分星级 1-5分", required = true, example = "5") + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true, example = "5") + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true, example = "5") + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)") + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]") + @Size(max = 9, message = "评论图片地址数组长度不能超过9张") + private List picUrls; + + @Schema(description = "评价人名称", required = true, example = "小姑凉") + @NotNull(message = "评价人名称不能为空") + private String userNickname; + + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png") + @NotNull(message = "评价人头像不能为空") + private String userAvatar; + + @Schema(description = "评价人", required = true, example = "16868") + @NotNull(message = "评价人不能为空") + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 8c5501b53..6e81746a4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; @@ -18,6 +19,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailR import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -75,9 +77,10 @@ public interface TradeOrderConvert { return orderItem; }); } + TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); - @Mapping(source = "userId" , target = "userId") + @Mapping(source = "userId", target = "userId") PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId); @Mappings({ @@ -85,6 +88,7 @@ public interface TradeOrderConvert { @Mapping(source = "count", target = "incrCount"), }) ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); + List convertList(List list); default PayOrderCreateReqDTO convert(TradeOrderDO order, List orderItems, @@ -136,7 +140,7 @@ public interface TradeOrderConvert { properties.forEach(property -> { ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); if (propertyValueDetail == null) { - return; + return; } item.getProperties().add(convert(propertyValueDetail)); }); @@ -148,7 +152,9 @@ public interface TradeOrderConvert { }); return new PageResult<>(orderVOs, pageResult.getTotal()); } + TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); + ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); // TODO 芋艿:可简化 @@ -179,7 +185,9 @@ public interface TradeOrderConvert { orderVO.setUser(convert(user)); return orderVO; } + TradeOrderDetailRespVO convert2(TradeOrderDO order, List items); + MemberUserRespVO convert(MemberUserRespDTO bean); // TODO 芋艿:可简化 @@ -214,7 +222,9 @@ public interface TradeOrderConvert { }); return new PageResult<>(orderVOs, pageResult.getTotal()); } + AppTradeOrderPageItemRespVO convert02(TradeOrderDO order, List items); + AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean); default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List orderItems, @@ -243,10 +253,13 @@ public interface TradeOrderConvert { orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); return orderVO; } + AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List items); AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); + CommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO); + default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, List cartList) { TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); @@ -286,6 +299,8 @@ public interface TradeOrderConvert { } return respVO; } + AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address); + } From 9ff873fe53d7356b2552c9b756e268a29a00b266 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 12 Jun 2023 12:09:16 +0800 Subject: [PATCH 106/232] =?UTF-8?q?fix=EF=BC=9A=E5=AE=8C=E5=96=84=E5=95=86?= =?UTF-8?q?=E5=93=81=E8=AF=84=E8=AE=BA=E6=B5=8B=E8=AF=95=20sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/resources/sql/create_tables.sql | 109 +++++++++++++----- 1 file changed, 77 insertions(+), 32 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 983aee740..e9fa0f6ce 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -126,36 +126,81 @@ CREATE TABLE IF NOT EXISTS `product_property_value` ( PRIMARY KEY("id") ) COMMENT '规格值'; -CREATE TABLE IF NOT EXISTS `product_comment` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评价编号', - `user_id` bigint NOT NULL COMMENT ' 评价ID 用户编号', - `user_nickname` varchar(128) NOT NULL COMMENT '评价人名称', - `user_avatar` varchar(255) NOT NULL COMMENT '评价人头像', - `anonymous` bit(1) NOT NULL DEFAULT 0 COMMENT '是否匿名 0:不匿名 1:匿名', - `order_id` bigint NOT NULL COMMENT '交易订单编号', - `order_item_id` bigint NOT NULL COMMENT '交易订单项编号', - `spu_id` bigint NOT NULL COMMENT '商品SPU编号', - `spu_name` varchar NOT NULL COMMENT '商品SPU名称', - `sku_id` bigint NOT NULL COMMENT '商品SKU编号', - `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 true:显示 false:隐藏', - `scores` int NOT NULL COMMENT '评分星级 1-5分', - `description_scores` int NOT NULL COMMENT '描述星级 1-5分', - `benefit_scores` int NOT NULL COMMENT '服务星级 1-5分', - `delivery_scores` int NOT NULL COMMENT '配送星级 1-5分', - `content` varchar(2000) NOT NULL COMMENT '评论内容', - `pic_urls` varchar(1024) DEFAULT '' COMMENT '评论图片地址数组,以逗号分隔最多上传9张', - `replied` bit(1) NOT NULL DEFAULT 0 COMMENT '商家是否回复 1:回复 0:未回复', - `reply_user_id` bigint COMMENT '回复管理员编号', - `reply_content` varchar(2000) COMMENT '商家回复内容', - `reply_time` datetime COMMENT '商家回复时间', - `additional_content` varchar(2000) COMMENT '追加评价内容', - `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张', - `additional_time` datetime COMMENT '追加评价时间', - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, +CREATE TABLE IF NOT EXISTS `product_comment` +( + `id` + bigint + NOT + NULL + AUTO_INCREMENT + COMMENT + '评论编号,主键自增', + `user_id` + bigint + DEFAULT + NULL + COMMENT + '评价人的用户编号关联 MemberUserDO 的 id 编号', + `user_nickname` + varchar +( + 255 +) DEFAULT NULL COMMENT '评价人名称', + `user_avatar` varchar +( + 1024 +) DEFAULT NULL COMMENT '评价人头像', + `anonymous` bit +( + 1 +) DEFAULT NULL COMMENT '是否匿名', + `order_id` bigint DEFAULT NULL COMMENT '交易订单编号关联 TradeOrderDO 的 id 编号', + `order_item_id` bigint DEFAULT NULL COMMENT '交易订单项编号关联 TradeOrderItemDO 的 id 编号', + `spu_id` bigint DEFAULT NULL COMMENT '商品 SPU 编号关联 ProductSpuDO 的 id', + `spu_name` varchar +( + 255 +) DEFAULT NULL COMMENT '商品 SPU 名称', + `sku_id` bigint DEFAULT NULL COMMENT '商品 SKU 编号关联 ProductSkuDO 的 id 编号', + `visible` bit +( + 1 +) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏', + `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分', + `description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星', + `benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星', + `content` varchar +( + 1024 +) DEFAULT NULL COMMENT '评论内容', + `pic_urls` varchar +( + 4096 +) DEFAULT NULL COMMENT '评论图片地址数组', + `reply_status` bit +( + 1 +) DEFAULT NULL COMMENT '商家是否回复', + `reply_user_id` bigint DEFAULT NULL COMMENT '回复管理员编号关联 AdminUserDO 的 id 编号', + `reply_content` varchar +( + 1024 +) DEFAULT NULL COMMENT '商家回复内容', + `reply_time` datetime DEFAULT NULL COMMENT '商家回复时间', + `creator` varchar +( + 64 +) DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar +( + 64 +) DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY (`id`) -) COMMENT '商品评价'; \ No newline at end of file + "tenant_id" bigint not null default '0', + PRIMARY KEY +( + `id` +) + ) COMMENT '产品评论表'; From 60172274ecaa925236a73d63e4599f4fd014142f Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 12 Jun 2023 17:02:46 +0800 Subject: [PATCH 107/232] =?UTF-8?q?fix=EF=BC=9A=E5=90=88=E5=B9=B6=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=90=8E=E4=BF=AE=E6=94=B9=E5=B7=AE=E5=BC=82=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=95=86=E5=93=81=E8=AF=84=E8=AE=BA=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/ProductCommentController.java | 2 +- ...yVO.java => ProductCommentReplyReqVO.java} | 3 +- .../comment/AppProductCommentController.java | 78 ++++++++++++++++--- .../app/comment/vo/AppCommentPageReqVO.java | 5 ++ .../comment/vo/AppProductCommentBaseVO.java | 54 ------------- .../vo/AppProductCommentCreateReqVO.java | 44 ++++++++++- .../comment/vo/AppProductCommentRespVO.java | 51 +++++++++++- .../comment/ProductCommentConvert.java | 4 + .../mysql/comment/ProductCommentMapper.java | 21 ----- .../comment/ProductCommentService.java | 6 +- .../comment/ProductCommentServiceImpl.java | 40 +++++++++- .../ProductCommentServiceImplTest.java | 7 +- .../app/order/AppTradeOrderController.java | 2 + 13 files changed, 212 insertions(+), 105 deletions(-) rename yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/{ProductCommentReplyVO.java => ProductCommentReplyReqVO.java} (91%) delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index 6a8b12778..91020a51c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -46,7 +46,7 @@ public class ProductCommentController { @PutMapping("/reply") @Operation(summary = "商家回复") @PreAuthorize("@ss.hasPermission('product:comment:update')") - public CommonResult commentReply(@Valid @RequestBody ProductCommentReplyVO replyVO) { + public CommonResult commentReply(@Valid @RequestBody ProductCommentReplyReqVO replyVO) { productCommentService.replyComment(replyVO, getLoginUserId()); return success(true); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java similarity index 91% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java index a935108dc..927f898cd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java @@ -7,11 +7,10 @@ import lombok.ToString; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -// TODO @puhui999:ReqVO @Schema(description = "管理后台 - 商品评价可见修改 Request VO") @Data @ToString(callSuper = true) -public class ProductCommentReplyVO { +public class ProductCommentReplyReqVO { @Schema(description = "评价编号", required = true, example = "15721") @NotNull(message = "评价编号不能为空") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java index 6921e6cbf..90a387c80 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.module.product.controller.app.comment; -import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -18,6 +19,11 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -30,17 +36,69 @@ public class AppProductCommentController { @Resource private ProductCommentService productCommentService; + @GetMapping("/list") + @Operation(summary = "获得最近的 n 条商品评价") + @Parameters({ + @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"), + @Parameter(name = "count", description = "数量", required = true, example = "10") + }) + public CommonResult> getCommentList(@RequestParam("spuId") Long spuId, + @RequestParam(value = "count", defaultValue = "10") Integer count) { + + List list = new ArrayList<>(); + + AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO(); + item1.setPropertyId(1L); + item1.setPropertyName("颜色"); + item1.setValueId(1024L); + item1.setValueName("红色"); + list.add(item1); + + AppProductPropertyValueDetailRespVO item2 = new AppProductPropertyValueDetailRespVO(); + item2.setPropertyId(2L); + item2.setPropertyName("尺寸"); + item2.setValueId(2048L); + item2.setValueName("大号"); + list.add(item2); + + AppProductPropertyValueDetailRespVO item3 = new AppProductPropertyValueDetailRespVO(); + item3.setPropertyId(3L); + item3.setPropertyName("重量"); + item3.setValueId(3072L); + item3.setValueName("500克"); + list.add(item3); + + // TODO 生成 mock 的数据 + AppProductCommentRespVO appCommentRespVO = new AppProductCommentRespVO(); + appCommentRespVO.setUserId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setUserNickname("用户" + new Random().nextInt(100)); + appCommentRespVO.setUserAvatar("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); + appCommentRespVO.setId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setAnonymous(new Random().nextBoolean()); + appCommentRespVO.setOrderId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setOrderItemId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setReplyStatus(new Random().nextBoolean()); + appCommentRespVO.setReplyUserId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setReplyContent("回复内容" + new Random().nextInt(100)); + appCommentRespVO.setReplyTime(LocalDateTime.now().minusDays(new Random().nextInt(30))); + appCommentRespVO.setCreateTime(LocalDateTime.now().minusDays(new Random().nextInt(30))); + appCommentRespVO.setSpuId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setSpuName("商品" + new Random().nextInt(100)); + appCommentRespVO.setSkuId((long) (new Random().nextInt(100000) + 10000)); + appCommentRespVO.setSkuProperties(list); + appCommentRespVO.setScores(new Random().nextInt(5) + 1); + appCommentRespVO.setDescriptionScores(new Random().nextInt(5) + 1); + appCommentRespVO.setBenefitScores(new Random().nextInt(5) + 1); + appCommentRespVO.setContent("评论内容" + new Random().nextInt(100)); + appCommentRespVO.setPicUrls(Arrays.asList("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg")); + + return success(Arrays.asList(appCommentRespVO)); + } + @GetMapping("/page") @Operation(summary = "获得商品评价分页") public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { - PageResult result = productCommentService.getCommentPage(pageVO, Boolean.TRUE); - result.getList().forEach(item -> { - // 判断用户是否选择匿名 - if (ObjectUtil.equal(item.getAnonymous(), true)) { - item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); - } - }); - return success(result); + return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); } @GetMapping("/getCommentStatistics") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index 8799c5c75..0e6ef98cc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -8,6 +8,11 @@ import lombok.ToString; import javax.validation.constraints.NotNull; +/** + * 用户 APP - 商品评价分页 Request VO + * + * @author HUIHUI + */ @Schema(description = "用户APP - 商品评价分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java deleted file mode 100644 index 8c989ef18..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.comment.vo; - -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.List; - -/** - * 商品评论 Base VO - * - * @author HUIHUI - */ -@Data -public class AppProductCommentBaseVO { - - @Schema(description = "商品SPU编号", required = true, example = "91192") - @NotNull(message = "商品SPU编号不能为空") - private Long spuId; - - @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖") - @NotNull(message = "商品SPU名称不能为空") - private String spuName; - - @Schema(description = "商品SKU编号", required = true, example = "81192") - @NotNull(message = "商品SKU编号不能为空") - private Long skuId; - - @Schema(description = "商品 SKU 属性", required = true) - private List skuProperties; // TODO puhui999:这个需要从数据库查询哈 - - @Schema(description = "评分星级 1-5分", required = true, example = "5") - @NotNull(message = "评分星级 1-5分不能为空") - private Integer scores; - - @Schema(description = "描述星级 1-5分", required = true, example = "5") - @NotNull(message = "描述星级 1-5分不能为空") - private Integer descriptionScores; - - @Schema(description = "服务星级 1-5分", required = true, example = "5") - @NotNull(message = "服务星级 1-5分不能为空") - private Integer benefitScores; - - @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") - @NotNull(message = "评论内容不能为空") - private String content; - - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") - @Size(max = 9, message = "评论图片地址数组长度不能超过9张") - private List picUrls; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java index 42cdc7e5b..53e797447 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java @@ -2,17 +2,21 @@ package cn.iocoder.yudao.module.product.controller.app.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; -// TODO @puhui999:不应该继承 AppProductCommentCreateReqVO +/** + * 用户APP - 商品评价创建 Request VO + * + * @author HUIHUI + */ @Schema(description = "用户APP - 商品评价创建 Request VO") @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class AppProductCommentCreateReqVO extends AppProductCommentBaseVO { +public class AppProductCommentCreateReqVO { @Schema(description = "是否匿名", required = true, example = "true") @NotNull(message = "是否匿名不能为空") @@ -22,4 +26,36 @@ public class AppProductCommentCreateReqVO extends AppProductCommentBaseVO { @NotNull(message = "交易订单项编号不能为空") private Long orderItemId; + @Schema(description = "商品SPU编号", required = true, example = "91192") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "81192") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "评分星级 1-5分", required = true, example = "5") + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true, example = "5") + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true, example = "5") + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") + @Size(max = 9, message = "评论图片地址数组长度不能超过9张") + private List picUrls; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java index 5fb8eb351..e78f996e1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java @@ -1,19 +1,27 @@ package cn.iocoder.yudao.module.product.controller.app.comment.vo; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.time.LocalDateTime; import java.util.List; -@Schema(description = "用户APP - 商品评价 Response VO") +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 用户APP - 商品评价详情 Response VO + * + * @author HUIHUI + */ +@Schema(description = "用户APP - 商品评价详情 Response VO") @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class AppProductCommentRespVO extends AppProductCommentBaseVO { +public class AppProductCommentRespVO { @Schema(description = "评价人的用户编号", required = true, example = "15721") private Long userId; @@ -63,4 +71,39 @@ public class AppProductCommentRespVO extends AppProductCommentBaseVO { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; + @Schema(description = "商品SPU编号", required = true, example = "91192") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "81192") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "商品 SKU 属性", required = true) + private List skuProperties; + + @Schema(description = "评分星级 1-5分", required = true, example = "5") + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true, example = "5") + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true, example = "5") + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") + @Size(max = 9, message = "评论图片地址数组长度不能超过9张") + private List picUrls; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index ff895f491..9ec7e5cb4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -6,7 +6,9 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; @@ -36,6 +38,8 @@ public interface ProductCommentConvert { List convertList(List list); + List convertList01(List properties); + PageResult convertPage(PageResult page); PageResult convertPage02(PageResult pageResult); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index 13c0f47f7..f44c1e334 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -6,14 +6,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; -import java.time.LocalDateTime; - @Mapper public interface ProductCommentMapper extends BaseMapperX { @@ -55,23 +51,6 @@ public interface ProductCommentMapper extends BaseMapperX { return selectPage(reqVO, queryWrapper); } - default void updateCommentVisible(Long id, Boolean visible) { - LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .set(ProductCommentDO::getVisible, visible) - .eq(ProductCommentDO::getId, id); - update(null, lambdaUpdateWrapper); - } - - default void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { - LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .set(ProductCommentDO::getReplyStatus, Boolean.TRUE) - .set(ProductCommentDO::getReplyTime, LocalDateTime.now()) - .set(ProductCommentDO::getReplyUserId, loginUserId) - .set(ProductCommentDO::getReplyContent, replyVO.getReplyContent()) - .eq(ProductCommentDO::getId, replyVO.getId()); - update(null, lambdaUpdateWrapper); - } - default ProductCommentDO selectByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { return selectOne(new LambdaQueryWrapperX() .eq(ProductCommentDO::getUserId, userId) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 10592f7b9..c6841770a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; @@ -36,15 +36,13 @@ public interface ProductCommentService { */ void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO); - // TODO @puhui999:replyComment - /** * 商家回复 * * @param replyVO 商家回复 * @param loginUserId 管理后台商家登陆人 ID */ - void replyComment(ProductCommentReplyVO replyVO, Long loginUserId); + void replyComment(ProductCommentReplyReqVO replyVO, Long loginUserId); /** * 获得商品评价分页 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index 6dc67beb8..05d38899c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,25 +1,36 @@ package cn.iocoder.yudao.module.product.service.comment; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; @@ -42,6 +53,10 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Resource private ProductSpuService productSpuService; + @Resource + @Lazy + private ProductSkuService productSkuService; + @Override @Transactional(rollbackFor = Exception.class) public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { @@ -55,7 +70,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override @Transactional(rollbackFor = Exception.class) - public void replyComment(ProductCommentReplyVO replyVO, Long loginUserId) { + public void replyComment(ProductCommentReplyReqVO replyVO, Long loginUserId) { // 校验评论是否存在 ProductCommentDO productCommentDO = validateCommentExists(replyVO.getId()); productCommentDO.setReplyTime(LocalDateTime.now()); @@ -127,7 +142,26 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { - return ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); + PageResult result = ProductCommentConvert.INSTANCE.convertPage02( + productCommentMapper.selectPage(pageVO, visible)); + Set skuIds = result.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet()); + List skuList = productSkuService.getSkuList(skuIds); + Map skuDOMap = new HashMap<>(skuIds.size()); + if (CollUtil.isNotEmpty(skuList)) { + skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c))); + } + result.getList().forEach(item -> { + // 判断用户是否选择匿名 + if (ObjectUtil.equal(item.getAnonymous(), true)) { + item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); + } + ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId()); + if (productSkuDO != null) { + List skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties()); + item.setSkuProperties(skuProperties); + } + }); + return result; } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 6e4419d4f..ad782bc51 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -5,7 +5,7 @@ import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; import org.junit.jupiter.api.Test; @@ -52,6 +53,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { private TradeOrderApi tradeOrderApi; @MockBean private ProductSpuService productSpuService; + @MockBean + private ProductSkuService productSkuService; public String generateNo() { return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); @@ -183,7 +186,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { Long productCommentId = productComment.getId(); - ProductCommentReplyVO replyVO = new ProductCommentReplyVO(); + ProductCommentReplyReqVO replyVO = new ProductCommentReplyReqVO(); replyVO.setId(productCommentId); replyVO.setReplyContent("测试"); productCommentService.replyComment(replyVO, 1L); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index defc1cee7..d36c0f80a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -148,4 +148,6 @@ public class AppTradeOrderController { return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId())); } + // TODO 合并代码后发现只有商家回复功能 用户追评不要了吗? + } From e23fb5024a386503c704205b92947405a96387f0 Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 14 Jun 2023 15:21:41 +0800 Subject: [PATCH 108/232] =?UTF-8?q?fix:=20required=20=3D=20true=20?= =?UTF-8?q?=E5=B7=B2=E8=BF=87=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 6 ++-- .../admin/order/vo/TradeOrderItemBaseVO.java | 28 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 4eac7409c..c7c424fa0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -27,13 +27,13 @@ public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { @NotNull(message = "商品编号不能为空") private Long id; - @Schema(description = "商品销量", required = true, example = "1999") + @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999") private Integer salesCount; - @Schema(description = "浏览量", required = true, example = "1999") + @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999") private Integer browseCount; - @Schema(description = "商品状态", required = true, example = "1") + @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @InEnum(ProductSpuStatusEnum.class) private Integer status; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java index 351d5a787..ded1fe7a1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java @@ -12,47 +12,47 @@ public class TradeOrderItemBaseVO { // ========== 订单项基本信息 ========== - @Schema(description = "编号", required = true, example = "1") + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long id; - @Schema(description = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long userId; - @Schema(description = "订单编号", required = true, example = "1") + @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long orderId; // ========== 商品基本信息 ========== - @Schema(description = "商品 SPU 编号", required = true, example = "1") + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long spuId; - @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") + @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") private String spuName; - @Schema(description = "商品 SKU 编号", required = true, example = "1") + @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long skuId; - @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + @Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png") private String picUrl; - @Schema(description = "购买数量", required = true, example = "1") + @Schema(description = "购买数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer count; // ========== 价格 + 支付基本信息 ========== - @Schema(description = "商品原价(单)", required = true, example = "100") + @Schema(description = "商品原价(单)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer price; - @Schema(description = "商品优惠(总)", required = true, example = "100") + @Schema(description = "商品优惠(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer discountPrice; - @Schema(description = "商品实付金额(总)", required = true, example = "100") + @Schema(description = "商品实付金额(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer payPrice; - @Schema(description = "子订单分摊金额(总)", required = true, example = "100") + @Schema(description = "子订单分摊金额(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer orderPartPrice; - @Schema(description = "分摊后子订单实付金额(总)", required = true, example = "100") + @Schema(description = "分摊后子订单实付金额(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer orderDividePrice; // ========== 营销基本信息 ========== @@ -61,7 +61,7 @@ public class TradeOrderItemBaseVO { // ========== 售后基本信息 ========== - @Schema(description = "售后状态", required = true, example = "1") + @Schema(description = "售后状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer afterSaleStatus; } From b74991e24261edde587713ffbe9b612c56d5be50 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 14 Jun 2023 23:08:22 +0800 Subject: [PATCH 109/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Amock=20?= =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E6=B4=BB=E5=8A=A8=E8=AF=A6=E6=83=85=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combination/AppCombinationController.java | 70 +++++++++++++++++++ .../AppCombinationActivityDetailRespVO.java | 67 ++++++++++++++++++ .../vo/AppSeckillActivitiDetailRespVO.java | 7 +- 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java new file mode 100644 index 000000000..cd6d142a2 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityDetailRespVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 拼团活动") +@RestController +@RequestMapping("/promotion/combination-activity") +@Validated +public class AppCombinationController { + + @GetMapping("/get-detail") + @Operation(summary = "获得拼团活动明细") + @Parameter(name = "id", description = "活动编号", required = true, example = "1024") + public CommonResult getCombinationActivity(@RequestParam("id") Long id) { + // TODO 芋艿:如果禁用的时候,需要抛出异常; + AppCombinationActivityDetailRespVO obj = new AppCombinationActivityDetailRespVO(); + // 设置其属性的值 + obj.setId(id); + obj.setName("晚九点限时秒杀"); + obj.setStatus(1); + obj.setStartTime(LocalDateTime.of(2023, 6, 11, 0, 0, 0)); + obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0)); + obj.setSpuId(633L); + // 创建一个Product对象的列表 + List productList = new ArrayList<>(); + // 创建三个新的Product对象并设置其属性的值 + AppCombinationActivityDetailRespVO.Product product1 = new AppCombinationActivityDetailRespVO.Product(); + product1.setSkuId(1L); + product1.setCombinationPrice(100); + product1.setQuota(50); + product1.setLimitCount(3); + // 将第一个Product对象添加到列表中 + productList.add(product1); + // 创建第二个Product对象并设置其属性的值 + AppCombinationActivityDetailRespVO.Product product2 = new AppCombinationActivityDetailRespVO.Product(); + product2.setSkuId(2L); + product2.setCombinationPrice(200); + product2.setQuota(100); + product2.setLimitCount(4); + // 将第二个Product对象添加到列表中 + productList.add(product2); + // 创建第三个Product对象并设置其属性的值 + AppCombinationActivityDetailRespVO.Product product3 = new AppCombinationActivityDetailRespVO.Product(); + product3.setSkuId(3L); + product3.setCombinationPrice(300); + product3.setQuota(150); + product3.setLimitCount(5); + // 将第三个Product对象添加到列表中 + productList.add(product3); + // 将Product列表设置为对象的属性值 + obj.setProducts(productList); + return success(obj); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java new file mode 100644 index 000000000..553a31fd8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "用户 App - 拼团活动明细 Response VO") +@Data +public class AppCombinationActivityDetailRespVO { + + @Schema(description = "拼团活动编号", required = true, example = "1024") + private Long id; + + @Schema(description = "拼团活动名称", required = true, example = "618 大拼团") + private String name; + + @Schema(description = "活动状态", required = true, example = "1") + private Integer status; + + @Schema(description = "活动开始时间", required = true) + private LocalDateTime startTime; + + @Schema(description = "活动结束时间", required = true) + private LocalDateTime endTime; + + @Schema(description = "商品 SPU 编号", required = true, example = "2048") + private Long spuId; + + @Schema(description = "商品信息数组", required = true) + private List products; + + @Schema(description = "成功的拼团记录", required = true) + private List successRecords; + + @Schema(description = "进行中的拼团记录", required = true) + private List runningRecords; + + @Schema(description = "商品信息") + @Data + public static class Product { + + @Schema(description = "商品 SKU 编号", required = true, example = "4096") + private Long skuId; + + @Schema(description = "拼团金额,单位:分", required = true, example = "100") + private Integer combinationPrice; + + @Schema(description = "拼团限量库存", required = true, example = "50") + private Integer quota; + + @Schema(description = "每人限购数量", required = true, example = "10") + private Integer limitCount; + + } + + @Schema(description = "拼团记录") + @Data + public static class Record { + + @Schema(description = "拼团记录编号", required = true, example = "1024") + private Long id; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java index 0f1408928..a643fc1b3 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java @@ -27,10 +27,13 @@ public class AppSeckillActivitiDetailRespVO { @Schema(description = "活动结束时间", required = true) private LocalDateTime endTime; + + private Long successGruopCount; + @Schema(description = "商品 SPU 编号", required = true, example = "2048") private Long spuId; - @Schema(description = "商品 SPU 名字", required = true) + @Schema(description = "商品信息数组", required = true) private List products; @Schema(description = "商品信息") @@ -46,7 +49,7 @@ public class AppSeckillActivitiDetailRespVO { @Schema(description = "秒杀限量库存", required = true, example = "50") private Integer quota; - @Schema(description = "limitCount", required = true, example = "10") + @Schema(description = "每人限购数量", required = true, example = "10") private Integer limitCount; } From e69e6d880b08e02b0d9c9ca9b8c166cc1ef0954b Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 15 Jun 2023 10:49:24 +0800 Subject: [PATCH 110/232] =?UTF-8?q?=E5=BF=AB=E9=80=92=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=20review=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 5 +- .../DeliveryExpressTemplateConvert.java | 7 +- .../DeliveryExpressTemplateChargeMapper.java | 8 +- .../DeliveryExpressTemplateFreeMapper.java | 9 ++- .../DeliveryExpressTemplateService.java | 12 ++- .../DeliveryExpressTemplateServiceImpl.java | 55 ++++++------- .../bo/DeliveryExpressTemplateChargeBO.java | 29 ------- .../bo/DeliveryExpressTemplateFreeBO.java | 26 ------ .../bo/DeliveryExpressTemplateRespBO.java | 79 +++++++++++++++++++ .../bo/SpuDeliveryExpressTemplateRespBO.java | 33 -------- .../price/bo/TradePriceCalculateRespBO.java | 5 ++ .../TradeDeliveryPriceCalculator.java | 46 ++++++----- .../TradePriceCalculatorHelper.java | 3 +- .../TradeDeliveryPriceCalculatorTest.java | 38 +++++---- 14 files changed, 172 insertions(+), 183 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 46ee636a5..800b5f239 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -51,13 +51,12 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); - ErrorCode DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003004, "计算快递运费时,收件人地址编号为空"); // TODO @jaosn:这个错误码,放到 Price 这块 - ErrorCode PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND = new ErrorCode(1011003005, "找不到到商品对应的运费模板"); // TODO @jaosn:这个错误码,放到 Price 这块 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003006, "快递查询接口异常"); ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003007, "快递查询返回失败, 原因:{}"); ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003008, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); - + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011004001, "计算快递运费异常,收件人地址编号为空"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011004002, "计算快递运费异常,找不到对应的运费模板"); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index 6ac562658..bbd57c62e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -6,8 +6,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -49,7 +48,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo); - DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); + DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); @@ -61,7 +60,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo); - DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); + DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); List convertTemplateChargeList(List list); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java index dc96b24f2..985b418ac 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -5,10 +5,9 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; -import org.springframework.stereotype.Repository; +import java.util.Collection; import java.util.List; @Mapper @@ -23,6 +22,11 @@ public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX() .eq(DeliveryExpressTemplateChargeDO::getTemplateId, templateId)); } + + default List selectByTemplateIds(Collection templateIds) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(DeliveryExpressTemplateChargeDO::getTemplateId, templateIds)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java index 58caaf9af..5cc407354 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -2,13 +2,11 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.ibatis.annotations.Mapper; -import org.springframework.stereotype.Repository; +import java.util.Collection; import java.util.List; @Mapper @@ -23,6 +21,11 @@ public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX() .eq(DeliveryExpressTemplateFreeDO::getTemplateId, templateId)); } + + default List selectListByTemplateIds(Collection ids) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(DeliveryExpressTemplateFreeDO::getTemplateId, ids)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 3c438df12..39edd823e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplat import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import javax.validation.Valid; import java.util.Collection; @@ -83,14 +83,12 @@ public interface DeliveryExpressTemplateService { */ DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); - // TODO @jason:可以把 spuIds 改成传递 ids 么?价格计算那,在 TradePriceCalculateRespBO 冗余好 templateId 字段。目的是,减少重复的查询 /** - * 基于指定的 SPU 编号数组和收件人地址区域编号. 获取匹配运费模板 + * 基于运费模板编号数组和收件人地址区域编号. 获取匹配运费模板 * - * @param spuIds SPU 编号列表 + * @param ids 编号列表 * @param areaId 区域编号 - * @return Map (spuId -> 运费模板设置) + * @return Map (templateId -> 运费模板设置) */ - Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId); - + Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index c7ddc9da6..c4aa22b8f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.trade.service.delivery; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO; @@ -15,9 +13,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateChargeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateFreeMapper; import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressTemplateMapper; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -46,8 +42,6 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla private DeliveryExpressTemplateChargeMapper expressTemplateChargeMapper; @Resource private DeliveryExpressTemplateFreeMapper expressTemplateFreeMapper; - @Resource - private ProductSpuApi productSpuApi; @Override @Transactional(rollbackFor = Exception.class) @@ -228,41 +222,40 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla } @Override - public Map getExpressTemplateMapBySpuIdsAndArea(Collection spuIds, Integer areaId) { + public Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId) { Assert.notNull(areaId, "区域编号 {} 不能为空", areaId); - List spuList = productSpuApi.getSpuList(spuIds); - if (CollUtil.isEmpty(spuList)) { + if (CollUtil.isEmpty(ids)) { return Collections.emptyMap(); } - Map spuMap = convertMap(spuList, ProductSpuRespDTO::getDeliveryTemplateId); - List templateList = expressTemplateMapper.selectBatchIds(spuMap.keySet()); - Map result = new HashMap<>(templateList.size()); + List templateList = expressTemplateMapper.selectBatchIds(ids); + // 查询 templateCharge + List templeChargeList = expressTemplateChargeMapper.selectByTemplateIds(ids); + Map> templateChargeMap = convertMultiMap(templeChargeList, + DeliveryExpressTemplateChargeDO::getTemplateId); + // 查询 templateFree + List templateFreeList = expressTemplateFreeMapper.selectListByTemplateIds(ids); + Map> templateFreeMap = convertMultiMap(templateFreeList, + DeliveryExpressTemplateFreeDO::getTemplateId); + // 组合运费模板配置 RespBO + Map result = new HashMap<>(templateList.size()); templateList.forEach(item -> { - ProductSpuRespDTO spu = spuMap.get(item.getId()); - if (spu == null) { - return; - } - // TODO @jason:避免循环查询;最好类似 expressTemplateMapper.selectBatchIds(spuMap.keySet()); 批量查询,内存组合; - SpuDeliveryExpressTemplateRespBO bo = new SpuDeliveryExpressTemplateRespBO() + DeliveryExpressTemplateRespBO bo = new DeliveryExpressTemplateRespBO() .setChargeMode(item.getChargeMode()) - .setTemplateCharge(findMatchExpressTemplateCharge(item.getId(), areaId)) - .setTemplateFree(findMatchExpressTemplateFree(item.getId(), areaId)); - result.put(spu.getId(), bo); + .setTemplateCharge(findMatchExpressTemplateCharge(templateChargeMap.get(item.getId()), areaId)) + .setTemplateFree(findMatchExpressTemplateFree(templateFreeMap.get(item.getId()), areaId)); + result.put(item.getId(), bo); }); return result; } - private DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge(Long templateId, Integer areaId) { - return INSTANCE.convertTemplateCharge(findFirst( - expressTemplateChargeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) - ) - ); + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge( + List templateChargeList, Integer areaId) { + return INSTANCE.convertTemplateCharge(findFirst(templateChargeList, item -> item.getAreaIds().contains(areaId))); } - private DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree(Long templateId, Integer areaId) { - return INSTANCE.convertTemplateFree(findFirst( - expressTemplateFreeMapper.selectListByTemplateId(templateId), item -> item.getAreaIds().contains(areaId) - )); + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree( + List templateFreeList, Integer areaId) { + return INSTANCE.convertTemplateFree(findFirst(templateFreeList, item -> item.getAreaIds().contains(areaId))); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java deleted file mode 100644 index 9dd908c41..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateChargeBO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import lombok.Data; - -/** - * 快递运费模板费用配置 BO - * - * @author jason - */ -@Data -public class DeliveryExpressTemplateChargeBO { - - /** - * 首件数量(件数,重量,或体积) - */ - private Double startCount; - /** - * 起步价,单位:分 - */ - private Integer startPrice; - /** - * 续件数量(件, 重量,或体积) - */ - private Double extraCount; - /** - * 额外价,单位:分 - */ - private Integer extraPrice; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java deleted file mode 100644 index 6bccb038e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateFreeBO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import lombok.Data; - -/** - * 快递运费模板包邮配置 BO - * - * @author jason - */ -@Data -public class DeliveryExpressTemplateFreeBO { - - /** - * 包邮金额,单位:分 - * - * 订单总金额 > 包邮金额时,才免运费 - */ - private Integer freePrice; - - /** - * 包邮件数 - * - * 订单总件数 > 包邮件数时,才免运费 - */ - private Integer freeCount; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java new file mode 100644 index 000000000..6c8764a5c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.trade.service.delivery.bo; + +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; +import lombok.Data; + +/** + * 运费模板配置 Resp BO + * + * @author jason + */ +@Data +public class DeliveryExpressTemplateRespBO { + + /** + * 配送计费方式 + * + * 枚举 {@link DeliveryExpressChargeModeEnum} + */ + private Integer chargeMode; + + /** + * 运费模板快递运费设置 + */ + private DeliveryExpressTemplateChargeBO templateCharge; + + /** + * 运费模板包邮设置 + */ + private DeliveryExpressTemplateFreeBO templateFree; + + /** + * 快递运费模板费用配置 BO + * + * @author jason + */ + @Data + public static class DeliveryExpressTemplateChargeBO { + + /** + * 首件数量(件数,重量,或体积) + */ + private Double startCount; + /** + * 起步价,单位:分 + */ + private Integer startPrice; + /** + * 续件数量(件, 重量,或体积) + */ + private Double extraCount; + /** + * 额外价,单位:分 + */ + private Integer extraPrice; + } + + /** + * 快递运费模板包邮配置 BO + * + * @author jason + */ + @Data + public static class DeliveryExpressTemplateFreeBO { + + /** + * 包邮金额,单位:分 + * + * 订单总金额 > 包邮金额时,才免运费 + */ + private Integer freePrice; + + /** + * 包邮件数 + * + * 订单总件数 > 包邮件数时,才免运费 + */ + private Integer freeCount; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java deleted file mode 100644 index 82a0274de..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/SpuDeliveryExpressTemplateRespBO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.delivery.bo; - -import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; -import lombok.Data; - -/** - * SPU 运费模板配置 Resp BO - * - * @author jason - */ -@Data -public class SpuDeliveryExpressTemplateRespBO { - - /** - * 配送计费方式 - * - * 枚举 {@link DeliveryExpressChargeModeEnum} - */ - private Integer chargeMode; - - // TODO @jaosn:可以把 DeliveryExpressTemplateChargeBO 和 DeliveryExpressTemplateFreeBO 搞成内嵌的类。这样简洁一点 - - /** - * 运费模板快递运费设置 - */ - private DeliveryExpressTemplateChargeBO templateCharge; - - /** - * 运费模板包邮设置 - */ - private DeliveryExpressTemplateFreeBO templateFree; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java index 8231621bb..76fb68c1f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java @@ -180,6 +180,11 @@ public class TradePriceCalculateRespBO { */ private Long categoryId; + /** + * 运费模板 Id + */ + private Long deliveryTemplateId; + // ========== 商品 SKU 信息 ========== /** * 商品重量,单位:kg 千克 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 9f8e6afa7..1a0598c63 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -7,9 +7,7 @@ import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO.OrderItem; @@ -24,8 +22,8 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND; /** * 运费的 {@link TradePriceCalculator} 实现类 @@ -49,7 +47,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { return; } if (param.getAddressId() == null) { - throw exception(DELIVERY_EXPRESS_USER_ADDRESS_IS_EMPTY); + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY); } // 1.2 得到收件地址区域 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); @@ -57,29 +55,29 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { // 2. 过滤出已选中的商品SKU List selectedItem = filterList(result.getItems(), OrderItem::getSelected); - Set spuIds = convertSet(selectedItem, OrderItem::getSpuId); - Map spuExpressTemplateMap = - deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(spuIds, address.getAreaId()); + Set deliveryTemplateIds = convertSet(selectedItem, OrderItem::getDeliveryTemplateId); + Map expressTemplateMap = + deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(deliveryTemplateIds, address.getAreaId()); // 3. 计算配送费用 - if (CollUtil.isEmpty(spuExpressTemplateMap)) { - log.error("[calculate][找不到商品 spuId{} areaId{} 对应的运费模板]", spuIds, address.getAreaId()); - throw exception(PRODUCT_EXPRESS_TEMPLATE_NOT_FOUND); + if (CollUtil.isEmpty(expressTemplateMap)) { + log.error("[calculate][找不到商品 templateIds {} areaId{} 对应的运费模板]", deliveryTemplateIds, address.getAreaId()); + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND); } - calculateDeliveryPrice(selectedItem, spuExpressTemplateMap, result); + calculateDeliveryPrice(selectedItem, expressTemplateMap, result); } private void calculateDeliveryPrice(List selectedSkus, - Map spuExpressTemplateMap, + Map expressTemplateMap, TradePriceCalculateRespBO result) { - // 按 SPU 来计算商品的运费:一个 spuId 可能对应多条订单商品 SKU - Map> spuIdItemMap = convertMultiMap(selectedSkus, OrderItem::getSpuId); - // 依次计算每个 SPU 的快递运费 - for (Map.Entry> entry : spuIdItemMap.entrySet()) { - Long spuId = entry.getKey(); + // 按商品运费模板来计算商品的运费:相同的运费模板可能对应多条订单商品 SKU + Map> tplIdItemMap = convertMultiMap(selectedSkus, OrderItem::getDeliveryTemplateId); + // 依次计算快递运费 + for (Map.Entry> entry : tplIdItemMap.entrySet()) { + Long templateId = entry.getKey(); List orderItems = entry.getValue(); - SpuDeliveryExpressTemplateRespBO templateBO = spuExpressTemplateMap.get(spuId); + DeliveryExpressTemplateRespBO templateBO = expressTemplateMap.get(templateId); if (templateBO == null) { - log.error("不能计算快递运费。不能找到 spuId : {}. 对应的运费模板配置 Resp BO", spuId); + log.error("不能计算快递运费。不能找到 templateId : {}. 对应的运费模板配置 Resp BO", templateId); continue; } // 总件数, 总金额, 总重量, 总体积 @@ -117,7 +115,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品项目 */ private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume, - int chargeMode, DeliveryExpressTemplateChargeBO templateCharge, + int chargeMode, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { if (templateCharge == null) { log.error("计算快递运费时,不能找到对应的快递运费模板费用配置。无法计算以下商品 SKU 项目运费: {}", orderItems); @@ -147,7 +145,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateCharge 快递运费配置 * @param orderItems SKU 商品项目 */ - private void calculateExpressFee(double total, DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { + private void calculateExpressFee(double total, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { int deliveryPrice; if (total <= templateCharge.getStartCount()) { deliveryPrice = templateCharge.getStartPrice(); @@ -192,7 +190,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateFree 包邮配置 */ private boolean isExpressFree(Integer chargeMode, int totalCount, double totalWeight, - double totalVolume, int totalPrice, DeliveryExpressTemplateFreeBO templateFree) { + double totalVolume, int totalPrice, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO templateFree) { if (templateFree == null) { return false; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index 7945c72eb..bd3d3b5be 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -56,7 +56,8 @@ public class TradePriceCalculatorHelper { orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()) .setWeight(sku.getWeight()).setVolume(sku.getVolume()); // spu 信息 - orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()); + orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()) + .setDeliveryTemplateId(spu.getDeliveryTemplateId()); if (orderItem.getPicUrl() == null) { orderItem.setPicUrl(spu.getPicUrl()); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java index e6af92430..99fdac64e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java @@ -4,9 +4,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateChargeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateFreeBO; -import cn.iocoder.yudao.module.trade.service.delivery.bo.SpuDeliveryExpressTemplateRespBO; +import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import org.junit.jupiter.api.BeforeEach; @@ -44,9 +42,9 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { private TradePriceCalculateReqBO reqBO; private TradePriceCalculateRespBO resultBO; private AddressRespDTO addressResp; - private DeliveryExpressTemplateChargeBO chargeBO; - private DeliveryExpressTemplateFreeBO freeBO; - private SpuDeliveryExpressTemplateRespBO spuTemplateRespBO; + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO chargeBO; + private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO freeBO; + private DeliveryExpressTemplateRespBO templateRespBO; @BeforeEach public void init(){ @@ -64,11 +62,11 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { .setPrice(new TradePriceCalculateRespBO.Price()) .setPromotions(new ArrayList<>()) .setItems(asList( - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(10L).setCount(2).setSelected(true) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(10L).setCount(2).setSelected(true) .setWeight(10d).setVolume(10d).setPrice(100), - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(20L).setCount(10).setSelected(true) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(20L).setCount(10).setSelected(true) .setWeight(10d).setVolume(10d).setPrice(200), - new TradePriceCalculateRespBO.OrderItem().setSpuId(1L).setSkuId(30L).setCount(1).setSelected(false) + new TradePriceCalculateRespBO.OrderItem().setDeliveryTemplateId(1L).setSkuId(30L).setCount(1).setSelected(false) .setWeight(10d).setVolume(10d).setPrice(300) )); // 保证价格被初始化上 @@ -77,13 +75,13 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // 准备收件地址数据 addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); // 准备运费模板费用配置数据 - chargeBO = randomPojo(DeliveryExpressTemplateChargeBO.class, + chargeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO.class, item -> item.setStartCount(10D).setStartPrice(1000).setExtraCount(10D).setExtraPrice(2000)); // 准备运费模板包邮配置数据 订单总件数 < 包邮件数时 12 < 20 - freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, item -> item.setFreeCount(20).setFreePrice(100)); // 准备 SP 运费模板 数据 - spuTemplateRespBO = randomPojo(SpuDeliveryExpressTemplateRespBO.class, + templateRespBO = randomPojo(DeliveryExpressTemplateRespBO.class, item -> item.setChargeMode(PIECE.getType()) .setTemplateCharge(chargeBO).setTemplateFree(freeBO)); } @@ -94,12 +92,12 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 首件 1000 + 续件 2000 = 3000 - Map respMap = new HashMap<>(); - respMap.put(1L, spuTemplateRespBO); + Map respMap = new HashMap<>(); + respMap.put(1L, templateRespBO); // mock 方法 when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); - when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) .thenReturn(respMap); calculator.calculate(reqBO, resultBO); @@ -131,15 +129,15 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 0 - Map respMap = new HashMap<>(); - respMap.put(1L, spuTemplateRespBO); + Map respMap = new HashMap<>(); + respMap.put(1L, templateRespBO); // 准备运费模板包邮配置数据 包邮 订单总件数 > 包邮件数时 12 > 10 - freeBO = randomPojo(DeliveryExpressTemplateFreeBO.class, + freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, item -> item.setFreeCount(10).setFreePrice(1000)); - spuTemplateRespBO.setTemplateFree(freeBO); + templateRespBO.setTemplateFree(freeBO); // mock 方法 when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); - when(deliveryExpressTemplateService.getExpressTemplateMapBySpuIdsAndArea(eq(asSet(1L)), eq(10))) + when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) .thenReturn(respMap); calculator.calculate(reqBO, resultBO); From 1662d17fc97c824e5373c28809e5f6b075538ec5 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 15 Jun 2023 14:59:31 +0800 Subject: [PATCH 111/232] =?UTF-8?q?=E5=BF=AB=E9=80=92=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=20review=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 7 +- .../delivery/config/ExpressClientConfig.java | 31 ++++++++ ...rties.java => TradeExpressProperties.java} | 17 ++--- .../delivery/core/ExpressQueryClient.java | 24 ------- .../delivery/core/ExpressQueryProvider.java | 22 ------ .../core/ExpressQueryProviderFactory.java | 19 ----- .../delivery/core/client/ExpressClient.java | 23 ++++++ .../ExpressClientEnum.java} | 13 ++-- .../core/client/ExpressClientFactory.java | 23 ++++++ .../client/convert/ExpressQueryConvert.java | 27 +++++++ .../{ => client}/dto/ExpressQueryReqDTO.java | 5 +- .../{ => client}/dto/ExpressQueryRespDTO.java | 2 +- .../dto}/kd100/Kd100ExpressQueryReqDTO.java | 5 +- .../dto}/kd100/Kd100ExpressQueryRespDTO.java | 2 +- .../dto}/kdniao/KdNiaoExpressQueryReqDTO.java | 5 +- .../kdniao/KdNiaoExpressQueryRespDTO.java | 2 +- .../client/impl/ExpressClientFactoryImpl.java | 56 +++++++++++++++ .../impl/Kd100ExpressClient.java} | 70 ++++++++----------- .../impl/KdNiaoExpressClient.java} | 67 ++++++++---------- .../client/impl/NoProvideExpressClient.java | 22 ++++++ .../core/convert/ExpressQueryConvert.java | 27 ------- .../core/impl/ExpressQueryClientImpl.java | 65 ----------------- .../impl/ExpressQueryProviderFactoryImpl.java | 48 ------------- .../impl/Kd100ExpressClientTest.java} | 26 +++---- .../impl/KdNiaoExpressClientTest.java} | 24 +++---- .../impl/NoProvideExpressClientTest.java | 52 ++++++++++++++ .../application-trade-delivery-query.yaml | 18 ----- .../test/resources/application-unit-test.yaml | 8 +++ 28 files changed, 351 insertions(+), 359 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/{TradeExpressQueryProperties.java => TradeExpressProperties.java} (70%) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{ExpressQueryProviderEnum.java => client/ExpressClientEnum.java} (58%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{ => client}/dto/ExpressQueryReqDTO.java (71%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{ => client}/dto/ExpressQueryRespDTO.java (81%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{dto/provider => client/dto}/kd100/Kd100ExpressQueryReqDTO.java (80%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{dto/provider => client/dto}/kd100/Kd100ExpressQueryRespDTO.java (93%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{dto/provider => client/dto}/kdniao/KdNiaoExpressQueryReqDTO.java (74%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{dto/provider => client/dto}/kdniao/KdNiaoExpressQueryRespDTO.java (94%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{impl/Kd100ExpressQueryProvider.java => client/impl/Kd100ExpressClient.java} (58%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{impl/KdNiaoExpressQueryProvider.java => client/impl/KdNiaoExpressClient.java} (62%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java rename yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{impl/Kd100ExpressQueryProviderTest.java => client/impl/Kd100ExpressClientTest.java} (62%) rename yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{impl/KdNiaoExpressQueryProviderTest.java => client/impl/KdNiaoExpressClientTest.java} (61%) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 800b5f239..12d921a88 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -51,9 +51,10 @@ public interface ErrorCodeConstants { ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); - ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003006, "快递查询接口异常"); - ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003007, "快递查询返回失败, 原因:{}"); - ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003008, "自提门店不存在"); + ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003004, "快递查询接口异常"); + ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003005, "快递查询返回失败, 原因:{}"); + ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011003006, "需要接入快递服务商,比如【快递100】"); + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003007, "自提门店不存在"); // ========== Price 相关 1011004000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java new file mode 100644 index 000000000..e93c0a70b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.config; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.ExpressClientFactoryImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * 快递客户端端配置类, 提供快递客户端工厂,默认的快递客户端实现 + * + * @author jason + */ +@Configuration( + proxyBeanMethods = false +) +public class ExpressClientConfig { + + @Bean + public ExpressClientFactory expressClientFactory(TradeExpressProperties tradeExpressProperties, + RestTemplate restTemplate) { + return new ExpressClientFactoryImpl(tradeExpressProperties, restTemplate); + } + + @Bean + public ExpressClient defaultExpressClient(ExpressClientFactory expressClientFactory) { + return expressClientFactory.getDefaultExpressClient(); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java similarity index 70% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java index be0f93414..5f593df8b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressQueryProperties.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.framework.delivery.config; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientEnum; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -9,27 +9,24 @@ import org.springframework.validation.annotation.Validated; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; -// TODO @jason:TradeExpressProperties;更通用哈 // TODO @芋艿:未来要不要放数据库中?考虑 saas 多租户时,不同租户使用不同的配置? /** - * 交易快递查询的配置项 + * 交易运费快递的配置项 * * @author jason */ @Component -@ConfigurationProperties(prefix = "yudao.trade.express.query") +@ConfigurationProperties(prefix = "yudao.trade.express") @Data @Validated -public class TradeExpressQueryProperties { +public class TradeExpressProperties { /** - * 快递查询服务商 + * 快递客户端 * - * 如果未配置,默认使用快递鸟 + * 默认不提供,需要提醒用户配置一个快递服务商。 */ - // TODO @jason:可以把 expressQueryProvider 改成 client 变量,更简洁一点; - private ExpressQueryProviderEnum expressQueryProvider; // TODO @jaosn:默认值可以通过属性直接赋值哈; - // TODO @jason:需要考虑下,用户只配置了其中一个; + private ExpressClientEnum client = ExpressClientEnum.NOT_PROVIDE; /** * 快递鸟配置 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java deleted file mode 100644 index 1494bb2e5..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryClient.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core; - -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; - -import java.util.List; - -// TODO @jason:可以改成 ExpressClient,未来可能还对接别的接口噢 -/** - * 快递查询客户端 - * - * @author jason - */ -public interface ExpressQueryClient { - - /** - * 快递实时查询 - * - * @param reqDTO 查询请求参数 - */ - // TODO @jason:可以改成 getExpressTrackList。返回字段可以参考 https://doc.youzanyun.com/detail/API/0/5 响应的 data - List realTimeQuery(ExpressQueryReqDTO reqDTO); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java deleted file mode 100644 index e741e1426..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProvider.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core; - -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; - -import java.util.List; - -/** - * 快递查询服务商 - * - * @author jason - */ -public interface ExpressQueryProvider { - - /** - * 快递实时查询 - * - * @param reqDTO 查询请求参数 - */ - List realTimeQueryExpress(ExpressQueryReqDTO reqDTO); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java deleted file mode 100644 index bad2c6a5d..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core; - -/** - * 快递服务商工厂,用于创建和缓存快递服务商服务 - * - * @author jason - */ -public interface ExpressQueryProviderFactory { - - /** - * 通过枚举获取快递查询服务商 - * - * 如果不存在,就创建一个对应的快递查询服务商 - * - * @param queryProviderEnum 快递服务商枚举 - */ - ExpressQueryProvider getOrCreateExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java new file mode 100644 index 000000000..b670313c5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; + +import java.util.List; + +/** + * 快递客户端接口 + * + * @author jason + */ +public interface ExpressClient { + + /** + * 快递实时查询 + * + * @param reqDTO 查询请求参数 + */ + // TODO @jason:返回字段可以参考 https://doc.youzanyun.com/detail/API/0/5 响应的 data + List getExpressTrackList(ExpressQueryReqDTO reqDTO); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java similarity index 58% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java index 48dab7eec..756252e61 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/ExpressQueryProviderEnum.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java @@ -1,16 +1,15 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client; import lombok.Getter; /** - * 快递查询服务商枚举 + * 快递客户端枚举 * * @author jason */ @Getter - -public enum ExpressQueryProviderEnum { - +public enum ExpressClientEnum { + NOT_PROVIDE("not-provide","未提供"), KD_NIAO("kd-niao", "快递鸟"), KD_100("kd-100", "快递100"); @@ -24,10 +23,8 @@ public enum ExpressQueryProviderEnum { */ private final String name; - // TODO @jaosn:@AllArgsConstructor 可以替代哈 - ExpressQueryProviderEnum(String code, String name) { + ExpressClientEnum(String code, String name) { this.code = code; this.name = name; } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java new file mode 100644 index 000000000..f6a54dd8f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client; + +/** + * 快递客户端工厂接口,快递客户端工厂:用于创建和缓存快递客户端 + * + * @author jason + */ +public interface ExpressClientFactory { + + /** + * 获取默认的快递客户端 + */ + ExpressClient getDefaultExpressClient(); + + /** + * 通过枚举获取快递客户端,如果不存在,就创建一个对应快递客户端 + * + * @param clientEnum 快递客户端枚举 + */ + ExpressClient getOrCreateExpressClient(ExpressClientEnum clientEnum); + + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java new file mode 100644 index 000000000..14a2c1c98 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.convert; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryRespDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface ExpressQueryConvert { + + ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class); + + List convertList(List expressTrackList); + + List convertList2(List expressTrackList); + + KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); + + Kd100ExpressQueryReqDTO convert2(ExpressQueryReqDTO dto); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java similarity index 71% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java index ffa72c532..ea579a170 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import lombok.Data; @@ -16,8 +16,7 @@ public class ExpressQueryReqDTO { * * 对应 {@link DeliveryExpressDO#getCode()} */ - // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 - private String expressCompanyCode; + private String expressCode; /** * 发货快递单号 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java similarity index 81% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java index 0bdb386c4..a2aad9025 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryReqDTO.java similarity index 80% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryReqDTO.java index d1b72426f..78bdada31 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryReqDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -13,12 +13,11 @@ import lombok.Data; @JsonInclude(JsonInclude.Include.NON_NULL) public class Kd100ExpressQueryReqDTO { - // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 /** * 快递公司编码 */ @JsonProperty("com") - private String expressCompanyCode; + private String expressCode; /** * 快递单号 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java similarity index 93% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java index f7e5bdf04..6a301f4e4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kd100/Kd100ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryReqDTO.java similarity index 74% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryReqDTO.java index 21b1abc58..bcb6e3353 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryReqDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -13,12 +13,11 @@ import lombok.Data; @JsonInclude(JsonInclude.Include.NON_NULL) public class KdNiaoExpressQueryReqDTO { - // TODO @jaosn:要不改成 expressCode;项目里使用这个哈 /** * 快递公司编码 */ @JsonProperty("ShipperCode") - private String expressCompanyCode; + private String expressCode; /** * 快递单号 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryRespDTO.java similarity index 94% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryRespDTO.java index 3e8883bbd..877b1206d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/dto/provider/kdniao/KdNiaoExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryRespDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java new file mode 100644 index 000000000..96666bfef --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientEnum; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 快递客户端工厂实现类 + * + * @author jason + */ +public class ExpressClientFactoryImpl implements ExpressClientFactory { + + private final Map clientMap = new ConcurrentHashMap<>(8); + + private final TradeExpressProperties tradeExpressProperties; + private final RestTemplate restTemplate; + + public ExpressClientFactoryImpl(TradeExpressProperties tradeExpressProperties, + RestTemplate restTemplate) { + this.tradeExpressProperties = tradeExpressProperties; + this.restTemplate = restTemplate; + } + + @Override + public ExpressClient getDefaultExpressClient() { + ExpressClient defaultClient = getOrCreateExpressClient(tradeExpressProperties.getClient()); + Assert.notNull("默认的快递客户端不能为空"); + return defaultClient; + } + + @Override + public ExpressClient getOrCreateExpressClient(ExpressClientEnum clientEnum) { + return clientMap.computeIfAbsent(clientEnum, + client -> createExpressClient(client, tradeExpressProperties)); + } + + private ExpressClient createExpressClient(ExpressClientEnum queryProviderEnum, + TradeExpressProperties tradeExpressProperties) { + switch (queryProviderEnum) { + case NOT_PROVIDE: + return new NoProvideExpressClient(); + case KD_NIAO: + return new KdNiaoExpressClient(restTemplate, tradeExpressProperties.getKdNiao()); + case KD_100: + return new Kd100ExpressClient(restTemplate, tradeExpressProperties.getKd100()); + } + return null; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java similarity index 58% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java index 4227cebc8..930d5d8d9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java @@ -1,15 +1,16 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.digest.DigestUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryRespDTO; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.util.LinkedMultiValueMap; @@ -23,48 +24,41 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_ERROR; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; -import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; +import static cn.iocoder.yudao.module.trade.framework.delivery.core.client.convert.ExpressQueryConvert.INSTANCE; -// TODO @jason:可以参考 KdNiaoExpressQueryProvider 建议改改哈 /** - * 快递 100 服务商 + * 快递 100 客户端 * * @author jason */ @Slf4j -public class Kd100ExpressQueryProvider implements ExpressQueryProvider { +@AllArgsConstructor +public class Kd100ExpressClient implements ExpressClient { private static final String REAL_TIME_QUERY_URL = "https://poll.kuaidi100.com/poll/query.do"; - private final RestTemplate restTemplate; - private final TradeExpressQueryProperties.Kd100Config config; - - public Kd100ExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.Kd100Config config) { - this.restTemplate = restTemplate; - this.config = config; - } + private final TradeExpressProperties.Kd100Config config; @Override - public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { + public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { // 发起查询 Kd100ExpressQueryReqDTO kd100ReqParam = INSTANCE.convert2(reqDTO); - kd100ReqParam.setExpressCompanyCode(kd100ReqParam.getExpressCompanyCode().toLowerCase()); // 快递公司编码需要转成小写 - Kd100ExpressQueryRespDTO respDTO = sendExpressQueryReq(REAL_TIME_QUERY_URL, kd100ReqParam, + kd100ReqParam.setExpressCode(kd100ReqParam.getExpressCode().toLowerCase()); // 快递公司编码需要转成小写 + Kd100ExpressQueryRespDTO respDTO = requestExpressQuery(REAL_TIME_QUERY_URL, kd100ReqParam, Kd100ExpressQueryRespDTO.class); - log.debug("[realTimeQueryExpress][快递 100 接口 查询接口返回 {}]", respDTO); + log.debug("[getExpressTrackList][快递 100 接口 查询接口返回 {}]", respDTO); // 处理结果 if (Objects.equals("false", respDTO.getResult())) { - log.error("[realTimeQueryExpress][快递 100 接口 返回失败 {}]", respDTO.getMessage()); + log.error("[getExpressTrackList][快递 100 接口 返回失败 {}]", respDTO.getMessage()); throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage()); - // TODO @json:else 可以不用写哈; - } else { - // TODO @jason:convertList2 如果空,应该返回 list 了; - if (CollUtil.isNotEmpty(respDTO.getTracks())) { - return INSTANCE.convertList2(respDTO.getTracks()); - } else { - return Collections.emptyList(); - } } + // TODO @jason:convertList2 如果空,应该返回 list 了; @芋艿 为了避免返回 null + if (CollUtil.isNotEmpty(respDTO.getTracks())) { + return INSTANCE.convertList2(respDTO.getTracks()); + } else { + return Collections.emptyList(); + } + } /** @@ -76,8 +70,7 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { * @param 每个请求的请求结构 Req DTO * @param 每个请求的响应结构 Resp DTO */ - // TODO @jason:可以改成 request,发起请求哈; - private Resp sendExpressQueryReq(String url, Req req, Class respClass) { + private Resp requestExpressQuery(String url, Req req, Class respClass) { // 请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -92,23 +85,20 @@ public class Kd100ExpressQueryProvider implements ExpressQueryProvider { log.debug("[sendExpressQueryReq][快递 100 接口的请求参数: {}]", requestBody); // 发送请求 HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); - // TODO @jason:可以使用 restTemplate 的 post 方法哇? + // TODO @jason:可以使用 restTemplate 的 post 方法哇 @芋艿 为了获取接口的原始返回。用exchange 便于查问题。 ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); log.debug("[sendExpressQueryReq][快递 100 接口响应结果 {}]", responseEntity); // 处理响应 - // TODO @jason:if return 原则;if (!responseEntity.getStatusCode().is2xxSuccessful()) 抛出异常;接着处理成功的 - if (responseEntity.getStatusCode().is2xxSuccessful()) { - String response = responseEntity.getBody(); - return JsonUtils.parseObject(response, respClass); - } else { + if (!responseEntity.getStatusCode().is2xxSuccessful()) { throw exception(EXPRESS_API_QUERY_ERROR); } + return JsonUtils.parseObject(responseEntity.getBody(), respClass); } private String generateReqSign(String param, String key, String customer) { String plainText = String.format("%s%s%s", param, key, customer); - // TODO @jason:DigestUtil.md5Hex(plainText); + // TODO @芋艿。 这里需要转换成大写, 没有对应方法 return HexUtil.encodeHexStr(DigestUtil.md5(plainText), false); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java similarity index 62% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java index 4ca5f6142..1e5e5f535 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProvider.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java @@ -1,16 +1,17 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.net.URLEncodeUtil; import cn.hutool.crypto.digest.DigestUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryRespDTO; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.util.LinkedMultiValueMap; @@ -23,15 +24,16 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_FAILED; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_API_QUERY_ERROR; -import static cn.iocoder.yudao.module.trade.framework.delivery.core.convert.ExpressQueryConvert.INSTANCE; +import static cn.iocoder.yudao.module.trade.framework.delivery.core.client.convert.ExpressQueryConvert.INSTANCE; /** - * 快递鸟服务商 + * 快递鸟客户端 * * @author jason */ @Slf4j -public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { +@AllArgsConstructor +public class KdNiaoExpressClient implements ExpressClient { private static final String REAL_TIME_QUERY_URL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"; @@ -39,15 +41,8 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { * 快递鸟即时查询免费版 RequestType */ private static final String REAL_TIME_FREE_REQ_TYPE = "1002"; - private final RestTemplate restTemplate; - private final TradeExpressQueryProperties.KdNiaoConfig config; - - // TODO @jason:可以改成 lombok 哈 - public KdNiaoExpressQueryProvider(RestTemplate restTemplate, TradeExpressQueryProperties.KdNiaoConfig config) { - this.restTemplate = restTemplate; - this.config = config; - } + private final TradeExpressProperties.KdNiaoConfig config; /** * 快递鸟即时查询免费版本 @@ -56,21 +51,20 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { * @param reqDTO 查询请求参数 */ @Override - public List realTimeQueryExpress(ExpressQueryReqDTO reqDTO) { + public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { KdNiaoExpressQueryReqDTO kdNiaoReqData = INSTANCE.convert(reqDTO); // 快递公司编码需要转成大写 - kdNiaoReqData.setExpressCompanyCode(reqDTO.getExpressCompanyCode().toUpperCase()); - KdNiaoExpressQueryRespDTO respDTO = sendKdNiaoApiRequest(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, + kdNiaoReqData.setExpressCode(reqDTO.getExpressCode().toUpperCase()); + KdNiaoExpressQueryRespDTO respDTO = requestKdNiaoApi(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, kdNiaoReqData, KdNiaoExpressQueryRespDTO.class); - log.debug("[realTimeQueryExpress][快递鸟即时查询接口返回 {}]", respDTO); - if(!respDTO.getSuccess()){ - throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getReason()); - }else{ - if (CollUtil.isNotEmpty(respDTO.getTracks())) { - return INSTANCE.convertList(respDTO.getTracks()); - }else{ - return Collections.emptyList(); - } + log.debug("[getExpressTrackList][快递鸟即时查询接口返回 {}]", respDTO); + if (respDTO == null || !respDTO.getSuccess()) { + throw exception(EXPRESS_API_QUERY_FAILED, respDTO == null ? "" : respDTO.getReason()); + } + if (CollUtil.isNotEmpty(respDTO.getTracks())) { + return INSTANCE.convertList(respDTO.getTracks()); + } else { + return Collections.emptyList(); } } @@ -83,8 +77,8 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { * @param 每个请求的请求结构 Req DTO * @param 每个请求的响应结构 Resp DTO */ - private Resp sendKdNiaoApiRequest(String url, String requestType, Req req, - Class respClass){ + private Resp requestKdNiaoApi(String url, String requestType, Req req, + Class respClass){ // 请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -97,19 +91,16 @@ public class KdNiaoExpressQueryProvider implements ExpressQueryProvider { requestBody.add("EBusinessID", config.getBusinessId()); requestBody.add("DataSign", dataSign); requestBody.add("RequestType", requestType); - log.debug("[sendKdNiaoApiRequest][快递鸟接口 RequestType : {}, 的请求参数 {}]", requestType, requestBody); - + log.debug("[requestKdNiaoApi][快递鸟接口 RequestType : {}, 的请求参数 {}]", requestType, requestBody); // 发送请求 HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); log.debug("快递鸟接口 RequestType : {}, 的响应结果 {}", requestType, responseEntity); // 处理响应 - if (responseEntity.getStatusCode().is2xxSuccessful()) { - String response = responseEntity.getBody(); - return JsonUtils.parseObject(response, respClass); - } else { + if (!responseEntity.getStatusCode().is2xxSuccessful()) { throw exception(EXPRESS_API_QUERY_ERROR); } + return JsonUtils.parseObject(responseEntity.getBody(), respClass); } /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java new file mode 100644 index 000000000..b4b9403a7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; + +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_CLIENT_NOT_PROVIDE; + +/** + * 未实现的快递客户端,用来提醒用户需要接入快递服务商, + * + * @author jason + */ +public class NoProvideExpressClient implements ExpressClient { + @Override + public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { + throw exception(EXPRESS_CLIENT_NOT_PROVIDE); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java deleted file mode 100644 index 615f84b4e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/convert/ExpressQueryConvert.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.convert; - -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kd100.Kd100ExpressQueryRespDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.provider.kdniao.KdNiaoExpressQueryRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -@Mapper -public interface ExpressQueryConvert { - - ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class); - - List convertList(List expressTrackList); - - List convertList2(List expressTrackList); - - KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); - - Kd100ExpressQueryReqDTO convert2(ExpressQueryReqDTO dto); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java deleted file mode 100644 index 59dfc77c1..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryClientImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; - -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryClient; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderFactory; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryRespDTO; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum.KD_NIAO; - -// TODO @jason:可以把整体包结构调整下;参考 sms client 的方式; -// + config -// + core -// client -// + dto -// + impl:里面可以放 kdniaoclient、kd100client -// ExpressClient -// ExpressClientFactory: 通过它直接获取默认和创建默认的 Client -// enums -/** - * 快递查询客户端实现 - * - * @author jason - */ -@Component -@Slf4j -public class ExpressQueryClientImpl implements ExpressQueryClient { - - @Resource - private ExpressQueryProviderFactory expressQueryProviderFactory; - @Resource - private TradeExpressQueryProperties tradeExpressQueryProperties; - - private ExpressQueryProvider expressQueryProvider; - - @PostConstruct - private void init() { - // 如果未设置,默认使用快递鸟 - ExpressQueryProviderEnum queryProvider = tradeExpressQueryProperties.getExpressQueryProvider(); - if (queryProvider == null) { - queryProvider = KD_NIAO; - } - // 创建客户端 - expressQueryProvider = expressQueryProviderFactory.getOrCreateExpressQueryProvider(queryProvider); - if (expressQueryProvider == null) { - log.error("获取创建快递查询服务商{}失败,请检查相关配置", queryProvider); - } - Assert.notNull(expressQueryProvider, "快递查询服务商不能为空"); - } - - @Override - public List realTimeQuery(ExpressQueryReqDTO reqDTO) { - return expressQueryProvider.realTimeQueryExpress(reqDTO); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java deleted file mode 100644 index b6ce8d68a..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/ExpressQueryProviderFactoryImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; - -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProvider; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderEnum; -import cn.iocoder.yudao.module.trade.framework.delivery.core.ExpressQueryProviderFactory; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import javax.annotation.Resource; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * // TODO @jason:注释不全 - * @author jason - */ -@Component -public class ExpressQueryProviderFactoryImpl implements ExpressQueryProviderFactory { - - private final Map providerMap = new ConcurrentHashMap<>(8); - - @Resource - private TradeExpressQueryProperties tradeExpressQueryProperties; - @Resource - private RestTemplate restTemplate; - - @Override - public ExpressQueryProvider getOrCreateExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum) { - return providerMap.computeIfAbsent(queryProviderEnum, - provider -> createExpressQueryProvider(provider, tradeExpressQueryProperties)); - } - - private ExpressQueryProvider createExpressQueryProvider(ExpressQueryProviderEnum queryProviderEnum, - TradeExpressQueryProperties tradeExpressQueryProperties) { - // TODO @jason:是不是直接 return 就好啦,更简洁一点 - ExpressQueryProvider result = null; - switch (queryProviderEnum) { - case KD_NIAO: - result = new KdNiaoExpressQueryProvider(restTemplate, tradeExpressQueryProperties.getKdNiao()); - break; - case KD_100: - result = new Kd100ExpressQueryProvider(restTemplate, tradeExpressQueryProperties.getKd100()); - break; - } - return result; - } -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java similarity index 62% rename from yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java rename to yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java index 0d82f745b..6fa41e314 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/Kd100ExpressQueryProviderTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java @@ -1,8 +1,8 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -21,36 +21,36 @@ import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author jason */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Kd100ExpressQueryProviderTest.Application.class) -@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 -public class Kd100ExpressQueryProviderTest { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Kd100ExpressClientTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 trade-delivery-query 配置文件 +public class Kd100ExpressClientTest { @Resource private RestTemplateBuilder builder; @Resource - private TradeExpressQueryProperties expressQueryProperties; + private TradeExpressProperties expressQueryProperties; - private Kd100ExpressQueryProvider kd100ExpressQueryProvider; + private Kd100ExpressClient kd100ExpressClient; @BeforeEach public void init(){ - kd100ExpressQueryProvider = new Kd100ExpressQueryProvider(builder.build(),expressQueryProperties.getKd100()); + kd100ExpressClient = new Kd100ExpressClient(builder.build(),expressQueryProperties.getKd100()); } @Test @Disabled("需要 授权 key. 暂时忽略") void testRealTimeQueryExpressFailed() { ServiceException t = assertThrows(ServiceException.class, () -> { ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); - reqDTO.setExpressCompanyCode("yto"); + reqDTO.setExpressCode("yto"); reqDTO.setLogisticsNo("YT9383342193097"); - kd100ExpressQueryProvider.realTimeQueryExpress(reqDTO); + kd100ExpressClient.getExpressTrackList(reqDTO); }); - assertEquals(1011003007, t.getCode()); + assertEquals(1011003005, t.getCode()); } @Import({ RestTemplateAutoConfiguration.class }) - @EnableConfigurationProperties(TradeExpressQueryProperties.class) + @EnableConfigurationProperties(TradeExpressProperties.class) public static class Application { } } \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java similarity index 61% rename from yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java rename to yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java index 8f6615678..ebf38d0b7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/impl/KdNiaoExpressQueryProviderTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java @@ -1,8 +1,8 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressQueryProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -21,35 +21,35 @@ import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author jason */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressQueryProviderTest.Application.class) -@ActiveProfiles("trade-delivery-query") // 设置使用 trade-delivery-query 配置文件 TODO @jason:可以直接写到 application-unit-test.yaml 配置文件里 -public class KdNiaoExpressQueryProviderTest { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressClientTest.Application.class) +@ActiveProfiles("unit-test") +public class KdNiaoExpressClientTest { @Resource private RestTemplateBuilder builder; @Resource - private TradeExpressQueryProperties expressQueryProperties; + private TradeExpressProperties expressQueryProperties; - private KdNiaoExpressQueryProvider kdNiaoExpressQueryProvider; + private KdNiaoExpressClient kdNiaoExpressClient; @BeforeEach public void init(){ - kdNiaoExpressQueryProvider = new KdNiaoExpressQueryProvider(builder.build(),expressQueryProperties.getKdNiao()); + kdNiaoExpressClient = new KdNiaoExpressClient(builder.build(),expressQueryProperties.getKdNiao()); } @Test @Disabled("需要 授权 key. 暂时忽略") void testRealTimeQueryExpressFailed() { assertThrows(ServiceException.class,() ->{ ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); - reqDTO.setExpressCompanyCode("yy"); + reqDTO.setExpressCode("yy"); reqDTO.setLogisticsNo("YT9383342193097"); - kdNiaoExpressQueryProvider.realTimeQueryExpress(reqDTO); + kdNiaoExpressClient.getExpressTrackList(reqDTO); }); } @Import({ RestTemplateAutoConfiguration.class }) - @EnableConfigurationProperties(TradeExpressQueryProperties.class) + @EnableConfigurationProperties(TradeExpressProperties.class) public static class Application { } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java new file mode 100644 index 000000000..76b8cd6b4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.trade.framework.delivery.config.ExpressClientConfig; +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @author jason + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = NoProvideExpressClientTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 trade-delivery-query 配置文件 +@Import({ExpressClientConfig.class}) +public class NoProvideExpressClientTest { + + @Resource + private ExpressClient expressClient; + + @Test + void getExpressTrackList() { + ServiceException t = assertThrows(ServiceException.class, () -> { + expressClient.getExpressTrackList(null); + }); + assertEquals(1011003006, t.getCode()); + } + + @Import({ + RestTemplateAutoConfiguration.class, + }) + @EnableConfigurationProperties(TradeExpressProperties.class) + public static class Application { + + @Bean + private RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder.build(); + } + } +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml deleted file mode 100644 index e01cb1652..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-trade-delivery-query.yaml +++ /dev/null @@ -1,18 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 交易快递查询相关配置 #################### - -yudao: - trade: - express: - query: - express-query-provider: kd_niao - kd-niao: - api-key: xxx - business-id: xxxxxxxx - kd100: - customer: xxxx - key: xxxxx diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml index 19dd0e97b..b548da6a3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml @@ -51,3 +51,11 @@ yudao: order: app-id: 1 merchant-order-id: 1 + express: + kd-niao: + api-key: xxxx + business-id: xxxxx + kd100: + customer: xxxxx + key: xxxxx + client: not_provide \ No newline at end of file From af9334c9b23567a79e091fede55cd977358227ac Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 16 Jun 2023 00:12:49 +0800 Subject: [PATCH 112/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Amock=20?= =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E8=AE=B0=E5=BD=95=E8=AF=A6=E6=83=85=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... => AppCombinationActivityController.java} | 8 +- .../AppCombinationRecordController.java | 78 +++++++++++++++++++ .../AppCombinationActivityDetailRespVO.java | 21 ++--- .../AppCombinationRecordDetailRespVO.java | 21 +++++ .../AppCombinationRecordSimpleRespVO.java | 30 +++++++ .../vo/AppSeckillActivitiDetailRespVO.java | 3 - 6 files changed, 140 insertions(+), 21 deletions(-) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/{AppCombinationController.java => AppCombinationActivityController.java} (92%) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java similarity index 92% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java index cd6d142a2..ba4c01e9a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java @@ -21,7 +21,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RestController @RequestMapping("/promotion/combination-activity") @Validated -public class AppCombinationController { +public class AppCombinationActivityController { @GetMapping("/get-detail") @Operation(summary = "获得拼团活动明细") @@ -33,8 +33,10 @@ public class AppCombinationController { obj.setId(id); obj.setName("晚九点限时秒杀"); obj.setStatus(1); - obj.setStartTime(LocalDateTime.of(2023, 6, 11, 0, 0, 0)); - obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0)); + obj.setStartTime(LocalDateTime.of(2023, 6, 15, 0, 0, 0)); + obj.setEndTime(LocalDateTime.of(2023, 6, 15, 23, 59, 0)); + obj.setUserSize(2); + obj.setSuccessCount(100); obj.setSpuId(633L); // 创建一个Product对象的列表 List productList = new ArrayList<>(); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java new file mode 100644 index 000000000..1e32111f1 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSimpleRespVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.constraints.Max; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 拼团活动") +@RestController +@RequestMapping("/promotion/combination-record") +@Validated +public class AppCombinationRecordController { + + @GetMapping("/get-head-list") + @Operation(summary = "获得最近 n 条拼团记录(团长发起的)") + public CommonResult> getHeadCombinationRecordList( + @RequestParam("status") Integer status, + @RequestParam(value = "count", defaultValue = "20") @Max(20) Integer count) { + List list = new ArrayList<>(); + for (int i = 1; i <= count; i++) { + AppCombinationRecordSimpleRespVO record = new AppCombinationRecordSimpleRespVO(); + record.setId((long) i); + record.setNickname("用户" + i); + record.setAvatar("头像" + i); + record.setExpireTime(new Date()); + record.setUserSize(10); + record.setUserCount(i); + list.add(record); + } + return success(list); + } + + @GetMapping("/get-detail") + @Operation(summary = "获得拼团记录明细") + @Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024") + public CommonResult getCombinationRecordDetail(@RequestParam("id") Long id) { + AppCombinationRecordDetailRespVO detail = new AppCombinationRecordDetailRespVO(); + // 团长 + AppCombinationRecordSimpleRespVO headRecord = new AppCombinationRecordSimpleRespVO(); + headRecord.setId(1L); + headRecord.setNickname("用户" + 1); + headRecord.setAvatar("头像" + 1); + headRecord.setExpireTime(new Date()); + headRecord.setUserSize(10); + headRecord.setUserCount(3); + // 团员 + List list = new ArrayList<>(); + for (int i = 1; i <= 2; i++) { + AppCombinationRecordSimpleRespVO record = new AppCombinationRecordSimpleRespVO(); + record.setId((long) i); + record.setNickname("用户" + i); + record.setAvatar("头像" + i); + record.setExpireTime(new Date()); + record.setUserSize(10); + record.setUserCount(i); + list.add(record); + } + detail.setMemberRecords(list); + // 订单编号 + detail.setOrderId(100L); + return success(detail); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java index 553a31fd8..79e54d610 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityDetailRespVO.java @@ -25,18 +25,18 @@ public class AppCombinationActivityDetailRespVO { @Schema(description = "活动结束时间", required = true) private LocalDateTime endTime; + @Schema(description = "拼团人数", required = true, example = "3") + private Integer userSize; + + @Schema(description = "成功的拼团数量", required = true, example = "100") + private Integer successCount; + @Schema(description = "商品 SPU 编号", required = true, example = "2048") private Long spuId; @Schema(description = "商品信息数组", required = true) private List products; - @Schema(description = "成功的拼团记录", required = true) - private List successRecords; - - @Schema(description = "进行中的拼团记录", required = true) - private List runningRecords; - @Schema(description = "商品信息") @Data public static class Product { @@ -55,13 +55,4 @@ public class AppCombinationActivityDetailRespVO { } - @Schema(description = "拼团记录") - @Data - public static class Record { - - @Schema(description = "拼团记录编号", required = true, example = "1024") - private Long id; - - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java new file mode 100644 index 000000000..120926ad6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 拼团记录详细 Response VO") +@Data +public class AppCombinationRecordDetailRespVO { + + @Schema(description = "团长的拼团记录", required = true) + private AppCombinationRecordSimpleRespVO headRecord; + + @Schema(description = "成员的拼团记录", required = true) + private List memberRecords; + + @Schema(description = "当前用户参团记录对应的订单编号", required = true, example = "1024") // 如果没参团,返回 null + private Long orderId; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java new file mode 100644 index 000000000..54177aeb8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Schema(description = "用户 App - 拼团记录精简 Response VO") +@Data +public class AppCombinationRecordSimpleRespVO { + + @Schema(description = "拼团记录编号", required = true, example = "1024") + private Long id; + + @Schema(description = "用户昵称", required = true, example = "1024") + private String nickname; + + @Schema(description = "用户头像", required = true, example = "1024") + private String avatar; + + @Schema(description = "过期时间", required = true) + private Date expireTime; + + @Schema(description = "可参团人数", required = true, example = "10") + private Integer userSize; + + @Schema(description = "已参团人数", required = true, example = "5") + private Integer userCount; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java index a643fc1b3..0feeac6ff 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java @@ -27,9 +27,6 @@ public class AppSeckillActivitiDetailRespVO { @Schema(description = "活动结束时间", required = true) private LocalDateTime endTime; - - private Long successGruopCount; - @Schema(description = "商品 SPU 编号", required = true, example = "2048") private Long spuId; From 8ec373388250cf26b16094de895e5a414490ed3b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 16 Jun 2023 20:32:03 +0800 Subject: [PATCH 113/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Amock=20?= =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E8=AE=B0=E5=BD=95=E5=88=97=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/date/DateUtils.java | 1 - .../AppCombinationRecordController.java | 29 ++++++++++++++----- .../AppCombinationRecordDetailRespVO.java | 4 +-- ...O.java => AppCombinationRecordRespVO.java} | 21 ++++++++++++-- .../vo/AppTradeOrderSettlementReqVO.java | 12 ++++++++ 5 files changed, 54 insertions(+), 13 deletions(-) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/{AppCombinationRecordSimpleRespVO.java => AppCombinationRecordRespVO.java} (50%) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java index a329fb177..c2d069a59 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java @@ -55,7 +55,6 @@ public class DateUtils { return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); } - @Deprecated public static Date addTime(Duration duration) { return new Date(System.currentTimeMillis() + duration.toMillis()); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java index 1e32111f1..b9086f362 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.promotion.controller.app.combination; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO; -import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSimpleRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordRespVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.Max; +import java.time.Duration; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -27,18 +29,23 @@ public class AppCombinationRecordController { @GetMapping("/get-head-list") @Operation(summary = "获得最近 n 条拼团记录(团长发起的)") - public CommonResult> getHeadCombinationRecordList( + // TODO @芋艿:注解要补全 + public CommonResult> getHeadCombinationRecordList( + @RequestParam(value = "activityId", required = false) Long activityId, @RequestParam("status") Integer status, @RequestParam(value = "count", defaultValue = "20") @Max(20) Integer count) { - List list = new ArrayList<>(); + List list = new ArrayList<>(); for (int i = 1; i <= count; i++) { - AppCombinationRecordSimpleRespVO record = new AppCombinationRecordSimpleRespVO(); + AppCombinationRecordRespVO record = new AppCombinationRecordRespVO(); record.setId((long) i); record.setNickname("用户" + i); record.setAvatar("头像" + i); record.setExpireTime(new Date()); record.setUserSize(10); record.setUserCount(i); + record.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); + record.setActivityId(1L); + record.setActivityName("活动:" + i); list.add(record); } return success(list); @@ -50,23 +57,29 @@ public class AppCombinationRecordController { public CommonResult getCombinationRecordDetail(@RequestParam("id") Long id) { AppCombinationRecordDetailRespVO detail = new AppCombinationRecordDetailRespVO(); // 团长 - AppCombinationRecordSimpleRespVO headRecord = new AppCombinationRecordSimpleRespVO(); + AppCombinationRecordRespVO headRecord = new AppCombinationRecordRespVO(); headRecord.setId(1L); headRecord.setNickname("用户" + 1); headRecord.setAvatar("头像" + 1); - headRecord.setExpireTime(new Date()); + headRecord.setExpireTime(DateUtils.addTime(Duration.ofDays(1))); headRecord.setUserSize(10); headRecord.setUserCount(3); + headRecord.setStatus(1); + headRecord.setActivityId(10L); + headRecord.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); + headRecord.setCombinationPrice(100); + detail.setHeadRecord(headRecord); // 团员 - List list = new ArrayList<>(); + List list = new ArrayList<>(); for (int i = 1; i <= 2; i++) { - AppCombinationRecordSimpleRespVO record = new AppCombinationRecordSimpleRespVO(); + AppCombinationRecordRespVO record = new AppCombinationRecordRespVO(); record.setId((long) i); record.setNickname("用户" + i); record.setAvatar("头像" + i); record.setExpireTime(new Date()); record.setUserSize(10); record.setUserCount(i); + record.setStatus(1); list.add(record); } detail.setMemberRecords(list); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java index 120926ad6..dae83ea9c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordDetailRespVO.java @@ -10,10 +10,10 @@ import java.util.List; public class AppCombinationRecordDetailRespVO { @Schema(description = "团长的拼团记录", required = true) - private AppCombinationRecordSimpleRespVO headRecord; + private AppCombinationRecordRespVO headRecord; @Schema(description = "成员的拼团记录", required = true) - private List memberRecords; + private List memberRecords; @Schema(description = "当前用户参团记录对应的订单编号", required = true, example = "1024") // 如果没参团,返回 null private Long orderId; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java similarity index 50% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java index 54177aeb8..0f591bcff 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java @@ -5,13 +5,16 @@ import lombok.Data; import java.util.Date; -@Schema(description = "用户 App - 拼团记录精简 Response VO") +@Schema(description = "用户 App - 拼团记录 Response VO") @Data -public class AppCombinationRecordSimpleRespVO { +public class AppCombinationRecordRespVO { @Schema(description = "拼团记录编号", required = true, example = "1024") private Long id; + @Schema(description = "拼团活动编号", required = true, example = "1024") + private Long activityId; + @Schema(description = "用户昵称", required = true, example = "1024") private String nickname; @@ -27,4 +30,18 @@ public class AppCombinationRecordSimpleRespVO { @Schema(description = "已参团人数", required = true, example = "5") private Integer userCount; + @Schema(description = "拼团状态", required = true, example = "1") + private Integer status; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "拼团金额,单位:分", required = true, example = "100") + private Integer combinationPrice; + + // ========== 获得最近 n 条拼团记录(团长发起的)返回的字段 ========== + + @Schema(description = "拼团活动名字", required = true, example = "1024") + private String activityName; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index 0324b492b..4a21bbc63 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -18,6 +18,7 @@ public class AppTradeOrderSettlementReqVO { @NotNull(message = "交易类型不能为空") @InEnum(value = TradeOrderTypeEnum.class, message = "交易类型必须是 {value}") + @Deprecated // TODO 芋艿:后续干掉这个字段,对于前端不需要关注这个 private Integer type; @Schema(description = "商品项数组", required = true) @@ -30,6 +31,17 @@ public class AppTradeOrderSettlementReqVO { @Schema(description = "优惠劵编号", example = "1024") private Long couponId; + // ========== 秒杀活动相关字段 ========== + @Schema(description = "秒杀活动编号", example = "1024") + private Long seckillActivityId; + + // ========== 拼团活动相关字段 ========== + @Schema(description = "拼团活动编号", example = "1024") + private Long combinationActivityId; + + @Schema(description = "拼团团长编号", example = "2048") + private Long combinationHeadId; + @Data @Schema(description = "用户 App - 商品项") @Valid From 5b324f90a4d5a1d544eae275b0666aa327c2e272 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 16 Jun 2023 23:27:27 +0800 Subject: [PATCH 114/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9Amock=20?= =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E6=B4=BB=E5=8A=A8=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppCombinationActivityController.java | 32 ++++++++++++++++++- .../AppCombinationRecordController.java | 2 +- .../AppCombinationActivityPageItemRespVO.java | 31 ++++++++++++++++++ .../vo/record/AppCombinationRecordRespVO.java | 8 ++--- 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java index ba4c01e9a..43680baa0 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.promotion.controller.app.combination; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityDetailRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityPageItemRespVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -23,10 +26,37 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Validated public class AppCombinationActivityController { + @GetMapping("/page") + @Operation(summary = "获得拼团活动分页") + public CommonResult> getCombinationActivityPage(PageParam pageParam) { + List activityList = new ArrayList<>(); + AppCombinationActivityPageItemRespVO activity1 = new AppCombinationActivityPageItemRespVO(); + activity1.setId(1L); + activity1.setName("618 大拼团"); + activity1.setUserSize(3); + activity1.setSpuId(2048L); + activity1.setPicUrl("商品图片地址"); + activity1.setMarketPrice(50); + activity1.setCombinationPrice(100); + activityList.add(activity1); + + AppCombinationActivityPageItemRespVO activity2 = new AppCombinationActivityPageItemRespVO(); + activity2.setId(2L); + activity2.setName("双十一拼团"); + activity2.setUserSize(5); + activity2.setSpuId(4096L); + activity2.setPicUrl("商品图片地址"); + activity2.setMarketPrice(100); + activity2.setCombinationPrice(200); + activityList.add(activity2); + + return success(new PageResult<>(activityList, 2L)); + } + @GetMapping("/get-detail") @Operation(summary = "获得拼团活动明细") @Parameter(name = "id", description = "活动编号", required = true, example = "1024") - public CommonResult getCombinationActivity(@RequestParam("id") Long id) { + public CommonResult getCombinationActivityDetail(@RequestParam("id") Long id) { // TODO 芋艿:如果禁用的时候,需要抛出异常; AppCombinationActivityDetailRespVO obj = new AppCombinationActivityDetailRespVO(); // 设置其属性的值 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java index b9086f362..657fe8b9c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java @@ -45,7 +45,7 @@ public class AppCombinationRecordController { record.setUserCount(i); record.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); record.setActivityId(1L); - record.setActivityName("活动:" + i); + record.setSpuName("活动:" + i); list.add(record); } return success(list); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java new file mode 100644 index 000000000..090a5f190 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 App - 拼团活动分页项 Response VO") +@Data +public class AppCombinationActivityPageItemRespVO { + + @Schema(description = "拼团活动编号", required = true, example = "1024") + private Long id; + + @Schema(description = "拼团活动名称", required = true, example = "618 大拼团") + private String name; + + @Schema(description = "拼团人数", required = true, example = "3") + private Integer userSize; + + @Schema(description = "商品 SPU 编号", required = true, example = "2048") + private Long spuId; + + @Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取 + private String picUrl; + + @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取 + private Integer marketPrice; + + @Schema(description = "拼团金额,单位:分", required = true, example = "100") // 从拼团商品里取最低价 + private Integer combinationPrice; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java index 0f591bcff..143271b3b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java @@ -33,15 +33,13 @@ public class AppCombinationRecordRespVO { @Schema(description = "拼团状态", required = true, example = "1") private Integer status; + @Schema(description = "商品名字", required = true, example = "我是大黄豆") + private String spuName; + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") private String picUrl; @Schema(description = "拼团金额,单位:分", required = true, example = "100") private Integer combinationPrice; - // ========== 获得最近 n 条拼团记录(团长发起的)返回的字段 ========== - - @Schema(description = "拼团活动名字", required = true, example = "1024") - private String activityName; - } From 07fe52939d1cb24654e1cfabe8c289a84a414611 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Jun 2023 00:47:47 +0800 Subject: [PATCH 115/232] =?UTF-8?q?mall=20+=20promotion=EF=BC=9Amock=20ban?= =?UTF-8?q?ner=20mock=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/banner/vo/BannerRespVO.java | 12 +---- .../app/banner/AppBannerController.java | 40 ++++++++--------- .../app/banner/vo/AppBannerRespVO.java | 20 +++++++++ .../AppCombinationActivityController.java | 44 ++++++++++++++++--- .../AppCombinationRecordController.java | 18 ++++++++ ...java => AppCombinationActivityRespVO.java} | 4 +- .../AppCombinationRecordSummaryRespVO.java | 18 ++++++++ 7 files changed, 116 insertions(+), 40 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/{AppCombinationActivityPageItemRespVO.java => AppCombinationActivityRespVO.java} (89%) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSummaryRespVO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java index f07644e8a..b1ea6c207 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java @@ -4,22 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -/** - * @author xia - */ @Schema(description = "管理后台 - Banner Response VO") @Data @ToString(callSuper = true) public class BannerRespVO extends BannerBaseVO { - @Schema(description = "banner编号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "banner编号不能为空") + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED) private Long id; - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java index 4bc094598..3a4ff8a78 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java @@ -1,42 +1,42 @@ package cn.iocoder.yudao.module.promotion.controller.app.banner; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; -import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.promotion.service.banner.BannerService; +import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.Resource; +import java.util.ArrayList; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -/** - * @author: XIA - */ @RestController -@RequestMapping("/market/banner") -@Tag(name = "用户APP- 首页Banner") +@RequestMapping("/promotion/banner") +@Tag(name = "用户 APP - 首页 Banner") @Validated public class AppBannerController { - @Resource - private BannerService bannerService; - - // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 @GetMapping("/list") - @Operation(summary = "获得banner列表") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult> getBannerList() { - List list = bannerService.getBannerList(); - return success(BannerConvert.INSTANCE.convertList(list)); + @Operation(summary = "获得 banner 列表") + // todo @芋艿:swagger 注解,待补全 + // TODO @芋艿:可以增加缓存,提升性能 + // TODO @芋艿:position = 1 时,首页;position = 10 时,拼团活动页 + public CommonResult> getBannerList(@RequestParam("position") Integer position) { + List bannerList = new ArrayList<>(); + AppBannerRespVO banner1 = new AppBannerRespVO(); + banner1.setUrl("https://www.example.com/link1"); + banner1.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2022/08/04/0f78716213f64bfa83f191d51a832cbf73f6axavoy.jpg"); + bannerList.add(banner1); + AppBannerRespVO banner2 = new AppBannerRespVO(); + banner2.setUrl("https://www.example.com/link2"); + banner2.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2023/01/11/be09e755268b43ee90b0db3a3e1b7132r7a6t2wvsm.jpg"); + bannerList.add(banner2); + return success(bannerList); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java new file mode 100644 index 000000000..7656a431d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.controller.app.banner.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 App - Banner Response VO") +@Data +public class AppBannerRespVO { + + @Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "跳转链接不能为空") + private String url; + + @Schema(description = "图片地址", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "图片地址不能为空") + private String picUrl; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java index 43680baa0..2f9d23278 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityDetailRespVO; -import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityPageItemRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity.AppCombinationActivityRespVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -26,11 +26,14 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Validated public class AppCombinationActivityController { - @GetMapping("/page") - @Operation(summary = "获得拼团活动分页") - public CommonResult> getCombinationActivityPage(PageParam pageParam) { - List activityList = new ArrayList<>(); - AppCombinationActivityPageItemRespVO activity1 = new AppCombinationActivityPageItemRespVO(); + @GetMapping("/list") + @Operation(summary = "获得拼团活动列表", description = "用于小程序首页") + // TODO 芋艿:增加 Spring Cache + // TODO 芋艿:缺少 swagger 注解 + public CommonResult> getCombinationActivityList( + @RequestParam(name = "count", defaultValue = "6") Integer count) { + List activityList = new ArrayList<>(); + AppCombinationActivityRespVO activity1 = new AppCombinationActivityRespVO(); activity1.setId(1L); activity1.setName("618 大拼团"); activity1.setUserSize(3); @@ -40,7 +43,34 @@ public class AppCombinationActivityController { activity1.setCombinationPrice(100); activityList.add(activity1); - AppCombinationActivityPageItemRespVO activity2 = new AppCombinationActivityPageItemRespVO(); + AppCombinationActivityRespVO activity2 = new AppCombinationActivityRespVO(); + activity2.setId(2L); + activity2.setName("双十一拼团"); + activity2.setUserSize(5); + activity2.setSpuId(4096L); + activity2.setPicUrl("商品图片地址"); + activity2.setMarketPrice(100); + activity2.setCombinationPrice(200); + activityList.add(activity2); + + return success(activityList); + } + + @GetMapping("/page") + @Operation(summary = "获得拼团活动分页") + public CommonResult> getCombinationActivityPage(PageParam pageParam) { + List activityList = new ArrayList<>(); + AppCombinationActivityRespVO activity1 = new AppCombinationActivityRespVO(); + activity1.setId(1L); + activity1.setName("618 大拼团"); + activity1.setUserSize(3); + activity1.setSpuId(2048L); + activity1.setPicUrl("商品图片地址"); + activity1.setMarketPrice(50); + activity1.setCombinationPrice(100); + activityList.add(activity1); + + AppCombinationActivityRespVO activity2 = new AppCombinationActivityRespVO(); activity2.setId(2L); activity2.setName("双十一拼团"); activity2.setUserSize(5); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java index 657fe8b9c..0c1c8510d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO; import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -27,6 +28,23 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Validated public class AppCombinationRecordController { + @GetMapping("/get-summary") + @Operation(summary = "获得拼团活动的概要信息", description = "用于小程序首页") + // TODO 芋艿:增加 @Cache 缓存,1 分钟过期 + public CommonResult getCombinationSummary() { + AppCombinationRecordSummaryRespVO summary = new AppCombinationRecordSummaryRespVO(); + summary.setUserCount(1024); + summary.setAvatars(new ArrayList<>()); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLjFK35Wvia9lJKHoXfQuHhk0qZbvpPNxrAiaEKF7aL2k4I8kuqrdTWwliamdPHeyAA7DjAg725X2GIQ/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTK1pXgdj5DvBMwrbe8v3tFibSWeQATEsAibt3fllD8XwJ460P2r6KS3WCQvDefuv1bVpDhNCle6CTCA/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTL7KRGHBE62N0awFyBesmmxiaCicf1fJ7E7UCh6zA8GWlT1QC1zT01gG4OxI7BWDESkdPZ5o7tno4hA/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/ouwtwJycbic2JrCoZjETict0klxd1uRuicRneKk00ewMcCClxVcVHQT91Sh9MJGtwibf1fOicD1WpwSP4icJM6eQq1AA/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/RpUrhwens58qc99OcGs993xL4M5QPOe05ekqF9Eia440kRicAlicicIdQWicHBmy2bzLgHzHguWEzHHxnIgeictL7bLA/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/S4tfqmxc8GZGsKc1K4mnhpvtG16gtMrLnTQfDibhr7jJich9LRI5RQKZDoqEjZM3azMib5nic7F4ZXKMEgYyLO08KA/132"); + summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); + return success(summary); + } + @GetMapping("/get-head-list") @Operation(summary = "获得最近 n 条拼团记录(团长发起的)") // TODO @芋艿:注解要补全 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityRespVO.java similarity index 89% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityRespVO.java index 090a5f190..1c3139a1e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/activity/AppCombinationActivityRespVO.java @@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.activity import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(description = "用户 App - 拼团活动分页项 Response VO") +@Schema(description = "用户 App - 拼团活动 Response VO") @Data -public class AppCombinationActivityPageItemRespVO { +public class AppCombinationActivityRespVO { @Schema(description = "拼团活动编号", required = true, example = "1024") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSummaryRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSummaryRespVO.java new file mode 100644 index 000000000..a071620a4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordSummaryRespVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 拼团记录的简要概括 Response VO") +@Data +public class AppCombinationRecordSummaryRespVO { + + @Schema(description = "拼团用户数量", required = true, example = "1024") + private Integer userCount; + + @Schema(description = "拼团用户头像列表", required = true) // 只返回最近的 7 个 + private List avatars; + +} From 59d5fef59277919dd5929045f0f7d9d09d12d20c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Jun 2023 11:35:31 +0800 Subject: [PATCH 116/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=BF=90=E8=B4=B9=E6=A8=A1=E7=89=88=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 34 ++++---- .../DeliveryExpressTemplateConvert.java | 27 +++++- .../DeliveryExpressTemplateChargeMapper.java | 5 +- .../DeliveryExpressTemplateFreeMapper.java | 6 +- .../delivery/DeliveryExpressServiceImpl.java | 2 +- .../DeliveryExpressTemplateService.java | 3 +- .../DeliveryExpressTemplateServiceImpl.java | 28 ++----- .../bo/DeliveryExpressTemplateRespBO.java | 9 +- .../service/order/TradeOrderServiceImpl.java | 2 +- .../TradeDeliveryPriceCalculator.java | 15 ++-- .../TradeDeliveryPriceCalculatorTest.java | 83 +++++++++---------- 11 files changed, 112 insertions(+), 102 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 12d921a88..ae7a0a501 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -45,19 +45,25 @@ public interface ErrorCodeConstants { // ========== Cart 模块 1011002000 ========== ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); - // ========== 物流配送模块 1011003000 ========== - ErrorCode DELIVERY_EXPRESS_NOT_EXISTS = new ErrorCode(1011003000, "快递公司不存在"); - // TODO @jason:最好每个模块一段哈。express 一个;exmpresstemplate 一个;pickup 一个 - ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011003001, "已经存在该编码的快递公司"); - ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011003002, "运费模板不存在"); - ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011003003, "已经存在该运费模板名"); - ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011003004, "快递查询接口异常"); - ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011003005, "快递查询返回失败, 原因:{}"); - ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011003006, "需要接入快递服务商,比如【快递100】"); - ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011003007, "自提门店不存在"); + // ========== Price 相关 1011003000 ============ + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011003000, "支付价格计算异常,原因:价格小于等于 0"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板"); + + // ========== 物流 Express 模块 1011004000 ========== + ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); + ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司"); + ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004002, "快递查询接口异常"); + ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004003, "快递查询返回失败,原因:{}"); + ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004004, "需要接入快递服务商,比如【快递100】"); + + // ========== 物流 Template 模块 1011005000 ========== + ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011005000, "已经存在该运费模板名"); + ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在"); + + // ========== 物流 PICK_UP 模块 1011006000 ========== + + ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在"); + - // ========== Price 相关 1011004000 ============ - ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011004000, "支付价格计算异常,原因:价格小于等于 0"); - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011004001, "计算快递运费异常,收件人地址编号为空"); - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011004002, "计算快递运费异常,找不到对应的运费模板"); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java index bbd57c62e..665dc787d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java @@ -7,10 +7,15 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemp import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; +import com.google.common.collect.Maps; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; @Mapper public interface DeliveryExpressTemplateConvert { @@ -48,7 +53,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo); - DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); + DeliveryExpressTemplateRespBO.Charge convertTemplateCharge(DeliveryExpressTemplateChargeDO bean); default List convertTemplateChargeList(Long templateId, Integer chargeMode, List list) { return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo)); @@ -60,7 +65,7 @@ public interface DeliveryExpressTemplateConvert { DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo); - DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO convertTemplateFree(DeliveryExpressTemplateFreeDO bean); + DeliveryExpressTemplateRespBO.Free convertTemplateFree(DeliveryExpressTemplateFreeDO bean); List convertTemplateChargeList(List list); @@ -70,4 +75,22 @@ public interface DeliveryExpressTemplateConvert { return CollectionUtils.convertList(list, vo -> convertTemplateFree(templateId, vo)); } + default Map convertMap(Integer areaId, List templateList, + List chargeList, + List freeList) { + Map> templateIdChargeMap = convertMultiMap(chargeList, + DeliveryExpressTemplateChargeDO::getTemplateId); + Map> templateIdFreeMap = convertMultiMap(freeList, + DeliveryExpressTemplateFreeDO::getTemplateId); + // 组合运费模板配置 RespBO + Map result = Maps.newHashMapWithExpectedSize(templateList.size()); + templateList.forEach(template -> { + DeliveryExpressTemplateRespBO bo = new DeliveryExpressTemplateRespBO() + .setChargeMode(template.getChargeMode()) + .setCharge(convertTemplateCharge(findFirst(templateIdChargeMap.get(template.getId()), charge -> charge.getAreaIds().contains(areaId)))) + .setFree(convertTemplateFree(findFirst(templateIdFreeMap.get(template.getId()), free -> free.getAreaIds().contains(areaId)))); + result.put(template.getId(), bo); + }); + return result; + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java index 985b418ac..a2403f019 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateChargeMapper.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -24,9 +23,9 @@ public interface DeliveryExpressTemplateChargeMapper extends BaseMapperX selectByTemplateIds(Collection templateIds) { - return selectList(new LambdaQueryWrapperX() - .inIfPresent(DeliveryExpressTemplateChargeDO::getTemplateId, templateIds)); + return selectList(DeliveryExpressTemplateChargeDO::getTemplateId, templateIds); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java index 5cc407354..b64a3c979 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressTemplateFreeMapper.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.trade.dal.mysql.delivery; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -22,9 +21,8 @@ public interface DeliveryExpressTemplateFreeMapper extends BaseMapperX selectListByTemplateIds(Collection ids) { - return selectList(new LambdaQueryWrapperX() - .inIfPresent(DeliveryExpressTemplateFreeDO::getTemplateId, ids)); + default List selectListByTemplateIds(Collection templateIds) { + return selectList(DeliveryExpressTemplateFreeDO::getTemplateId, templateIds); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java index a396a389a..2f08b0b3f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java @@ -75,7 +75,7 @@ public class DeliveryExpressServiceImpl implements DeliveryExpressService { } private void validateDeliveryExpressExists(Long id) { if (deliveryExpressMapper.selectById(id) == null) { - throw exception(DELIVERY_EXPRESS_NOT_EXISTS); + throw exception(EXPRESS_NOT_EXISTS); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java index 39edd823e..c455701b2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateService.java @@ -84,11 +84,12 @@ public interface DeliveryExpressTemplateService { DeliveryExpressTemplateDO validateDeliveryExpressTemplate(Long templateId); /** - * 基于运费模板编号数组和收件人地址区域编号. 获取匹配运费模板 + * 基于运费模板编号数组和收件人地址区域编号,获取匹配运费模板 * * @param ids 编号列表 * @param areaId 区域编号 * @return Map (templateId -> 运费模板设置) */ Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java index c4aa22b8f..0cfe5e815 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java @@ -224,36 +224,26 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla @Override public Map getExpressTemplateMapByIdsAndArea(Collection ids, Integer areaId) { Assert.notNull(areaId, "区域编号 {} 不能为空", areaId); + // 查询 template 数组 if (CollUtil.isEmpty(ids)) { return Collections.emptyMap(); } List templateList = expressTemplateMapper.selectBatchIds(ids); - // 查询 templateCharge - List templeChargeList = expressTemplateChargeMapper.selectByTemplateIds(ids); - Map> templateChargeMap = convertMultiMap(templeChargeList, - DeliveryExpressTemplateChargeDO::getTemplateId); - // 查询 templateFree - List templateFreeList = expressTemplateFreeMapper.selectListByTemplateIds(ids); - Map> templateFreeMap = convertMultiMap(templateFreeList, - DeliveryExpressTemplateFreeDO::getTemplateId); + // 查询 templateCharge 数组 + List chargeList = expressTemplateChargeMapper.selectByTemplateIds(ids); + // 查询 templateFree 数组 + List freeList = expressTemplateFreeMapper.selectListByTemplateIds(ids); + // 组合运费模板配置 RespBO - Map result = new HashMap<>(templateList.size()); - templateList.forEach(item -> { - DeliveryExpressTemplateRespBO bo = new DeliveryExpressTemplateRespBO() - .setChargeMode(item.getChargeMode()) - .setTemplateCharge(findMatchExpressTemplateCharge(templateChargeMap.get(item.getId()), areaId)) - .setTemplateFree(findMatchExpressTemplateFree(templateFreeMap.get(item.getId()), areaId)); - result.put(item.getId(), bo); - }); - return result; + return INSTANCE.convertMap(areaId, templateList, chargeList, freeList); } - private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO findMatchExpressTemplateCharge( + private DeliveryExpressTemplateRespBO.Charge findMatchExpressTemplateCharge( List templateChargeList, Integer areaId) { return INSTANCE.convertTemplateCharge(findFirst(templateChargeList, item -> item.getAreaIds().contains(areaId))); } - private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO findMatchExpressTemplateFree( + private DeliveryExpressTemplateRespBO.Free findMatchExpressTemplateFree( List templateFreeList, Integer areaId) { return INSTANCE.convertTemplateFree(findFirst(templateFreeList, item -> item.getAreaIds().contains(areaId))); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java index 6c8764a5c..db0af04eb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java @@ -21,12 +21,12 @@ public class DeliveryExpressTemplateRespBO { /** * 运费模板快递运费设置 */ - private DeliveryExpressTemplateChargeBO templateCharge; + private Charge charge; /** * 运费模板包邮设置 */ - private DeliveryExpressTemplateFreeBO templateFree; + private Free free; /** * 快递运费模板费用配置 BO @@ -34,7 +34,7 @@ public class DeliveryExpressTemplateRespBO { * @author jason */ @Data - public static class DeliveryExpressTemplateChargeBO { + public static class Charge { /** * 首件数量(件数,重量,或体积) @@ -60,7 +60,7 @@ public class DeliveryExpressTemplateRespBO { * @author jason */ @Data - public static class DeliveryExpressTemplateFreeBO { + public static class Free { /** * 包邮金额,单位:分 @@ -76,4 +76,5 @@ public class DeliveryExpressTemplateRespBO { */ private Integer freeCount; } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 7cd6fe87b..d90be3031 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -342,7 +342,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { // TODO 芋艿:logisticsId 校验存在 发货物流公司 fix DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId()); if (deliveryExpress == null) { - throw exception(DELIVERY_EXPRESS_NOT_EXISTS); + throw exception(EXPRESS_NOT_EXISTS); } // 更新 TradeOrderDO 状态为已发货,等待收货 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java index 1a0598c63..35a3cb92a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java @@ -77,7 +77,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { List orderItems = entry.getValue(); DeliveryExpressTemplateRespBO templateBO = expressTemplateMap.get(templateId); if (templateBO == null) { - log.error("不能计算快递运费。不能找到 templateId : {}. 对应的运费模板配置 Resp BO", templateId); + log.error("[calculateDeliveryPrice][不能计算快递运费,找不到 templateId({}) 对应的运费模板配置]", templateId); continue; } // 总件数, 总金额, 总重量, 总体积 @@ -93,12 +93,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { } // 优先判断是否包邮. 如果包邮不计算快递运费 if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, - totalVolume, totalPrice, templateBO.getTemplateFree())) { + totalVolume, totalPrice, templateBO.getFree())) { continue; } // 计算快递运费 calculateExpressFeeByChargeMode(totalCount, totalWeight, totalVolume, - templateBO.getChargeMode(), templateBO.getTemplateCharge(), orderItems); + templateBO.getChargeMode(), templateBO.getCharge(), orderItems); } TradePriceCalculatorHelper.recountAllPrice(result); @@ -115,10 +115,10 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param orderItems SKU 商品项目 */ private void calculateExpressFeeByChargeMode(double totalCount, double totalWeight, double totalVolume, - int chargeMode, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, + int chargeMode, DeliveryExpressTemplateRespBO.Charge templateCharge, List orderItems) { if (templateCharge == null) { - log.error("计算快递运费时,不能找到对应的快递运费模板费用配置。无法计算以下商品 SKU 项目运费: {}", orderItems); + log.error("[calculateExpressFeeByChargeMode][计算快递运费时,找不到 SKU({}) 对应的运费模版]", orderItems); return; } DeliveryExpressChargeModeEnum chargeModeEnum = DeliveryExpressChargeModeEnum.valueOf(chargeMode); @@ -145,7 +145,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateCharge 快递运费配置 * @param orderItems SKU 商品项目 */ - private void calculateExpressFee(double total, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO templateCharge, List orderItems) { + private void calculateExpressFee(double total, DeliveryExpressTemplateRespBO.Charge templateCharge, List orderItems) { int deliveryPrice; if (total <= templateCharge.getStartCount()) { deliveryPrice = templateCharge.getStartPrice(); @@ -174,7 +174,6 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { for (OrderItem item : orderItems) { // 更新快递运费 item.setDeliveryPrice(dividePrice); - TradePriceCalculatorHelper.recountPayPrice(item); } } @@ -190,7 +189,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { * @param templateFree 包邮配置 */ private boolean isExpressFree(Integer chargeMode, int totalCount, double totalWeight, - double totalVolume, int totalPrice, DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO templateFree) { + double totalVolume, int totalPrice, DeliveryExpressTemplateRespBO.Free templateFree) { if (templateFree == null) { return false; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java index 99fdac64e..1f408cf47 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; +import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; import cn.iocoder.yudao.module.member.api.address.AddressApi; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; +import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; @@ -14,20 +17,17 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum.PIECE; -import static cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum.EXPRESS; import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import static org.assertj.core.api.Assertions.assertThat; - /** + * {@link TradeDeliveryPriceCalculator} 的单元测试 + * * @author jason */ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { @@ -41,22 +41,22 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { private TradePriceCalculateReqBO reqBO; private TradePriceCalculateRespBO resultBO; - private AddressRespDTO addressResp; - private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO chargeBO; - private DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO freeBO; + private DeliveryExpressTemplateRespBO templateRespBO; + private DeliveryExpressTemplateRespBO.Charge chargeBO; + private DeliveryExpressTemplateRespBO.Free freeBO; @BeforeEach public void init(){ // 准备参数 reqBO = new TradePriceCalculateReqBO() - .setDeliveryType(EXPRESS.getMode()) + .setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()) .setAddressId(10L) .setUserId(1L) .setItems(asList( new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(10).setSelected(true), - new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(false) + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(false) // 未选中 )); resultBO = new TradePriceCalculateRespBO() .setPrice(new TradePriceCalculateRespBO.Price()) @@ -72,18 +72,21 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // 保证价格被初始化上 TradePriceCalculatorHelper.recountPayPrice(resultBO.getItems()); TradePriceCalculatorHelper.recountAllPrice(resultBO); + // 准备收件地址数据 - addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); + AddressRespDTO addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); + when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); + // 准备运费模板费用配置数据 - chargeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateChargeBO.class, + chargeBO = randomPojo(DeliveryExpressTemplateRespBO.Charge.class, item -> item.setStartCount(10D).setStartPrice(1000).setExtraCount(10D).setExtraPrice(2000)); - // 准备运费模板包邮配置数据 订单总件数 < 包邮件数时 12 < 20 - freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, + // 准备运费模板包邮配置数据:订单总件数 < 包邮件数时 12 < 20 + freeBO = randomPojo(DeliveryExpressTemplateRespBO.Free.class, item -> item.setFreeCount(20).setFreePrice(100)); - // 准备 SP 运费模板 数据 + // 准备 SP 运费模板数据 templateRespBO = randomPojo(DeliveryExpressTemplateRespBO.class, - item -> item.setChargeMode(PIECE.getType()) - .setTemplateCharge(chargeBO).setTemplateFree(freeBO)); + item -> item.setChargeMode(DeliveryExpressChargeModeEnum.PIECE.getType()) + .setCharge(chargeBO).setFree(freeBO)); } @Test @@ -92,32 +95,27 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 首件 1000 + 续件 2000 = 3000 - Map respMap = new HashMap<>(); - respMap.put(1L, templateRespBO); - // mock 方法 - when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) - .thenReturn(respMap); + .thenReturn(MapUtil.of(1L, templateRespBO)); + // 调用 calculator.calculate(reqBO, resultBO); - + // 断言 TradePriceCalculateRespBO.Price price = resultBO.getPrice(); - assertThat(price) .extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice") .containsExactly(2200, 0, 0, 0, 3000, 5200); - // 断言:SKU assertThat(resultBO.getItems()).hasSize(3); - // SKU1 + // 断言:SKU1 assertThat(resultBO.getItems().get(0)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(100, 2, 0, 0, 0, 1500, 1700); - // SKU2 + // 断言:SKU2 assertThat(resultBO.getItems().get(1)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(200, 10, 0, 0, 0, 1500, 3500); - // SKU3 未选中 + // 断言:SKU3 未选中 assertThat(resultBO.getItems().get(2)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(300, 1, 0, 0, 0, 0, 300); @@ -129,38 +127,33 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { // SKU 1 : 100 * 2 = 200 // SKU 2 :200 * 10 = 2000 // 运费 0 - Map respMap = new HashMap<>(); - respMap.put(1L, templateRespBO); - // 准备运费模板包邮配置数据 包邮 订单总件数 > 包邮件数时 12 > 10 - freeBO = randomPojo(DeliveryExpressTemplateRespBO.DeliveryExpressTemplateFreeBO.class, - item -> item.setFreeCount(10).setFreePrice(1000)); - templateRespBO.setTemplateFree(freeBO); // mock 方法 - when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); + // 准备运费模板包邮配置数据 包邮 订单总件数 > 包邮件数时 12 > 10 + templateRespBO.setFree(randomPojo(DeliveryExpressTemplateRespBO.Free.class, + item -> item.setFreeCount(10).setFreePrice(1000))); when(deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(eq(asSet(1L)), eq(10))) - .thenReturn(respMap); + .thenReturn(MapUtil.of(1L, templateRespBO)); + // 调用 calculator.calculate(reqBO, resultBO); - + // 断言 TradePriceCalculateRespBO.Price price = resultBO.getPrice(); - - // 断言price assertThat(price) .extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice") .containsExactly(2200, 0, 0, 0, 0, 2200); - // 断言:SKU assertThat(resultBO.getItems()).hasSize(3); - // SKU1 + // 断言:SKU1 assertThat(resultBO.getItems().get(0)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(100, 2, 0, 0, 0, 0, 200); - // SKU2 + // 断言:SKU2 assertThat(resultBO.getItems().get(1)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(200, 10, 0, 0, 0, 0, 2000); - // SKU3 未选中 + // 断言:SKU3 未选中 assertThat(resultBO.getItems().get(2)) .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice") .containsExactly(300, 1, 0, 0, 0, 0, 300); } -} \ No newline at end of file + +} From 0d47d6cead6ad1c56c4bbfdaaab5f54e71c965d3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Jun 2023 11:59:38 +0800 Subject: [PATCH 117/232] =?UTF-8?q?mall=20+=20trade=EF=BC=9Acode=20review?= =?UTF-8?q?=20=E5=BF=AB=E9=80=92=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E6=B2=A1=E5=95=A5=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=92=A7=EF=BC=8C=E6=90=9E=E4=B8=8B=E5=8D=95=E6=B5=8B=E5=B0=B1?= =?UTF-8?q?=20ok=20=E6=8B=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 7 ++++--- .../delivery/config/ExpressClientConfig.java | 9 +++++---- .../config/TradeExpressProperties.java | 3 ++- .../delivery/core/client/ExpressClient.java | 6 +++--- .../core/client/ExpressClientFactory.java | 5 +++-- .../client/convert/ExpressQueryConvert.java | 12 +++++------ ...qDTO.java => ExpressTrackQueryReqDTO.java} | 4 ++-- ...yRespDTO.java => ExpressTrackRespDTO.java} | 2 +- .../client/impl/ExpressClientFactoryImpl.java | 12 +++++------ .../client/impl/NoProvideExpressClient.java | 8 +++++--- .../impl/{ => kd100}/Kd100ExpressClient.java | 19 ++++++++---------- .../{ => kdniao}/KdNiaoExpressClient.java | 20 ++++++++++--------- .../{client => enums}/ExpressClientEnum.java | 10 ++++------ .../client/impl/Kd100ExpressClientTest.java | 9 ++++++--- .../client/impl/KdNiaoExpressClientTest.java | 10 +++++++--- .../impl/NoProvideExpressClientTest.java | 3 ++- 16 files changed, 74 insertions(+), 65 deletions(-) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/{ExpressQueryReqDTO.java => ExpressTrackQueryReqDTO.java} (87%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/{ExpressQueryRespDTO.java => ExpressTrackRespDTO.java} (91%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/{ => kd100}/Kd100ExpressClient.java (88%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/{ => kdniao}/KdNiaoExpressClient.java (90%) rename yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/{client => enums}/ExpressClientEnum.java (68%) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index ae7a0a501..1b3c73c30 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -53,9 +53,10 @@ public interface ErrorCodeConstants { // ========== 物流 Express 模块 1011004000 ========== ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司"); - ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004002, "快递查询接口异常"); - ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004003, "快递查询返回失败,原因:{}"); - ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004004, "需要接入快递服务商,比如【快递100】"); + ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商,比如【快递100】"); + + ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常"); + ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}"); // ========== 物流 Template 模块 1011005000 ========== ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011005000, "已经存在该运费模板名"); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java index e93c0a70b..2799c3f1c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/ExpressClientConfig.java @@ -8,13 +8,14 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** - * 快递客户端端配置类, 提供快递客户端工厂,默认的快递客户端实现 + * 快递客户端端配置类: + * + * 1. 快递客户端工厂 {@link ExpressClientFactory} + * 2. 默认的快递客户端实现 {@link ExpressClient} * * @author jason */ -@Configuration( - proxyBeanMethods = false -) +@Configuration(proxyBeanMethods = false) public class ExpressClientConfig { @Bean diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java index 5f593df8b..795af0dee 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.framework.delivery.config; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientEnum; +import cn.iocoder.yudao.module.trade.framework.delivery.core.enums.ExpressClientEnum; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -27,6 +27,7 @@ public class TradeExpressProperties { * 默认不提供,需要提醒用户配置一个快递服务商。 */ private ExpressClientEnum client = ExpressClientEnum.NOT_PROVIDE; + /** * 快递鸟配置 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java index b670313c5..76b361c3f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClient.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import java.util.List; @@ -18,6 +18,6 @@ public interface ExpressClient { * @param reqDTO 查询请求参数 */ // TODO @jason:返回字段可以参考 https://doc.youzanyun.com/detail/API/0/5 响应的 data - List getExpressTrackList(ExpressQueryReqDTO reqDTO); + List getExpressTrackList(ExpressTrackQueryReqDTO reqDTO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java index f6a54dd8f..5e457092f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientFactory.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client; +import cn.iocoder.yudao.module.trade.framework.delivery.core.enums.ExpressClientEnum; + /** - * 快递客户端工厂接口,快递客户端工厂:用于创建和缓存快递客户端 + * 快递客户端工厂接口:用于创建和缓存快递客户端 * * @author jason */ @@ -19,5 +21,4 @@ public interface ExpressClientFactory { */ ExpressClient getOrCreateExpressClient(ExpressClientEnum clientEnum); - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java index 14a2c1c98..1c8f76d73 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.convert; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO; @@ -16,12 +16,12 @@ public interface ExpressQueryConvert { ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class); - List convertList(List expressTrackList); + List convertList(List expressTrackList); - List convertList2(List expressTrackList); + List convertList2(List expressTrackList); - KdNiaoExpressQueryReqDTO convert(ExpressQueryReqDTO dto); + KdNiaoExpressQueryReqDTO convert(ExpressTrackQueryReqDTO dto); - Kd100ExpressQueryReqDTO convert2(ExpressQueryReqDTO dto); + Kd100ExpressQueryReqDTO convert2(ExpressTrackQueryReqDTO dto); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackQueryReqDTO.java similarity index 87% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackQueryReqDTO.java index ea579a170..34ad0128d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryReqDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackQueryReqDTO.java @@ -4,12 +4,12 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import lombok.Data; /** - * 快递查询 Req DTO + * 快递轨迹的查询 Req DTO * * @author jason */ @Data -public class ExpressQueryReqDTO { +public class ExpressTrackQueryReqDTO { /** * 快递公司编码 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackRespDTO.java similarity index 91% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackRespDTO.java index a2aad9025..b6463ef1d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackRespDTO.java @@ -8,7 +8,7 @@ import lombok.Data; * @author jason */ @Data -public class ExpressQueryRespDTO { +public class ExpressTrackRespDTO { // TODO @jason:LocalDateTime /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java index 96666bfef..d4432b264 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/ExpressClientFactoryImpl.java @@ -2,9 +2,12 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientEnum; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kd100.Kd100ExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kdniao.KdNiaoExpressClient; +import cn.iocoder.yudao.module.trade.framework.delivery.core.enums.ExpressClientEnum; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory; +import lombok.AllArgsConstructor; import org.springframework.web.client.RestTemplate; import java.util.Map; @@ -15,6 +18,7 @@ import java.util.concurrent.ConcurrentHashMap; * * @author jason */ +@AllArgsConstructor public class ExpressClientFactoryImpl implements ExpressClientFactory { private final Map clientMap = new ConcurrentHashMap<>(8); @@ -22,12 +26,6 @@ public class ExpressClientFactoryImpl implements ExpressClientFactory { private final TradeExpressProperties tradeExpressProperties; private final RestTemplate restTemplate; - public ExpressClientFactoryImpl(TradeExpressProperties tradeExpressProperties, - RestTemplate restTemplate) { - this.tradeExpressProperties = tradeExpressProperties; - this.restTemplate = restTemplate; - } - @Override public ExpressClient getDefaultExpressClient() { ExpressClient defaultClient = getOrCreateExpressClient(tradeExpressProperties.getClient()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java index b4b9403a7..7289710f6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClient.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import java.util.List; @@ -15,8 +15,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_CLI * @author jason */ public class NoProvideExpressClient implements ExpressClient { + @Override - public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { + public List getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) { throw exception(EXPRESS_CLIENT_NOT_PROVIDE); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kd100/Kd100ExpressClient.java similarity index 88% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kd100/Kd100ExpressClient.java index 930d5d8d9..0b7e1dcbd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClient.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kd100/Kd100ExpressClient.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kd100; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.HexUtil; @@ -6,8 +6,8 @@ import cn.hutool.crypto.digest.DigestUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd100ExpressQueryRespDTO; import lombok.AllArgsConstructor; @@ -36,29 +36,28 @@ import static cn.iocoder.yudao.module.trade.framework.delivery.core.client.conve public class Kd100ExpressClient implements ExpressClient { private static final String REAL_TIME_QUERY_URL = "https://poll.kuaidi100.com/poll/query.do"; + private final RestTemplate restTemplate; private final TradeExpressProperties.Kd100Config config; @Override - public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { + public List getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) { // 发起查询 Kd100ExpressQueryReqDTO kd100ReqParam = INSTANCE.convert2(reqDTO); kd100ReqParam.setExpressCode(kd100ReqParam.getExpressCode().toLowerCase()); // 快递公司编码需要转成小写 Kd100ExpressQueryRespDTO respDTO = requestExpressQuery(REAL_TIME_QUERY_URL, kd100ReqParam, Kd100ExpressQueryRespDTO.class); log.debug("[getExpressTrackList][快递 100 接口 查询接口返回 {}]", respDTO); + // 处理结果 if (Objects.equals("false", respDTO.getResult())) { log.error("[getExpressTrackList][快递 100 接口 返回失败 {}]", respDTO.getMessage()); throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage()); } - // TODO @jason:convertList2 如果空,应该返回 list 了; @芋艿 为了避免返回 null - if (CollUtil.isNotEmpty(respDTO.getTracks())) { - return INSTANCE.convertList2(respDTO.getTracks()); - } else { + if (CollUtil.isEmpty(respDTO.getTracks())) { return Collections.emptyList(); } - + return INSTANCE.convertList2(respDTO.getTracks()); } /** @@ -85,7 +84,6 @@ public class Kd100ExpressClient implements ExpressClient { log.debug("[sendExpressQueryReq][快递 100 接口的请求参数: {}]", requestBody); // 发送请求 HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); - // TODO @jason:可以使用 restTemplate 的 post 方法哇 @芋艿 为了获取接口的原始返回。用exchange 便于查问题。 ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); log.debug("[sendExpressQueryReq][快递 100 接口响应结果 {}]", responseEntity); @@ -98,7 +96,6 @@ public class Kd100ExpressClient implements ExpressClient { private String generateReqSign(String param, String key, String customer) { String plainText = String.format("%s%s%s", param, key, customer); - // TODO @芋艿。 这里需要转换成大写, 没有对应方法 return HexUtil.encodeHexStr(DigestUtil.md5(plainText), false); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kdniao/KdNiaoExpressClient.java similarity index 90% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kdniao/KdNiaoExpressClient.java index 1e5e5f535..52ebf72da 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClient.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kdniao/KdNiaoExpressClient.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kdniao; import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollUtil; @@ -7,8 +7,8 @@ import cn.hutool.crypto.digest.DigestUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryRespDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryRespDTO; import lombok.AllArgsConstructor; @@ -51,25 +51,27 @@ public class KdNiaoExpressClient implements ExpressClient { * @param reqDTO 查询请求参数 */ @Override - public List getExpressTrackList(ExpressQueryReqDTO reqDTO) { + public List getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) { KdNiaoExpressQueryReqDTO kdNiaoReqData = INSTANCE.convert(reqDTO); // 快递公司编码需要转成大写 kdNiaoReqData.setExpressCode(reqDTO.getExpressCode().toUpperCase()); KdNiaoExpressQueryRespDTO respDTO = requestKdNiaoApi(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE, kdNiaoReqData, KdNiaoExpressQueryRespDTO.class); log.debug("[getExpressTrackList][快递鸟即时查询接口返回 {}]", respDTO); + + // 处理结果 if (respDTO == null || !respDTO.getSuccess()) { throw exception(EXPRESS_API_QUERY_FAILED, respDTO == null ? "" : respDTO.getReason()); } if (CollUtil.isNotEmpty(respDTO.getTracks())) { - return INSTANCE.convertList(respDTO.getTracks()); - } else { return Collections.emptyList(); } + return INSTANCE.convertList(respDTO.getTracks()); } /** - * 快递鸟 通用的 API 请求, 暂时没有其他应用场景, 暂时放这里 + * 快递鸟 通用的 API 请求,暂时没有其他应用场景, 暂时放这里 + * * @param url 请求 url * @param requestType 对应的请求指令 (快递鸟的RequestType) * @param req 对应请求的请求参数 @@ -77,8 +79,8 @@ public class KdNiaoExpressClient implements ExpressClient { * @param 每个请求的请求结构 Req DTO * @param 每个请求的响应结构 Resp DTO */ - private Resp requestKdNiaoApi(String url, String requestType, Req req, - Class respClass){ + private Resp requestKdNiaoApi(String url, String requestType, Req req, + Class respClass){ // 请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/enums/ExpressClientEnum.java similarity index 68% rename from yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java rename to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/enums/ExpressClientEnum.java index 756252e61..81b96184c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/ExpressClientEnum.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/enums/ExpressClientEnum.java @@ -1,5 +1,6 @@ -package cn.iocoder.yudao.module.trade.framework.delivery.core.client; +package cn.iocoder.yudao.module.trade.framework.delivery.core.enums; +import lombok.AllArgsConstructor; import lombok.Getter; /** @@ -8,7 +9,9 @@ import lombok.Getter; * @author jason */ @Getter +@AllArgsConstructor public enum ExpressClientEnum { + NOT_PROVIDE("not-provide","未提供"), KD_NIAO("kd-niao", "快递鸟"), KD_100("kd-100", "快递100"); @@ -17,14 +20,9 @@ public enum ExpressClientEnum { * 快递服务商唯一编码 */ private final String code; - /** * 快递服务商名称 */ private final String name; - ExpressClientEnum(String code, String name) { - this.code = code; - this.name = name; - } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java index 6fa41e314..21b615dd0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kd100.Kd100ExpressClient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -18,12 +19,14 @@ import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器 /** * @author jason */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Kd100ExpressClientTest.Application.class) @ActiveProfiles("unit-test") // 设置使用 trade-delivery-query 配置文件 public class Kd100ExpressClientTest { + @Resource private RestTemplateBuilder builder; @Resource @@ -39,7 +42,7 @@ public class Kd100ExpressClientTest { @Disabled("需要 授权 key. 暂时忽略") void testRealTimeQueryExpressFailed() { ServiceException t = assertThrows(ServiceException.class, () -> { - ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); + ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO(); reqDTO.setExpressCode("yto"); reqDTO.setLogisticsNo("YT9383342193097"); kd100ExpressClient.getExpressTrackList(reqDTO); @@ -53,4 +56,4 @@ public class Kd100ExpressClientTest { @EnableConfigurationProperties(TradeExpressProperties.class) public static class Application { } -} \ No newline at end of file +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java index ebf38d0b7..fc7c6a953 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties; -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kdniao.KdNiaoExpressClient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -17,13 +18,16 @@ import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.assertThrows; -// TODO @芋艿:单测最后 review +// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器 /** + * {@link KdNiaoExpressClient} 的单元测试 + * * @author jason */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressClientTest.Application.class) @ActiveProfiles("unit-test") public class KdNiaoExpressClientTest { + @Resource private RestTemplateBuilder builder; @Resource @@ -39,7 +43,7 @@ public class KdNiaoExpressClientTest { @Disabled("需要 授权 key. 暂时忽略") void testRealTimeQueryExpressFailed() { assertThrows(ServiceException.class,() ->{ - ExpressQueryReqDTO reqDTO = new ExpressQueryReqDTO(); + ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO(); reqDTO.setExpressCode("yy"); reqDTO.setLogisticsNo("YT9383342193097"); kdNiaoExpressClient.getExpressTrackList(reqDTO); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java index 76b8cd6b4..3b60f3645 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java @@ -19,6 +19,7 @@ import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器 /** * @author jason */ @@ -49,4 +50,4 @@ public class NoProvideExpressClientTest { return builder.build(); } } -} \ No newline at end of file +} From 8e3a65d84c64c7e679c0b618c971ba5f2cd38f69 Mon Sep 17 00:00:00 2001 From: xiaqing Date: Sat, 17 Jun 2023 16:39:28 +0800 Subject: [PATCH 118/232] =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-local.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index cdc1d3fde..c748e9455 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -44,31 +44,31 @@ spring: primary: master datasource: master: - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: mall + url: jdbc:mysql://10.211.55.5:3308/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例 username: root - password: 123456 + password: 1qaz!QAZ # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W slave: # 模拟从库,可根据自己需要修改 - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: mall + url: jdbc:mysql://10.211.55.5:3308/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例 username: root - password: 123456 + password: 1qaz!QAZ # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: - host: 127.0.0.1 # 地址 + host: 10.211.55.5 # 地址 port: 6379 # 端口 database: 0 # 数据库索引 # password: dev # 密码,建议生产环境开启 @@ -159,6 +159,7 @@ logging: cn.iocoder.yudao.module.member.dal.mysql: debug cn.iocoder.yudao.module.trade.dal.mysql: debug cn.iocoder.yudao.module.promotion.dal.mysql: debug + cn.iocoder.yudao.module.point.dal.mysql: debug debug: false From fd072b7d6ee0001826033fdaa367814c5313f2d7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Jun 2023 18:33:17 +0800 Subject: [PATCH 119/232] =?UTF-8?q?code=20review=EF=BC=9A=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E7=A7=AF=E5=88=86=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../point/MemberPointConfigController.java | 45 ++++++++ .../vo/config/MemberPointConfigBaseVO.java | 27 +++++ .../vo/config/MemberPointConfigRespVO.java | 13 +++ .../vo/config/MemberPointConfigSaveReqVO.java | 13 +++ .../admin/point/vo/recrod/package-info.java | 1 + .../point/MemberPointConfigConvert.java | 20 ++++ .../dataobject/point/MemberPointConfigDO.java | 35 +++--- .../mysql/point/MemberPointConfigMapper.java | 14 +++ .../point/MemberPointConfigService.java | 29 +++++ .../point/MemberPointConfigServiceImpl.java | 33 ++++++ .../pointconfig/PointConfigController.java | 102 ------------------ .../pointconfig/vo/PointConfigBaseVO.java | 30 ------ .../vo/PointConfigCreateReqVO.java | 14 --- .../pointconfig/vo/PointConfigExcelVO.java | 45 -------- .../vo/PointConfigExportReqVO.java | 15 --- .../pointconfig/vo/PointConfigPageReqVO.java | 17 --- .../pointconfig/vo/PointConfigRespVO.java | 22 ---- .../vo/PointConfigUpdateReqVO.java | 18 ---- .../pointconfig/PointConfigConvert.java | 34 ------ .../mysql/pointconfig/PointConfigMapper.java | 32 ------ .../pointconfig/PointConfigService.java | 70 ------------ .../pointconfig/PointConfigServiceImpl.java | 92 ---------------- .../mapper/pointconfig/PointConfigMapper.xml | 12 --- .../mapper/pointrecord/PointRecordMapper.xml | 12 --- .../signinconfig/SignInConfigMapper.xml | 12 --- .../signinrecord/SignInRecordMapper.xml | 12 --- 26 files changed, 212 insertions(+), 557 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/recrod/package-info.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java rename yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java => yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java (53%) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml delete mode 100644 yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java new file mode 100644 index 000000000..f0e6d0ee2 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.member.controller.admin.point; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO; +import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; +import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; +import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 会员积分设置") +@RestController +@RequestMapping("/point/config") +@Validated +public class MemberPointConfigController { + + @Resource + private MemberPointConfigService memberPointConfigService; + + @PutMapping("/update") + @Operation(summary = "保存会员积分配置") + @PreAuthorize("@ss.hasPermission('member:point-config:save')") + public CommonResult updateConfig(@Valid @RequestBody MemberPointConfigSaveReqVO saveReqVO) { + memberPointConfigService.saveConfig(saveReqVO); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得会员积分配置") + @PreAuthorize("@ss.hasPermission('member:point-config:query')") + public CommonResult getConfig() { + MemberPointConfigDO config = memberPointConfigService.getConfig(); + return success(MemberPointConfigConvert.INSTANCE.convert(config)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java new file mode 100644 index 000000000..46ad58321 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 会员积分配置 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class MemberPointConfigBaseVO { + + @Schema(description = "积分抵扣开关", required = true, example = "true") + private Boolean tradeDeductEnable; + + @Schema(description = "积分抵扣,单位:分", example = "13506") + private BigDecimal tradeDeductUnitPrice; + + @Schema(description = "积分抵扣最大值", example = "32428") + private Long tradeDeductMaxPrice; + + @Schema(description = "1 元赠送多少分") + private Long tradeGivePoint; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java new file mode 100644 index 000000000..36ace83e7 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 会员积分配置 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MemberPointConfigRespVO extends MemberPointConfigBaseVO { +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java new file mode 100644 index 000000000..729ab74b6 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 会员积分配置保存 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MemberPointConfigSaveReqVO extends MemberPointConfigBaseVO { +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/recrod/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/recrod/package-info.java new file mode 100644 index 000000000..284e2178b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/recrod/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java new file mode 100644 index 000000000..cf49d2951 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.member.convert.point; + +import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO; +import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 会员积分配置 Convert + * + * @author QingX + */ +@Mapper +public interface MemberPointConfigConvert { + + MemberPointConfigConvert INSTANCE = Mappers.getMapper(MemberPointConfigConvert.class); + + MemberPointConfigRespVO convert(MemberPointConfigDO bean); + +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java similarity index 53% rename from yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java index ee30a27d1..a7d54219f 100644 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/dataobject/pointconfig/PointConfigDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java @@ -1,15 +1,15 @@ -package cn.iocoder.yudao.module.point.dal.dataobject.pointconfig; +package cn.iocoder.yudao.module.member.dal.dataobject.point; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import com.baomidou.mybatisplus.annotation.*; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; /** - * 积分设置 DO + * 会员积分配置 DO * * @author QingX */ @@ -21,7 +21,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @Builder @NoArgsConstructor @AllArgsConstructor -public class PointConfigDO extends BaseDO { +public class MemberPointConfigDO extends BaseDO { /** * 自增主键 @@ -29,23 +29,22 @@ public class PointConfigDO extends BaseDO { @TableId private Integer id; /** - * 1 开启积分抵扣 -0 关闭积分抵扣 - * - * 枚举 {@link TODO infra_boolean_string 对应的类} + * 积分抵扣开关 */ - private Integer tradeDeductEnable; + private Boolean tradeDeductEnable; /** - * 积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元) + * 积分抵扣,单位:分 + * + * 1 积分抵扣多少分 */ private BigDecimal tradeDeductUnitPrice; /** * 积分抵扣最大值 */ - private Long tradeDeductMaxPrice; + private Integer tradeDeductMaxPrice; /** - * 1元赠送多少分 + * 1 元赠送多少分 */ - private Long tradeGivePoint; + private Integer tradeGivePoint; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java new file mode 100644 index 000000000..e099c1714 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.member.dal.mysql.point; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 积分设置 Mapper + * + * @author QingX + */ +@Mapper +public interface MemberPointConfigMapper extends BaseMapperX { +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java new file mode 100644 index 000000000..4becacd36 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.member.service.point; + +import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; + +import javax.validation.Valid; + +/** + * 会员积分配置 Service 接口 + * + * @author QingX + */ +public interface MemberPointConfigService { + + /** + * 保存会员积分配置 + * + * @param saveReqVO 更新信息 + */ + void saveConfig(@Valid MemberPointConfigSaveReqVO saveReqVO); + + /** + * 获得会员积分配置 + * + * @return 积分配置 + */ + MemberPointConfigDO getConfig(); + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java new file mode 100644 index 000000000..181537d55 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.member.service.point; + +import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; +import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointConfigMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 会员积分配置 Service 实现类 + * + * @author QingX + */ +@Service +@Validated +public class MemberPointConfigServiceImpl implements MemberPointConfigService { + + @Resource + private MemberPointConfigMapper memberPointConfigMapper; + + @Override + public void saveConfig(MemberPointConfigSaveReqVO saveReqVO) { + // TODO qingx:配置存在,则 update;不存在则 insert + } + + @Override + public MemberPointConfigDO getConfig() { + // TODO qingx:直接查询到一条; + return null; + } +} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java deleted file mode 100644 index 137d03050..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/PointConfigController.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig; - -import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; - -import javax.validation.constraints.*; -import javax.validation.*; -import javax.servlet.http.*; -import java.util.*; -import java.io.IOException; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; - -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; - -import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; -import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; -import cn.iocoder.yudao.module.point.convert.pointconfig.PointConfigConvert; -import cn.iocoder.yudao.module.point.service.pointconfig.PointConfigService; - -@Tag(name = "管理后台 - 积分设置") -@RestController -@RequestMapping("/point/config") -@Validated -public class PointConfigController { - - @Resource - private PointConfigService configService; - - @PostMapping("/create") - @Operation(summary = "创建积分设置") - @PreAuthorize("@ss.hasPermission('point:config:create')") - public CommonResult createConfig(@Valid @RequestBody PointConfigCreateReqVO createReqVO) { - return success(configService.createConfig(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新积分设置") - @PreAuthorize("@ss.hasPermission('point:config:update')") - public CommonResult updateConfig(@Valid @RequestBody PointConfigUpdateReqVO updateReqVO) { - configService.updateConfig(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除积分设置") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('point:config:delete')") - public CommonResult deleteConfig(@RequestParam("id") Integer id) { - configService.deleteConfig(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得积分设置") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('point:config:query')") - public CommonResult getConfig(@RequestParam("id") Integer id) { - PointConfigDO config = configService.getConfig(id); - return success(PointConfigConvert.INSTANCE.convert(config)); - } - - @GetMapping("/list") - @Operation(summary = "获得积分设置列表") - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") - @PreAuthorize("@ss.hasPermission('point:config:query')") - public CommonResult> getConfigList(@RequestParam("ids") Collection ids) { - List list = configService.getConfigList(ids); - return success(PointConfigConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/page") - @Operation(summary = "获得积分设置分页") - @PreAuthorize("@ss.hasPermission('point:config:query')") - public CommonResult> getConfigPage(@Valid PointConfigPageReqVO pageVO) { - PageResult pageResult = configService.getConfigPage(pageVO); - return success(PointConfigConvert.INSTANCE.convertPage(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出积分设置 Excel") - @PreAuthorize("@ss.hasPermission('point:config:export')") - @OperateLog(type = EXPORT) - public void exportConfigExcel(@Valid PointConfigExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = configService.getConfigList(exportReqVO); - // 导出 Excel - List datas = PointConfigConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "积分设置.xls", "数据", PointConfigExcelVO.class, datas); - } - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java deleted file mode 100644 index d1e900cc2..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigBaseVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import javax.validation.constraints.*; - -/** - * 积分设置 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class PointConfigBaseVO { - - @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") - private Integer tradeDeductEnable; - - @Schema(description = "积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元)", example = "13506") - private BigDecimal tradeDeductUnitPrice; - - @Schema(description = "积分抵扣最大值", example = "32428") - private Long tradeDeductMaxPrice; - - @Schema(description = "1元赠送多少分") - private Long tradeGivePoint; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java deleted file mode 100644 index 4284f5e34..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigCreateReqVO.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import lombok.*; -import java.util.*; -import io.swagger.v3.oas.annotations.media.Schema; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 积分设置创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PointConfigCreateReqVO extends PointConfigBaseVO { - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java deleted file mode 100644 index 0d01c7a5c..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExcelVO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.time.LocalDateTime; - -import com.alibaba.excel.annotation.ExcelProperty; -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; - - -/** - * 积分设置 Excel VO - * - * @author QingX - */ -@Data -public class PointConfigExcelVO { - - @ExcelProperty("自增主键") - private Integer id; - - @ExcelProperty(value = "1 开启积分抵扣 0 关闭积分抵扣", converter = DictConvert.class) - @DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 - private Integer tradeDeductEnable; - - @ExcelProperty("积分抵扣,抵扣最低为分 以0.01表示 1积分抵扣0.01元(单位:元)") - private BigDecimal tradeDeductUnitPrice; - - @ExcelProperty("积分抵扣最大值") - private Long tradeDeductMaxPrice; - - @ExcelProperty("1元赠送多少分") - private Long tradeGivePoint; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - - @ExcelProperty("变更时间") - private LocalDateTime updateTime; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java deleted file mode 100644 index bcc712d29..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigExportReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import lombok.*; -import java.util.*; -import io.swagger.v3.oas.annotations.media.Schema; -import cn.iocoder.yudao.framework.common.pojo.PageParam; - -@Schema(description = "管理后台 - 积分设置 Excel 导出 Request VO,参数和 PointConfigPageReqVO 是一致的") -@Data -public class PointConfigExportReqVO { - - @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") - private Integer tradeDeductEnable; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java deleted file mode 100644 index cc994837c..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigPageReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import lombok.*; -import java.util.*; -import io.swagger.v3.oas.annotations.media.Schema; -import cn.iocoder.yudao.framework.common.pojo.PageParam; - -@Schema(description = "管理后台 - 积分设置分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PointConfigPageReqVO extends PageParam { - - @Schema(description = "1 开启积分抵扣 0 关闭积分抵扣", example = "1") - private Integer tradeDeductEnable; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java deleted file mode 100644 index a8efe57b4..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 积分设置 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PointConfigRespVO extends PointConfigBaseVO { - - @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20937") - private Integer id; - - @Schema(description = "创建时间") - private LocalDateTime createTime; - - @Schema(description = "变更时间") - private LocalDateTime updateTime; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java deleted file mode 100644 index 9b50f259d..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/controller/admin/pointconfig/vo/PointConfigUpdateReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 积分设置更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PointConfigUpdateReqVO extends PointConfigBaseVO { - - @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20937") - @NotNull(message = "自增主键不能为空") - private Integer id; - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java deleted file mode 100644 index 56b96cf75..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/convert/pointconfig/PointConfigConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.point.convert.pointconfig; - -import java.util.*; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; -import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; - -/** - * 积分设置 Convert - * - * @author QingX - */ -@Mapper -public interface PointConfigConvert { - - PointConfigConvert INSTANCE = Mappers.getMapper(PointConfigConvert.class); - - PointConfigDO convert(PointConfigCreateReqVO bean); - - PointConfigDO convert(PointConfigUpdateReqVO bean); - - PointConfigRespVO convert(PointConfigDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java deleted file mode 100644 index 5d11f9b5b..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/dal/mysql/pointconfig/PointConfigMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.point.dal.mysql.pointconfig; - -import java.util.*; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; -import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; - -/** - * 积分设置 Mapper - * - * @author QingX - */ -@Mapper -public interface PointConfigMapper extends BaseMapperX { - - default PageResult selectPage(PointConfigPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(PointConfigDO::getTradeDeductEnable, reqVO.getTradeDeductEnable()) - .orderByDesc(PointConfigDO::getId)); - } - - default List selectList(PointConfigExportReqVO reqVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(PointConfigDO::getTradeDeductEnable, reqVO.getTradeDeductEnable()) - .orderByDesc(PointConfigDO::getId)); - } - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java deleted file mode 100644 index d579b7b9d..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigService.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.point.service.pointconfig; - -import java.util.*; -import javax.validation.*; -import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; -import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -/** - * 积分设置 Service 接口 - * - * @author QingX - */ -public interface PointConfigService { - - /** - * 创建积分设置 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Integer createConfig(@Valid PointConfigCreateReqVO createReqVO); - - /** - * 更新积分设置 - * - * @param updateReqVO 更新信息 - */ - void updateConfig(@Valid PointConfigUpdateReqVO updateReqVO); - - /** - * 删除积分设置 - * - * @param id 编号 - */ - void deleteConfig(Integer id); - - /** - * 获得积分设置 - * - * @param id 编号 - * @return 积分设置 - */ - PointConfigDO getConfig(Integer id); - - /** - * 获得积分设置列表 - * - * @param ids 编号 - * @return 积分设置列表 - */ - List getConfigList(Collection ids); - - /** - * 获得积分设置分页 - * - * @param pageReqVO 分页查询 - * @return 积分设置分页 - */ - PageResult getConfigPage(PointConfigPageReqVO pageReqVO); - - /** - * 获得积分设置列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 积分设置列表 - */ - List getConfigList(PointConfigExportReqVO exportReqVO); - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java b/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java deleted file mode 100644 index 5cc8185d8..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/java/cn/iocoder/yudao/module/point/service/pointconfig/PointConfigServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package cn.iocoder.yudao.module.point.service.pointconfig; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; - -import java.util.*; -import cn.iocoder.yudao.module.point.controller.admin.pointconfig.vo.*; -import cn.iocoder.yudao.module.point.dal.dataobject.pointconfig.PointConfigDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.module.point.convert.pointconfig.PointConfigConvert; -import cn.iocoder.yudao.module.point.dal.mysql.pointconfig.PointConfigMapper; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.point.enums.ErrorCodeConstants.*; - -/** - * 积分设置 Service 实现类 - * - * @author QingX - */ -@Service -@Validated -public class PointConfigServiceImpl implements PointConfigService { - - @Autowired - private PointConfigMapper configMapper; - - @Override - public Integer createConfig(PointConfigCreateReqVO createReqVO) { - // 插入 - PointConfigDO config = PointConfigConvert.INSTANCE.convert(createReqVO); - //每个租户只允许存在一条记录 - validateConfigExistsOne(); - - configMapper.insert(config); - // 返回 - return config.getId(); - } - - @Override - public void updateConfig(PointConfigUpdateReqVO updateReqVO) { - // 校验存在 - validateConfigExists(updateReqVO.getId()); - // 更新 - PointConfigDO updateObj = PointConfigConvert.INSTANCE.convert(updateReqVO); - configMapper.updateById(updateObj); - } - - @Override - public void deleteConfig(Integer id) { - // 校验存在 - validateConfigExists(id); - // 删除 - configMapper.deleteById(id); - } - - private void validateConfigExists(Integer id) { - if (configMapper.selectById(id) == null) { - throw exception(CONFIG_NOT_EXISTS); - } - } - - private void validateConfigExistsOne() { - if (configMapper.selectCount() > 0) { - throw exception(CONFIG_EXISTS); - } - } - - @Override - public PointConfigDO getConfig(Integer id) { - return configMapper.selectById(id); - } - - @Override - public List getConfigList(Collection ids) { - return configMapper.selectBatchIds(ids); - } - - @Override - public PageResult getConfigPage(PointConfigPageReqVO pageReqVO) { - return configMapper.selectPage(pageReqVO); - } - - @Override - public List getConfigList(PointConfigExportReqVO exportReqVO) { - return configMapper.selectList(exportReqVO); - } - -} diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml deleted file mode 100644 index 963afd6c8..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointconfig/PointConfigMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml deleted file mode 100644 index cc09cce4b..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/pointrecord/PointRecordMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml deleted file mode 100644 index 2e665c01a..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinconfig/SignInConfigMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml b/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml deleted file mode 100644 index bd9d58976..000000000 --- a/yudao-module-point/yudao-module-point-biz/src/main/resources/mapper/signinrecord/SignInRecordMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - From 32cca12cd2a9cc8db4d4eb8c256045f8b034bab5 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 17 Jun 2023 21:17:02 +0800 Subject: [PATCH 120/232] =?UTF-8?q?fix=EF=BC=9AseckillTime=20=3D>=20seckil?= =?UTF-8?q?lConfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/dm/ruoyi-vue-pro-dm8.sql | 127 ++++++++++-- sql/mysql/ruoyi-vue-pro.sql | 127 ++++++++++-- .../seckill/SeckillConfigController.java | 87 ++++++++ .../admin/seckill/SeckillTimeController.java | 72 ------- .../vo/activity/SeckillActivityBaseVO.java | 2 +- .../vo/config/SeckillConfigBaseVO.java | 43 ++++ .../SeckillConfigCreateReqVO.java} | 9 +- .../SeckillConfigPageReqVO.java} | 16 +- .../SeckillConfigRespVO.java} | 15 +- .../SeckillConfigUpdateReqVO.java} | 9 +- .../seckill/vo/time/SeckillTimeBaseVO.java | 28 --- .../seckillconfig/SeckillConfigConvert.java | 35 ++++ .../seckilltime/SeckillTimeConvert.java | 34 ---- .../seckillactivity/SeckillProductDO.java | 2 +- .../SeckillConfigDO.java} | 19 +- .../seckillconfig/SeckillConfigMapper.java | 45 +++++ .../seckilltime/SeckillTimeMapper.java | 32 --- .../SeckillActivityService.java | 10 +- .../SeckillActivityServiceImpl.java | 44 ++-- .../SeckillConfigService.java} | 37 ++-- .../SeckillConfigServiceImpl.java | 131 ++++++++++++ .../seckilltime/SeckillTimeServiceImpl.java | 124 ------------ .../SeckillConfigServiceImplTest.java | 190 ++++++++++++++++++ .../SeckillTimeServiceImplTest.java | 190 ------------------ .../src/test/resources/sql/clean.sql | 20 +- .../src/test/resources/sql/create_tables.sql | 133 ++++++++++-- .../seckill/seckillActivity/index.vue | 111 +++++----- .../promotion/seckill/seckillTime/index.vue | 25 ++- 28 files changed, 1056 insertions(+), 661 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/{time/SeckillTimeCreateReqVO.java => config/SeckillConfigCreateReqVO.java} (68%) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/{time/SeckillTimePageReqVO.java => config/SeckillConfigPageReqVO.java} (73%) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/{time/SeckillTimeRespVO.java => config/SeckillConfigRespVO.java} (62%) rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/{time/SeckillTimeUpdateReqVO.java => config/SeckillConfigUpdateReqVO.java} (77%) delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/{seckilltime/SeckillTimeDO.java => seckillconfig/SeckillConfigDO.java} (60%) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java rename yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/{seckilltime/SeckillTimeService.java => seckillconfig/SeckillConfigService.java} (54%) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java diff --git a/sql/dm/ruoyi-vue-pro-dm8.sql b/sql/dm/ruoyi-vue-pro-dm8.sql index 8275065b4..8128c647e 100644 --- a/sql/dm/ruoyi-vue-pro-dm8.sql +++ b/sql/dm/ruoyi-vue-pro-dm8.sql @@ -1797,27 +1797,112 @@ INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT" INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2046,'满减送活动关闭','promotion:reward-activity:close',3,5,2041,'','','',null,0,1,1,1,'1','2022-11-05 10:42:53','1','2022-11-05 10:42:53',0); INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2047,'限时折扣活动','',2,7,2030,'discount-activity','time','mall/promotion/discountActivity/index','PromotionDiscountActivity',0,1,1,1,'','2022-11-05 17:12:15','1','2023-04-08 11:45:44',0); INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2048,'限时折扣活动查询','promotion:discount-activity:query',3,1,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:15','','2022-11-05 17:12:15',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2049,'限时折扣活动创建','promotion:discount-activity:create',3,2,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:15','','2022-11-05 17:12:15',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2050,'限时折扣活动更新','promotion:discount-activity:update',3,3,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2051,'限时折扣活动删除','promotion:discount-activity:delete',3,4,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2052,'限时折扣活动关闭','promotion:discount-activity:close',3,5,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2059,'秒杀活动管理','',2,0,2030,'seckill-activity','time-range','mall/promotion/seckill/seckillActivity/index','PromotionSeckillActivity',0,1,1,1,'','2022-11-06 22:24:49','1','2023-04-08 11:46:02',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2060,'秒杀活动查询','promotion:seckill-activity:query',3,1,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2061,'秒杀活动创建','promotion:seckill-activity:create',3,2,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2062,'秒杀活动更新','promotion:seckill-activity:update',3,3,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2063,'秒杀活动删除','promotion:seckill-activity:delete',3,4,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2064,'秒杀活动导出','promotion:seckill-activity:export',3,5,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2066,'秒杀时段管理','',2,0,2030,'seckill-time','','mall/promotion/seckill/seckillTime/index','PromotionSeckillTime',0,0,1,1,'','2022-11-15 19:46:50','1','2023-04-08 11:46:17',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2067,'秒杀时段查询','promotion:seckill-time:query',3,1,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2068,'秒杀时段创建','promotion:seckill-time:create',3,2,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2069,'秒杀时段更新','promotion:seckill-time:update',3,3,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2070,'秒杀时段删除','promotion:seckill-time:delete',3,4,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2071,'秒杀时段导出','promotion:seckill-time:export',3,5,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2072,'订单中心','',1,65,0,'/trade','order',null,null,0,1,1,1,'1','2022-11-19 18:57:19','1','2022-12-10 16:32:57',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2073,'售后退款','',2,1,2072,'trade/after-sale','education','mall/trade/afterSale/index','TradeAfterSale',0,1,1,1,'','2022-11-19 20:15:32','1','2023-04-08 11:43:19',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2074,'售后查询','trade:after-sale:query',3,1,2073,'','','',null,0,1,1,1,'','2022-11-19 20:15:33','1','2022-12-10 21:04:29',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2075,'秒杀活动关闭','promotion:sekill-activity:close',3,6,2059,'','','',null,0,1,1,1,'1','2022-11-28 20:20:15','1','2022-11-28 20:20:15',0); -INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2076,'订单列表','',2,0,2072,'trade/order','list','mall/trade/order/index','TradeOrder',0,1,1,1,'1','2022-12-10 21:05:44','1','2023-04-08 11:42:23',0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2049, '限时折扣活动创建', 'promotion:discount-activity:create', 3, 2, 2047, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2050, '限时折扣活动更新', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2051, '限时折扣活动删除', 'promotion:discount-activity:delete', 3, 4, 2047, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2052, '限时折扣活动关闭', 'promotion:discount-activity:close', 3, 5, 2047, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2059, '秒杀活动管理', '', 2, 0, 2030, 'seckill-activity', 'time-range', + 'mall/promotion/seckill/seckillActivity/index', 'PromotionSeckillActivity', 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '1', '2023-04-08 11:46:02', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2060, '秒杀活动查询', 'promotion:seckill-activity:query', 3, 1, 2059, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2061, '秒杀活动创建', 'promotion:seckill-activity:create', 3, 2, 2059, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2062, '秒杀活动更新', 'promotion:seckill-activity:update', 3, 3, 2059, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2063, '秒杀活动删除', 'promotion:seckill-activity:delete', 3, 4, 2059, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2064, '秒杀活动导出', 'promotion:seckill-activity:export', 3, 5, 2059, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2066, '秒杀时段管理', '', 2, 0, 2030, 'seckill-time', '', 'mall/promotion/seckill/SeckillConfig/index', + 'PromotionSeckillConfig', 0, 0, 1, 1, '', '2022-11-15 19:46:50', '1', '2023-04-08 11:46:17', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2067, '秒杀时段查询', 'promotion:seckill-time:query', 3, 1, 2066, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2068, '秒杀时段创建', 'promotion:seckill-time:create', 3, 2, 2066, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2069, '秒杀时段更新', 'promotion:seckill-time:update', 3, 3, 2066, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2070, '秒杀时段删除', 'promotion:seckill-time:delete', 3, 4, 2066, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2071, '秒杀时段导出', 'promotion:seckill-time:export', 3, 5, 2066, '', '', '', null, 0, 1, 1, 1, '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2072, '订单中心', '', 1, 65, 0, '/trade', 'order', null, null, 0, 1, 1, 1, '1', '2022-11-19 18:57:19', '1', + '2022-12-10 16:32:57', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2073, '售后退款', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index', + 'TradeAfterSale', 0, 1, 1, 1, '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2074, '售后查询', 'trade:after-sale:query', 3, 1, 2073, '', '', '', null, 0, 1, 1, 1, '', '2022-11-19 20:15:33', + '1', '2022-12-10 21:04:29', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2075, '秒杀活动关闭', 'promotion:sekill-activity:close', 3, 6, 2059, '', '', '', null, 0, 1, 1, 1, '1', + '2022-11-28 20:20:15', '1', '2022-11-28 20:20:15', 0); +INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON", + "COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE", + "ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") +VALUES (2076, '订单列表', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, 1, 1, 1, + '1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', 0); INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2077,'物流公司管理管理','',2,0,2072,'express-company','','mall/trade/expressCompany/index',null,0,1,1,1,'','2022-12-20 23:27:55','1','2022-12-20 23:36:20',0); INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2078,'物流公司管理查询','trade:express-company:query',3,1,2077,'','','',null,0,1,1,1,'','2022-12-20 23:27:55','','2022-12-20 23:27:55',0); INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2079,'物流公司管理创建','trade:express-company:create',3,2,2077,'','','',null,0,1,1,1,'','2022-12-20 23:27:55','','2022-12-20 23:27:55',0); diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 65e94c88d..a5d6982fd 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -1980,27 +1980,112 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2046, '满减送活动关闭', 'promotion:reward-activity:close', 3, 5, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2022-11-05 10:42:53', '1', '2022-11-05 10:42:53', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2047, '限时折扣活动', '', 2, 7, 2030, 'discount-activity', 'time', 'mall/promotion/discountActivity/index', 'PromotionDiscountActivity', 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '1', '2023-04-08 11:45:44', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2048, '限时折扣活动查询', 'promotion:discount-activity:query', 3, 1, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2049, '限时折扣活动创建', 'promotion:discount-activity:create', 3, 2, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2050, '限时折扣活动更新', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2051, '限时折扣活动删除', 'promotion:discount-activity:delete', 3, 4, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2052, '限时折扣活动关闭', 'promotion:discount-activity:close', 3, 5, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2059, '秒杀活动管理', '', 2, 0, 2030, 'seckill-activity', 'time-range', 'mall/promotion/seckill/seckillActivity/index', 'PromotionSeckillActivity', 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '1', '2023-04-08 11:46:02', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2060, '秒杀活动查询', 'promotion:seckill-activity:query', 3, 1, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2061, '秒杀活动创建', 'promotion:seckill-activity:create', 3, 2, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2062, '秒杀活动更新', 'promotion:seckill-activity:update', 3, 3, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2063, '秒杀活动删除', 'promotion:seckill-activity:delete', 3, 4, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2064, '秒杀活动导出', 'promotion:seckill-activity:export', 3, 5, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2066, '秒杀时段管理', '', 2, 0, 2030, 'seckill-time', '', 'mall/promotion/seckill/seckillTime/index', 'PromotionSeckillTime', 0, b'0', b'1', b'1', '', '2022-11-15 19:46:50', '1', '2023-04-08 11:46:17', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2067, '秒杀时段查询', 'promotion:seckill-time:query', 3, 1, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2068, '秒杀时段创建', 'promotion:seckill-time:create', 3, 2, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2069, '秒杀时段更新', 'promotion:seckill-time:update', 3, 3, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2070, '秒杀时段删除', 'promotion:seckill-time:delete', 3, 4, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2071, '秒杀时段导出', 'promotion:seckill-time:export', 3, 5, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2072, '订单中心', '', 1, 65, 0, '/trade', 'order', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-11-19 18:57:19', '1', '2022-12-10 16:32:57', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2073, '售后退款', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index', 'TradeAfterSale', 0, b'1', b'1', b'1', '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2074, '售后查询', 'trade:after-sale:query', 3, 1, 2073, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-19 20:15:33', '1', '2022-12-10 21:04:29', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2075, '秒杀活动关闭', 'promotion:sekill-activity:close', 3, 6, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2022-11-28 20:20:15', '1', '2022-11-28 20:20:15', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2076, '订单列表', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, b'1', b'1', b'1', '1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2049, '限时折扣活动创建', 'promotion:discount-activity:create', 3, 2, 2047, '', '', '', NULL, 0, b'1', b'1', + b'1', '', '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2050, '限时折扣活动更新', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', NULL, 0, b'1', b'1', + b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2051, '限时折扣活动删除', 'promotion:discount-activity:delete', 3, 4, 2047, '', '', '', NULL, 0, b'1', b'1', + b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2052, '限时折扣活动关闭', 'promotion:discount-activity:close', 3, 5, 2047, '', '', '', NULL, 0, b'1', b'1', + b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2059, '秒杀活动管理', '', 2, 0, 2030, 'seckill-activity', 'time-range', + 'mall/promotion/seckill/seckillActivity/index', 'PromotionSeckillActivity', 0, b'1', b'1', b'1', '', + '2022-11-06 22:24:49', '1', '2023-04-08 11:46:02', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2060, '秒杀活动查询', 'promotion:seckill-activity:query', 3, 1, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2061, '秒杀活动创建', 'promotion:seckill-activity:create', 3, 2, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', + '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2062, '秒杀活动更新', 'promotion:seckill-activity:update', 3, 3, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', + '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2063, '秒杀活动删除', 'promotion:seckill-activity:delete', 3, 4, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', + '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2064, '秒杀活动导出', 'promotion:seckill-activity:export', 3, 5, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', + '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2066, '秒杀时段管理', '', 2, 0, 2030, 'seckill-time', '', 'mall/promotion/seckill/SeckillConfig/index', + 'PromotionSeckillConfig', 0, b'0', b'1', b'1', '', '2022-11-15 19:46:50', '1', '2023-04-08 11:46:17', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2067, '秒杀时段查询', 'promotion:seckill-time:query', 3, 1, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2068, '秒杀时段创建', 'promotion:seckill-time:create', 3, 2, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2069, '秒杀时段更新', 'promotion:seckill-time:update', 3, 3, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2070, '秒杀时段删除', 'promotion:seckill-time:delete', 3, 4, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2071, '秒杀时段导出', 'promotion:seckill-time:export', 3, 5, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2072, '订单中心', '', 1, 65, 0, '/trade', 'order', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-11-19 18:57:19', + '1', '2022-12-10 16:32:57', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2073, '售后退款', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index', + 'TradeAfterSale', 0, b'1', b'1', b'1', '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2074, '售后查询', 'trade:after-sale:query', 3, 1, 2073, '', '', '', NULL, 0, b'1', b'1', b'1', '', + '2022-11-19 20:15:33', '1', '2022-12-10 21:04:29', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2075, '秒杀活动关闭', 'promotion:sekill-activity:close', 3, 6, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '1', + '2022-11-28 20:20:15', '1', '2022-11-28 20:20:15', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2076, '订单列表', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, b'1', b'1', + b'1', '1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2077, '物流公司管理管理', '', 2, 0, 2072, 'express-company', '', 'mall/trade/expressCompany/index', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '1', '2022-12-20 23:36:20', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2078, '物流公司管理查询', 'trade:express-company:query', 3, 1, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2079, '物流公司管理创建', 'trade:express-company:create', 3, 2, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0'); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java new file mode 100644 index 000000000..1e682b009 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java @@ -0,0 +1,87 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * 管理后台 - 秒杀时段相关接口 + * + * @author HUIHUI + */ +@Tag(name = "管理后台 - 秒杀时段") +@RestController +@RequestMapping("/promotion/seckill-config") +@Validated +public class SeckillConfigController { + + @Resource + private SeckillConfigService seckillConfigService; + + @PostMapping("/create") + @Operation(summary = "创建秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:create')") + public CommonResult createSeckillConfig(@Valid @RequestBody SeckillConfigCreateReqVO createReqVO) { + return success(seckillConfigService.createSeckillConfig(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:update')") + public CommonResult updateSeckillConfig(@Valid @RequestBody SeckillConfigUpdateReqVO updateReqVO) { + seckillConfigService.updateSeckillConfig(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除秒杀时段") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:delete')") + public CommonResult deleteSeckillConfig(@RequestParam("id") Long id) { + seckillConfigService.deleteSeckillConfig(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得秒杀时段") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") + public CommonResult getSeckillConfig(@RequestParam("id") Long id) { + SeckillConfigDO seckillConfig = seckillConfigService.getSeckillConfig(id); + return success(SeckillConfigConvert.INSTANCE.convert(seckillConfig)); + } + + @GetMapping("/list") + @Operation(summary = "获得所有秒杀时段列表") + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") + public CommonResult> getSeckillConfigList() { + List list = seckillConfigService.getSeckillConfigList(); + return success(SeckillConfigConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得秒杀活动分页") + @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") + public CommonResult> getSeckillActivityPage(@Valid SeckillConfigPageReqVO pageVO) { + PageResult pageResult = seckillConfigService.getSeckillConfigPage(pageVO); + return success(SeckillConfigConvert.INSTANCE.convertPage(pageResult)); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java deleted file mode 100644 index 992f34ab9..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 秒杀时段") -@RestController -@RequestMapping("/promotion/seckill-time") -@Validated -public class SeckillTimeController { - - @Resource - private SeckillTimeService seckillTimeService; - - @PostMapping("/create") - @Operation(summary = "创建秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')") - public CommonResult createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) { - return success(seckillTimeService.createSeckillTime(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')") - public CommonResult updateSeckillTime(@Valid @RequestBody SeckillTimeUpdateReqVO updateReqVO) { - seckillTimeService.updateSeckillTime(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除秒杀时段") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:delete')") - public CommonResult deleteSeckillTime(@RequestParam("id") Long id) { - seckillTimeService.deleteSeckillTime(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得秒杀时段") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") - public CommonResult getSeckillTime(@RequestParam("id") Long id) { - SeckillTimeDO seckillTime = seckillTimeService.getSeckillTime(id); - return success(SeckillTimeConvert.INSTANCE.convert(seckillTime)); - } - - @GetMapping("/list") - @Operation(summary = "获得所有秒杀时段列表") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") - public CommonResult> getSeckillTimeList() { - List list = seckillTimeService.getSeckillTimeList(); - return success(SeckillTimeConvert.INSTANCE.convertList(list)); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java index 31df31365..e7076ba63 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java @@ -54,7 +54,7 @@ public class SeckillActivityBaseVO { @Schema(description = "秒杀库存", example = "80") @Min(value = 0, message = "秒杀库存需要大于等于 0") - private Integer stock; + private Integer quota; @Schema(description = "每人限购", example = "10") // 如果为 0 则不限购 @Min(value = 0, message = "每人限购需要大于等于 0") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java new file mode 100644 index 000000000..bb6012015 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.time.LocalTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_HOUR_MINUTE_SECOND; + +/** + * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + * + * @author HUIHUI + */ +@Data +public class SeckillConfigBaseVO { + + @Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "早上场") + @NotNull(message = "秒杀时段名称不能为空") + private String name; + + @Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:00:00") + @NotNull(message = "开始时间点不能为空") + @DateTimeFormat(pattern = FORMAT_HOUR_MINUTE_SECOND) + private LocalTime startTime; + + @Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:00:00") + @NotNull(message = "结束时间点不能为空") + @DateTimeFormat(pattern = FORMAT_HOUR_MINUTE_SECOND) + private LocalTime endTime; + + @Schema(description = "秒杀主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") + @NotNull(message = "秒杀主图不能为空") + private String picUrl; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @NotNull(message = "状态不能为空") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigCreateReqVO.java similarity index 68% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigCreateReqVO.java index 4d3ccd092..8591e9d9a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigCreateReqVO.java @@ -1,14 +1,19 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +/** + * 管理后台 秒杀时段创建 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 秒杀时段创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SeckillTimeCreateReqVO extends SeckillTimeBaseVO { +public class SeckillConfigCreateReqVO extends SeckillConfigBaseVO { } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java similarity index 73% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java index 36853a0e0..f743885af 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config; import cn.iocoder.yudao.framework.common.pojo.PageParam; import io.swagger.v3.oas.annotations.media.Schema; @@ -9,21 +9,29 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalTime; +/** + * 管理后台 - 秒杀时段分页 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 秒杀时段分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SeckillTimePageReqVO extends PageParam { +public class SeckillConfigPageReqVO extends PageParam { @Schema(description = "秒杀时段名称", example = "上午场") private String name; + @Schema(description = "状态", example = "0") + private Integer status; + @Schema(description = "开始时间点", example = "16:30:40") @DateTimeFormat(pattern = "HH:mm:ss") - private LocalTime startTime; + private LocalTime[] startTime; @Schema(description = "结束时间点", example = "16:30:40") @DateTimeFormat(pattern = "HH:mm:ss") - private LocalTime endTime; + private LocalTime[] endTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigRespVO.java similarity index 62% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigRespVO.java index 6c45ecd54..53b4cc6a8 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigRespVO.java @@ -1,25 +1,34 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 管理后台 - 秒杀时段 Response VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 秒杀时段 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SeckillTimeRespVO extends SeckillTimeBaseVO { +public class SeckillConfigRespVO extends SeckillConfigBaseVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long id; - @Schema(description = "秒杀活动数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "秒杀活动数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer seckillActivityCount; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java similarity index 77% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java index 045de4983..1ad35b069 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -7,11 +7,16 @@ import lombok.ToString; import javax.validation.constraints.NotNull; +/** + * 管理后台 - 秒杀时段更新 Request VO + * + * @author HUIHUI + */ @Schema(description = "管理后台 - 秒杀时段更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SeckillTimeUpdateReqVO extends SeckillTimeBaseVO { +public class SeckillConfigUpdateReqVO extends SeckillConfigBaseVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "编号不能为空") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java deleted file mode 100644 index 0abbfea43..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.time.LocalTime; - -/** - * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class SeckillTimeBaseVO { - - @Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "上午场") - @NotNull(message = "秒杀时段名称不能为空") - private String name; - - @Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:30:40") - @NotNull(message = "开始时间点不能为空") - private LocalTime startTime; - - @Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:30:40") - @NotNull(message = "结束时间点不能为空") - private LocalTime endTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java new file mode 100644 index 000000000..f2a7283e4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 秒杀时段 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface SeckillConfigConvert { + + SeckillConfigConvert INSTANCE = Mappers.getMapper(SeckillConfigConvert.class); + + SeckillConfigDO convert(SeckillConfigCreateReqVO bean); + + SeckillConfigDO convert(SeckillConfigUpdateReqVO bean); + + @Mapping(target = "s") + SeckillConfigRespVO convert(SeckillConfigDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java deleted file mode 100644 index 4cea7a91c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime; - -import java.util.*; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; - -/** - * 秒杀时段 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface SeckillTimeConvert { - - SeckillTimeConvert INSTANCE = Mappers.getMapper(SeckillTimeConvert.class); - - SeckillTimeDO convert(SeckillTimeCreateReqVO bean); - - SeckillTimeDO convert(SeckillTimeUpdateReqVO bean); - - SeckillTimeRespVO convert(SeckillTimeDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java index 2adc0acfd..921679df7 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java @@ -57,7 +57,7 @@ public class SeckillProductDO extends BaseDO { /** * 秒杀库存 */ - private Integer stock; + private Integer quota; /** * 每人限购 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java similarity index 60% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java index df338c0e6..8b64ab10f 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java @@ -1,5 +1,6 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime; +package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -15,12 +16,12 @@ import java.time.LocalTime; * * @author 芋道源码 */ -@TableName("promotion_seckill_time") -@KeySequence("promotion_seckill_time_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName("promotion_seckill_config") +@KeySequence("promotion_seckill_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SeckillTimeDO extends BaseDO { +public class SeckillConfigDO extends BaseDO { /** * 编号 @@ -40,8 +41,14 @@ public class SeckillTimeDO extends BaseDO { */ private LocalTime endTime; /** - * 秒杀活动数量 + * 秒杀主图 */ - private Integer seckillActivityCount; + private String picUrl; + /** + * 状态 开启:0 禁用:1 + *

+ * 枚举 {@link CommonStatusEnum 对应的类} + */ + private Integer status; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java new file mode 100644 index 000000000..639991551 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalTime; +import java.util.Collection; +import java.util.List; + +@Mapper +public interface SeckillConfigMapper extends BaseMapperX { + + default List selectListByTime(LocalTime time) { + return selectList(SeckillConfigDO::getStartTime, SeckillConfigDO::getEndTime, time); + } + + default List selectListByTime(LocalTime startTime, LocalTime endTime) { + return selectList(new LambdaQueryWrapper() + .ge(SeckillConfigDO::getStartTime, startTime) + .le(SeckillConfigDO::getEndTime, endTime)); + } + + default void updateActivityCount(Collection ids, String type, Integer count) { + new LambdaUpdateChainWrapper<>(this) + .in(SeckillConfigDO::getId, ids) + .setSql("`seckill_activity_count` = `seckill_activity_count` " + type + count) + .update(); + } + + default PageResult selectPage(SeckillConfigPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(SeckillConfigDO::getName, reqVO.getName()) + .betweenIfPresent(SeckillConfigDO::getStartTime, reqVO.getStartTime()) + .betweenIfPresent(SeckillConfigDO::getEndTime, reqVO.getEndTime()) + .eqIfPresent(SeckillConfigDO::getStatus, reqVO.getStatus()) + .orderByDesc(SeckillConfigDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java deleted file mode 100644 index 46cfe5d3a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalTime; -import java.util.Collection; -import java.util.List; - -@Mapper -public interface SeckillTimeMapper extends BaseMapperX { - - default List selectListByTime(LocalTime time) { - return selectList(SeckillTimeDO::getStartTime, SeckillTimeDO::getEndTime, time); - } - - default List selectListByTime(LocalTime startTime, LocalTime endTime) { - return selectList(new LambdaQueryWrapper() - .ge(SeckillTimeDO::getStartTime, startTime) - .le(SeckillTimeDO::getEndTime, endTime)); - } - - default void updateActivityCount(Collection ids, String type, Integer count) { - new LambdaUpdateChainWrapper<>(this) - .in(SeckillTimeDO::getId, ids) - .setSql("`seckill_activity_count` = `seckill_activity_count` " + type + count) - .update(); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java index a0ff74dc8..1c3ed38fe 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java @@ -1,15 +1,16 @@ package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; -import java.util.*; -import javax.validation.*; - +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + /** * 秒杀活动 Service 接口 * @@ -77,4 +78,5 @@ public interface SeckillActivityService { * @return 活动商品列表 */ List getSeckillProductListByActivityId(Long id); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java index 45581d825..4e14ed723 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java @@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity. import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper; import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; +import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService; import cn.iocoder.yudao.module.promotion.util.PromotionUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -34,29 +34,30 @@ import static java.util.Arrays.asList; @Service @Validated public class SeckillActivityServiceImpl implements SeckillActivityService { + @Resource private SeckillActivityMapper seckillActivityMapper; @Resource private SeckillProductMapper seckillProductMapper; @Resource - private SeckillTimeService seckillTimeService; + private SeckillConfigService seckillConfigService; @Override public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { // 校验商品是否冲突 validateSeckillActivityProductConflicts(null, createReqVO.getProducts()); // 校验秒杀时段是否存在 - seckillTimeService.validateSeckillTimeExists(createReqVO.getTimeIds()); + seckillConfigService.validateSeckillConfigExists(createReqVO.getTimeIds()); // 插入秒杀活动 SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); seckillActivityMapper.insert(seckillActivity); // 插入商品 - List productDOS = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), seckillActivity); - seckillProductMapper.insertBatch(productDOS); + List productDOs = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), seckillActivity); + seckillProductMapper.insertBatch(productDOs); // 更新秒杀时段的秒杀活动数量 - seckillTimeService.sekillActivityCountIncr(createReqVO.getTimeIds()); + seckillConfigService.seckillActivityCountIncr(createReqVO.getTimeIds()); return seckillActivity.getId(); } @@ -77,17 +78,16 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { // 更新商品 updateSeckillProduct(updateReqVO); // 更新秒杀时段的秒杀活动数量 - updateSeckillTimeActivityCount(seckillActivity, updateReqVO.getTimeIds()); + updateSeckillConfigActivityCount(seckillActivity, updateReqVO.getTimeIds()); } - /** * 更新秒杀时段的秒杀活动数量 * * @param seckillActivity 查询出的秒杀活动 * @param updateTimeIds 更新后的秒杀时段id列表 */ - private void updateSeckillTimeActivityCount(SeckillActivityDO seckillActivity, List updateTimeIds) { + private void updateSeckillConfigActivityCount(SeckillActivityDO seckillActivity, List updateTimeIds) { // 查询出 timeIds List existsTimeIds = seckillActivity.getTimeIds(); // 需要减少的时间段 @@ -96,10 +96,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { updateTimeIds.removeIf(existsTimeIds::contains); // 更新减少时间段和增加时间段 if (CollUtil.isNotEmpty(updateTimeIds)) { - seckillTimeService.sekillActivityCountIncr(updateTimeIds); + seckillConfigService.seckillActivityCountIncr(updateTimeIds); } if (CollUtil.isNotEmpty(reduceIds)) { - seckillTimeService.sekillActivityCountDecr(reduceIds); + seckillConfigService.seckillActivityCountDecr(reduceIds); } } @@ -113,11 +113,11 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { * @param updateReqVO 更新的请求VO */ private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { - List seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); + List seckillProductDOs = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); List products = updateReqVO.getProducts(); // 计算需要删除的数据 - List deleteIds = CollectionUtils.convertList(seckillProductDOS, SeckillProductDO::getId, + List deleteIds = CollectionUtils.convertList(seckillProductDOs, SeckillProductDO::getId, seckillProductDO -> products.stream() .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product))); if (CollUtil.isNotEmpty(deleteIds)) { @@ -127,7 +127,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { // 计算需要新增的数据 List newSeckillProductDOs = CollectionUtils.convertList(products, product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); - newSeckillProductDOs.removeIf(product -> seckillProductDOS.stream() + newSeckillProductDOs.removeIf(product -> seckillProductDOs.stream() .anyMatch(seckillProduct -> SeckillActivityConvert.INSTANCE.isEquals(seckillProduct, product))); if (CollUtil.isNotEmpty(newSeckillProductDOs)) { seckillProductMapper.insertBatch(newSeckillProductDOs); @@ -147,21 +147,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { if (CollUtil.isEmpty(products)) { return; } - List seckillProductDOS = seckillProductMapper + List seckillProductDOs = seckillProductMapper .selectListBySkuIds(CollectionUtils.convertSet(products, SeckillActivityBaseVO.Product::getSkuId)); - if (CollUtil.isEmpty(seckillProductDOS)) { + if (CollUtil.isEmpty(seckillProductDOs)) { return; } - List seckillActivityDOS = seckillActivityMapper - .selectBatchIds(CollectionUtils.convertSet(seckillProductDOS, SeckillProductDO::getActivityId)); + List seckillActivityDOs = seckillActivityMapper + .selectBatchIds(CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getActivityId)); if (id != null) { // 排除自己这个活动 - seckillActivityDOS.removeIf(item -> id.equals(item.getId())); + seckillActivityDOs.removeIf(item -> id.equals(item.getId())); } // 排除不满足 status 的活动 List statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); - seckillActivityDOS.removeIf(item -> !statuses.contains(item.getStatus())); + seckillActivityDOs.removeIf(item -> !statuses.contains(item.getStatus())); // 如果非空,则说明冲突 - if (CollUtil.isNotEmpty(seckillActivityDOS)) { + if (CollUtil.isNotEmpty(seckillActivityDOs)) { throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); } } @@ -190,7 +190,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); } // 更新秒杀时段的秒杀活动数量 - seckillTimeService.sekillActivityCountDecr(seckillActivity.getTimeIds()); + seckillConfigService.seckillActivityCountDecr(seckillActivity.getTimeIds()); // 删除 seckillActivityMapper.deleteById(id); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigService.java similarity index 54% rename from yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java rename to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigService.java index 2e9c21249..b50e4e476 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigService.java @@ -1,8 +1,10 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; +package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; import javax.validation.Valid; import java.util.Collection; @@ -13,7 +15,7 @@ import java.util.List; * * @author halfninety */ -public interface SeckillTimeService { +public interface SeckillConfigService { /** * 创建秒杀时段 @@ -21,21 +23,21 @@ public interface SeckillTimeService { * @param createReqVO 创建信息 * @return 编号 */ - Long createSeckillTime(@Valid SeckillTimeCreateReqVO createReqVO); + Long createSeckillConfig(@Valid SeckillConfigCreateReqVO createReqVO); /** * 更新秒杀时段 * * @param updateReqVO 更新信息 */ - void updateSeckillTime(@Valid SeckillTimeUpdateReqVO updateReqVO); + void updateSeckillConfig(@Valid SeckillConfigUpdateReqVO updateReqVO); /** * 删除秒杀时段 * * @param id 编号 */ - void deleteSeckillTime(Long id); + void deleteSeckillConfig(Long id); /** * 获得秒杀时段 @@ -43,28 +45,28 @@ public interface SeckillTimeService { * @param id 编号 * @return 秒杀时段 */ - SeckillTimeDO getSeckillTime(Long id); + SeckillConfigDO getSeckillConfig(Long id); /** * 获得所有秒杀时段列表 * * @return 所有秒杀时段列表 */ - List getSeckillTimeList(); + List getSeckillConfigList(); /** * 校验秒杀时段是否存在 * * @param timeIds 秒杀时段id集合 */ - void validateSeckillTimeExists(Collection timeIds); + void validateSeckillConfigExists(Collection timeIds); /** * 秒杀时段列表的秒杀活动数量加 1 * * @param ids 秒杀时段id列表 */ - void sekillActivityCountIncr(Collection ids); + void seckillActivityCountIncr(Collection ids); /** @@ -72,5 +74,14 @@ public interface SeckillTimeService { * * @param ids 秒杀时段id列表 */ - void sekillActivityCountDecr(Collection ids); + void seckillActivityCountDecr(Collection ids); + + /** + * 获得秒杀时间段配置分页数据 + * + * @param pageVO 分页请求参数 + * @return 秒杀时段分页列表 + */ + PageResult getSeckillConfigPage(SeckillConfigPageReqVO pageVO); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java new file mode 100644 index 000000000..27497bea2 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java @@ -0,0 +1,131 @@ +package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalTime; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_CONFLICTS; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; + +/** + * 秒杀时段 Service 实现类 + * + * @author halfninety + */ +@Service +@Validated +public class SeckillConfigServiceImpl implements SeckillConfigService { + + @Resource + private SeckillConfigMapper seckillConfigMapper; + + @Override + public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) { + // 校验时间段是否冲突 + validateSeckillConfigConflict(null, createReqVO.getStartTime(), createReqVO.getEndTime()); + // 插入 + SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO); + seckillConfigMapper.insert(seckillConfig); + // 返回 + return seckillConfig.getId(); + } + + @Override + public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) { + // 校验存在 + this.validateSeckillConfigExists(updateReqVO.getId()); + // 校验时间段是否冲突 + validateSeckillConfigConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime()); + // 更新 + SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO); + seckillConfigMapper.updateById(updateObj); + } + + @Override + public void deleteSeckillConfig(Long id) { + // 校验存在 + this.validateSeckillConfigExists(id); + // 删除 + seckillConfigMapper.deleteById(id); + } + + private void validateSeckillConfigExists(Long id) { + if (seckillConfigMapper.selectById(id) == null) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + } + + /** + * 校验时间是否存在冲突 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + private void validateSeckillConfigConflict(Long id, LocalTime startTime, LocalTime endTime) { + //查询开始时间,结束时间,是否在别人的时间段内 + List startTimeList = seckillConfigMapper.selectListByTime(startTime); + List endTimeList = seckillConfigMapper.selectListByTime(endTime); + //查询自己时间段内是否有时间段 + List startEndTimeList = seckillConfigMapper.selectListByTime(startTime, endTime); + if (id != null) { + //移除自己 + startTimeList.removeIf(seckillConfig -> Objects.equals(seckillConfig.getId(), id)); + endTimeList.removeIf(seckillConfig -> Objects.equals(seckillConfig.getId(), id)); + startEndTimeList.removeIf(seckillConfig -> Objects.equals(seckillConfig.getId(), id)); + } + if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList) + || CollUtil.isNotEmpty(startEndTimeList)) { + throw exception(SECKILL_TIME_CONFLICTS); + } + } + + @Override + public SeckillConfigDO getSeckillConfig(Long id) { + return seckillConfigMapper.selectById(id); + } + + @Override + public List getSeckillConfigList() { + return seckillConfigMapper.selectList(); + } + + @Override + public void validateSeckillConfigExists(Collection timeIds) { + if (CollUtil.isEmpty(timeIds)) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + if (seckillConfigMapper.selectBatchIds(timeIds).size() != timeIds.size()) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + } + + @Override + public void seckillActivityCountIncr(Collection ids) { + seckillConfigMapper.updateActivityCount(ids, "+", 1); + } + + @Override + public void seckillActivityCountDecr(Collection ids) { + seckillConfigMapper.updateActivityCount(ids, "-", 1); + } + + @Override + public PageResult getSeckillConfigPage(SeckillConfigPageReqVO pageVO) { + return seckillConfigMapper.selectPage(pageVO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java deleted file mode 100644 index d38183860..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalTime; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_CONFLICTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; - -/** - * 秒杀时段 Service 实现类 - * - * @author halfninety - */ -@Service -@Validated -public class SeckillTimeServiceImpl implements SeckillTimeService { - - @Resource - private SeckillTimeMapper seckillTimeMapper; - - @Override - public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) { - // 校验时间段是否冲突 - validateSeckillTimeConflict(null, createReqVO.getStartTime(), createReqVO.getEndTime()); - // 插入 - SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO); - seckillTimeMapper.insert(seckillTime); - // 返回 - return seckillTime.getId(); - } - - @Override - public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) { - // 校验存在 - this.validateSeckillTimeExists(updateReqVO.getId()); - // 校验时间段是否冲突 - validateSeckillTimeConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime()); - // 更新 - SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO); - seckillTimeMapper.updateById(updateObj); - } - - @Override - public void deleteSeckillTime(Long id) { - // 校验存在 - this.validateSeckillTimeExists(id); - // 删除 - seckillTimeMapper.deleteById(id); - } - - private void validateSeckillTimeExists(Long id) { - if (seckillTimeMapper.selectById(id) == null) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - } - - /** - * 校验时间是否存在冲突 - * - * @param startTime 开始时间 - * @param endTime 结束时间 - */ - private void validateSeckillTimeConflict(Long id, LocalTime startTime, LocalTime endTime) { - //查询开始时间,结束时间,是否在别人的时间段内 - List startTimeList = seckillTimeMapper.selectListByTime(startTime); - List endTimeList = seckillTimeMapper.selectListByTime(endTime); - //查询自己时间段内是否有时间段 - List startEndTimeList = seckillTimeMapper.selectListByTime(startTime, endTime); - if (id != null) { - //移除自己 - startTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - endTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - startEndTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - } - if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList) - || CollUtil.isNotEmpty(startEndTimeList)) { - throw exception(SECKILL_TIME_CONFLICTS); - } - } - - @Override - public SeckillTimeDO getSeckillTime(Long id) { - return seckillTimeMapper.selectById(id); - } - - @Override - public List getSeckillTimeList() { - return seckillTimeMapper.selectList(); - } - - @Override - public void validateSeckillTimeExists(Collection timeIds) { - if (CollUtil.isEmpty(timeIds)) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - if (seckillTimeMapper.selectBatchIds(timeIds).size() != timeIds.size()) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - } - - @Override - public void sekillActivityCountIncr(Collection ids) { - seckillTimeMapper.updateActivityCount(ids, "+", 1); - } - - @Override - public void sekillActivityCountDecr(Collection ids) { - seckillTimeMapper.updateActivityCount(ids, "-", 1); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java new file mode 100644 index 000000000..306491aae --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java @@ -0,0 +1,190 @@ +package cn.iocoder.yudao.module.promotion.service.seckillconfig; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper; +import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigServiceImpl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * {@link SeckillConfigServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(SeckillConfigServiceImpl.class) +@Disabled // TODO 芋艿:未来开启 +public class SeckillConfigServiceImplTest extends BaseDbUnitTest { + + @Resource + private SeckillConfigServiceImpl SeckillConfigService; + + @Resource + private SeckillConfigMapper seckillConfigMapper; + + @Resource + private ObjectMapper objectMapper; + + @Test + public void testJacksonSerializ() { + + // 准备参数 + SeckillConfigCreateReqVO reqVO = randomPojo(SeckillConfigCreateReqVO.class); +// ObjectMapper objectMapper = new ObjectMapper(); + try { + String string = objectMapper.writeValueAsString(reqVO); + System.out.println(string); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + + } + + @Test + public void testCreateSeckillConfig_success() { + // 准备参数 + SeckillConfigCreateReqVO reqVO = randomPojo(SeckillConfigCreateReqVO.class); + + // 调用 + Long SeckillConfigId = SeckillConfigService.createSeckillConfig(reqVO); + // 断言 + assertNotNull(SeckillConfigId); + // 校验记录的属性是否正确 + SeckillConfigDO SeckillConfig = seckillConfigMapper.selectById(SeckillConfigId); + assertPojoEquals(reqVO, SeckillConfig); + } + + @Test + public void testUpdateSeckillConfig_success() { + // mock 数据 + SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class); + seckillConfigMapper.insert(dbSeckillConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class, o -> { + o.setId(dbSeckillConfig.getId()); // 设置更新的 ID + }); + + // 调用 + SeckillConfigService.updateSeckillConfig(reqVO); + // 校验是否更新正确 + SeckillConfigDO SeckillConfig = seckillConfigMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, SeckillConfig); + } + + @Test + public void testUpdateSeckillConfig_notExists() { + // 准备参数 + SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> SeckillConfigService.updateSeckillConfig(reqVO), SECKILL_TIME_NOT_EXISTS); + } + + @Test + public void testDeleteSeckillConfig_success() { + // mock 数据 + SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class); + seckillConfigMapper.insert(dbSeckillConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSeckillConfig.getId(); + + // 调用 + SeckillConfigService.deleteSeckillConfig(id); + // 校验数据不存在了 + assertNull(seckillConfigMapper.selectById(id)); + } + + @Test + public void testDeleteSeckillConfig_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> SeckillConfigService.deleteSeckillConfig(id), SECKILL_TIME_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillConfigPage() { + // mock 数据 +// SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class, o -> { // 等会查询到 +// o.setName(null); +// o.setStartTime(null); +// o.setEndTime(null); +// o.setCreateTime(null); +// }); +// seckillConfigMapper.insert(dbSeckillConfig); +// // 测试 name 不匹配 +// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setName(null))); +// // 测试 startTime 不匹配 +// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setStartTime(null))); +// // 测试 endTime 不匹配 +// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setEndTime(null))); +// // 测试 createTime 不匹配 +// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setCreateTime(null))); +// // 准备参数 +// SeckillConfigPageReqVO reqVO = new SeckillConfigPageReqVO(); +// reqVO.setName(null); +//// reqVO.setStartTime((new LocalTime())); +//// reqVO.setEndTime((new LocalTime[]{})); +//// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// PageResult pageResult = SeckillConfigService.getSeckillConfigPage(reqVO); +// // 断言 +// assertEquals(1, pageResult.getTotal()); +// assertEquals(1, pageResult.getList().size()); +// assertPojoEquals(dbSeckillConfig, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillConfigList() { + // mock 数据 + SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class, o -> { // 等会查询到 + o.setName(null); + o.setStartTime(null); + o.setEndTime(null); + o.setCreateTime(null); + }); + seckillConfigMapper.insert(dbSeckillConfig); + // 测试 name 不匹配 + seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setName(null))); + // 测试 startTime 不匹配 + seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setStartTime(null))); + // 测试 endTime 不匹配 + seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setEndTime(null))); + // 测试 createTime 不匹配 + seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setCreateTime(null))); + // 准备参数 +// SeckillConfigExportReqVO reqVO = new SeckillConfigExportReqVO(); +// reqVO.setName(null); +// reqVO.setStartTime((new LocalTime[]{})); +// reqVO.setEndTime((new LocalTime[]{})); +// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// List list = SeckillConfigService.getSeckillConfigList(reqVO); +// // 断言 +// assertEquals(1, list.size()); +// assertPojoEquals(dbSeckillConfig, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java deleted file mode 100644 index b6d7246d7..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java +++ /dev/null @@ -1,190 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckilltime; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeServiceImpl; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import javax.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link SeckillTimeServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(SeckillTimeServiceImpl.class) -@Disabled // TODO 芋艿:未来开启 -public class SeckillTimeServiceImplTest extends BaseDbUnitTest { - - @Resource - private SeckillTimeServiceImpl seckillTimeService; - - @Resource - private SeckillTimeMapper seckillTimeMapper; - - @Resource - private ObjectMapper objectMapper; - - @Test - public void testJacksonSerializ(){ - - // 准备参数 - SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); -// ObjectMapper objectMapper = new ObjectMapper(); - try { - String string = objectMapper.writeValueAsString(reqVO); - System.out.println(string); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - - - } - - @Test - public void testCreateSeckillTime_success() { - // 准备参数 - SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); - - // 调用 - Long seckillTimeId = seckillTimeService.createSeckillTime(reqVO); - // 断言 - assertNotNull(seckillTimeId); - // 校验记录的属性是否正确 - SeckillTimeDO seckillTime = seckillTimeMapper.selectById(seckillTimeId); - assertPojoEquals(reqVO, seckillTime); - } - - @Test - public void testUpdateSeckillTime_success() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); - seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 - // 准备参数 - SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class, o -> { - o.setId(dbSeckillTime.getId()); // 设置更新的 ID - }); - - // 调用 - seckillTimeService.updateSeckillTime(reqVO); - // 校验是否更新正确 - SeckillTimeDO seckillTime = seckillTimeMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, seckillTime); - } - - @Test - public void testUpdateSeckillTime_notExists() { - // 准备参数 - SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> seckillTimeService.updateSeckillTime(reqVO), SECKILL_TIME_NOT_EXISTS); - } - - @Test - public void testDeleteSeckillTime_success() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); - seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbSeckillTime.getId(); - - // 调用 - seckillTimeService.deleteSeckillTime(id); - // 校验数据不存在了 - assertNull(seckillTimeMapper.selectById(id)); - } - - @Test - public void testDeleteSeckillTime_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> seckillTimeService.deleteSeckillTime(id), SECKILL_TIME_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillTimePage() { - // mock 数据 -// SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 -// o.setName(null); -// o.setStartTime(null); -// o.setEndTime(null); -// o.setCreateTime(null); -// }); -// seckillTimeMapper.insert(dbSeckillTime); -// // 测试 name 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); -// // 测试 startTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); -// // 测试 endTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); -// // 测试 createTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); -// // 准备参数 -// SeckillTimePageReqVO reqVO = new SeckillTimePageReqVO(); -// reqVO.setName(null); -//// reqVO.setStartTime((new LocalTime())); -//// reqVO.setEndTime((new LocalTime[]{})); -//// reqVO.setCreateTime((new Date[]{})); -// -// // 调用 -// PageResult pageResult = seckillTimeService.getSeckillTimePage(reqVO); -// // 断言 -// assertEquals(1, pageResult.getTotal()); -// assertEquals(1, pageResult.getList().size()); -// assertPojoEquals(dbSeckillTime, pageResult.getList().get(0)); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillTimeList() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 - o.setName(null); - o.setStartTime(null); - o.setEndTime(null); - o.setCreateTime(null); - }); - seckillTimeMapper.insert(dbSeckillTime); - // 测试 name 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); - // 测试 startTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); - // 测试 endTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); - // 测试 createTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); - // 准备参数 -// SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO(); -// reqVO.setName(null); -// reqVO.setStartTime((new LocalTime[]{})); -// reqVO.setEndTime((new LocalTime[]{})); -// reqVO.setCreateTime((new Date[]{})); -// -// // 调用 -// List list = seckillTimeService.getSeckillTimeList(reqVO); -// // 断言 -// assertEquals(1, list.size()); -// assertPojoEquals(dbSeckillTime, list.get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql index d3f8e3718..ebeccb954 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql @@ -1,6 +1,14 @@ -DELETE FROM "market_activity"; -DELETE FROM "promotion_coupon_template"; -DELETE FROM "promotion_coupon"; -DELETE FROM "promotion_reward_activity"; -DELETE FROM "promotion_discount_activity"; -DELETE FROM "promotion_discount_product"; +DELETE +FROM "market_activity"; +DELETE +FROM "promotion_coupon_template"; +DELETE +FROM "promotion_coupon"; +DELETE +FROM "promotion_reward_activity"; +DELETE +FROM "promotion_discount_activity"; +DELETE +FROM "promotion_discount_product"; +DELETE +FROM "promotion_seckill_config"; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql index 7ff1a7239..4cbd4b72c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql @@ -108,17 +108,122 @@ CREATE TABLE IF NOT EXISTS "promotion_discount_activity" ( ) COMMENT '限时折扣活动'; CREATE TABLE IF NOT EXISTS "promotion_discount_product" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "activity_id" bigint NOT NULL, - "spu_id" bigint NOT NULL, - "sku_id" bigint NOT NULL, - "discount_type" int NOT NULL, - "discount_percent" int, - "discount_price" int, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '限时折扣活动'; + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "activity_id" bigint NOT NULL, + "spu_id" bigint NOT NULL, + "sku_id" bigint NOT NULL, + "discount_type" int NOT NULL, + "discount_percent" + int, + "discount_price" + int, + "creator" + varchar + DEFAULT + '', + "create_time" + datetime + NOT + NULL + DEFAULT + CURRENT_TIMESTAMP, + "updater" + varchar + DEFAULT + '', + "update_time" + datetime + NOT + NULL + DEFAULT + CURRENT_TIMESTAMP + ON + UPDATE + CURRENT_TIMESTAMP, + "deleted" + bit + NOT + NULL + DEFAULT + FALSE, + PRIMARY + KEY +( + "id" +) + ) COMMENT '限时折扣活动'; + +CREATE TABLE IF NOT EXISTS "promotion_seckill_config" +( + "id" + bigint + NOT + NULL + GENERATED + BY + DEFAULT AS + IDENTITY, + "name" + varchar + NOT + NULL, + "start_time" + varchar + NOT + NULL, + "end_time" + varchar + NOT + NULL, + "seckill_activity_count" + int + NOT + NULL, + "pic_url" + varchar + NOT + NULL, + "status" + varchar + NOT + NULL, + "creator" + varchar + DEFAULT + '', + "create_time" + datetime + NOT + NULL + DEFAULT + CURRENT_TIMESTAMP, + "updater" + varchar + DEFAULT + '', + "update_time" + datetime + NOT + NULL + DEFAULT + CURRENT_TIMESTAMP + ON + UPDATE + CURRENT_TIMESTAMP, + "deleted" + bit + NOT + NULL + DEFAULT + FALSE, + "tenant_id" + bigint + NOT + NULL, + PRIMARY + KEY +( + "id" +) + ) COMMENT '秒杀时段配置'; + diff --git a/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue index 5616fb983..f00af26a9 100644 --- a/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue +++ b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue @@ -17,7 +17,7 @@ - + @@ -38,8 +38,9 @@ v-hasPermi="['promotion:seckill-activity:create']">新增秒杀活动 - 管理参与场次 + 管理参与场次 + @@ -54,8 +55,8 @@ @@ -110,12 +111,13 @@ - - {{ item.name + ': { ' }} {{ item.startTime }} -- {{ item.endTime + - ' }' - }} - - + + {{ item.name + ': { ' }} {{ item.startTime }} -- {{ + item.endTime + + ' }' + }} + + @@ -186,10 +188,17 @@ diff --git a/yudao-ui-admin/src/views/pay/order/index.vue b/yudao-ui-admin/src/views/pay/order/index.vue index ecf70bb7a..1a0aeb486 100755 --- a/yudao-ui-admin/src/views/pay/order/index.vue +++ b/yudao-ui-admin/src/views/pay/order/index.vue @@ -3,13 +3,6 @@ - - - - - @@ -70,12 +63,9 @@ - - + + + + + + - diff --git a/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue b/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue new file mode 100644 index 000000000..1043c414a --- /dev/null +++ b/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue @@ -0,0 +1,268 @@ + + + diff --git a/yudao-ui-admin/src/views/pay/app/index.vue b/yudao-ui-admin/src/views/pay/app/index.vue index d280321a3..3a038f8be 100644 --- a/yudao-ui-admin/src/views/pay/app/index.vue +++ b/yudao-ui-admin/src/views/pay/app/index.vue @@ -216,7 +216,7 @@ - + @@ -225,13 +225,13 @@ import { createApp, updateApp, changeAppStatus, deleteApp, getApp, getAppPage } import { DICT_TYPE, getDictDatas } from "@/utils/dict"; import { PayType, PayChannelEnum, CommonStatusEnum } from "@/utils/constants"; import wechatChannelForm from "@/views/pay/app/components/wechatChannelForm"; -import aliPayChannelForm from "@/views/pay/app/components/aliPayChannelForm"; +import alipayChannelForm from "@/views/pay/app/components/alipayChannelForm"; export default { name: "PayApp", components: { "wechatChannelForm": wechatChannelForm, - "aliPayChannelForm": aliPayChannelForm + "alipayChannelForm": alipayChannelForm }, data() { return { @@ -285,13 +285,6 @@ export default { "appId": null, // 渠道编码 "payCode": null, - // 商户对象 - "payMerchant": { - // 编号 - "id": null, - // 名称 - "name": null - }, } }; }, @@ -426,14 +419,12 @@ export default { this.channelParam.aliPayOpen = false; } if (type === PayType.ALIPAY) { - this.channelParam.aliPayOpen = true; - this.channelParam.wechatOpen = false; + console.log(this.$refs['alipayChannelFormRef']) + this.$refs['alipayChannelFormRef'].open(row.id, payCode); + return; + // this.channelParam.aliPayOpen = true; + // this.channelParam.wechatOpen = false; } - this.channelParam.edit = false; - this.channelParam.loading = false; - this.channelParam.appId = row.id; - this.channelParam.payCode = payCode; - this.channelParam.payMerchant = row.payMerchant; }, /** * 根据渠道编码判断渠道列表中是否存在 From f92a5899f3bb9e7ee53cc002a10909467b31f5e8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 21 Jul 2023 21:50:05 +0800 Subject: [PATCH 211/232] =?UTF-8?q?mall=20+=20pay=EF=BC=9A=201.=20?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E7=9A=84?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-ui-admin/src/utils/constants.js | 8 - .../pay/app/components/alipayChannelForm.vue | 9 +- .../pay/app/components/wechatChannelForm.vue | 328 ------------------ .../pay/app/components/weixinChannelForm.vue | 257 ++++++++++++++ yudao-ui-admin/src/views/pay/app/index.vue | 167 ++++----- 5 files changed, 318 insertions(+), 451 deletions(-) delete mode 100644 yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue create mode 100644 yudao-ui-admin/src/views/pay/app/components/weixinChannelForm.vue diff --git a/yudao-ui-admin/src/utils/constants.js b/yudao-ui-admin/src/utils/constants.js index 70e0f5a02..a4805096d 100644 --- a/yudao-ui-admin/src/utils/constants.js +++ b/yudao-ui-admin/src/utils/constants.js @@ -180,14 +180,6 @@ export const PayDisplayModeEnum = { } } -/** - * 支付类型枚举 - */ -export const PayType = { - WECHAT: "WECHAT", - ALIPAY: "ALIPAY" -} - /** * 支付订单状态枚举 */ diff --git a/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue b/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue index 1043c414a..cb67b9d76 100644 --- a/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue +++ b/yudao-ui-admin/src/views/pay/app/components/alipayChannelForm.vue @@ -172,7 +172,7 @@ export default { this.formData = response.data; this.formData.config = JSON.parse(response.data.config); } - this.title = this.formData.id ? '创建支付渠道' : '编辑支付渠道' + this.title = !this.formData.id ? '创建支付渠道' : '编辑支付渠道' }).finally(() => { this.formLoading = false; }); @@ -257,12 +257,7 @@ export default { this.formData.config.rootCertContent = e.target.result } readFile.readAsText(event.file); - }, - + } } } - - diff --git a/yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue b/yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue deleted file mode 100644 index c3e691f9f..000000000 --- a/yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue +++ /dev/null @@ -1,328 +0,0 @@ - - - diff --git a/yudao-ui-admin/src/views/pay/app/components/weixinChannelForm.vue b/yudao-ui-admin/src/views/pay/app/components/weixinChannelForm.vue new file mode 100644 index 000000000..00e0773b5 --- /dev/null +++ b/yudao-ui-admin/src/views/pay/app/components/weixinChannelForm.vue @@ -0,0 +1,257 @@ + + diff --git a/yudao-ui-admin/src/views/pay/app/index.vue b/yudao-ui-admin/src/views/pay/app/index.vue index 3a038f8be..be92e0dae 100644 --- a/yudao-ui-admin/src/views/pay/app/index.vue +++ b/yudao-ui-admin/src/views/pay/app/index.vue @@ -9,7 +9,7 @@ - @@ -48,60 +48,55 @@ @@ -110,60 +105,55 @@ @@ -191,7 +181,7 @@ - + {{ dict.label }} @@ -214,24 +204,23 @@ - - + + From e27ec2fd50146abca9c5604e9f1c197e22d22341 Mon Sep 17 00:00:00 2001 From: "zhijiantianya@gmail.com" Date: Fri, 21 Jul 2023 22:02:39 +0800 Subject: [PATCH 212/232] =?UTF-8?q?by=20gateway:=201.=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E9=83=A8=E5=88=86=20refund=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/refund/PayRefundServiceImpl.java | 109 ++++---- .../service/order/PayOrderServiceTest.java | 244 +++++++++++++++++- .../service/refund/PayRefundServiceTest.java | 239 ++++++++++++++--- .../src/test/resources/sql/create_tables.sql | 16 +- 4 files changed, 492 insertions(+), 116 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 41f800393..ceaab0a43 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.service.refund; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.RandomUtil; +import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; @@ -16,9 +15,9 @@ import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; @@ -35,12 +34,11 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; /** * 退款订单 Service 实现类 @@ -60,6 +58,8 @@ public class PayRefundServiceImpl implements PayRefundService { @Resource private PayRefundMapper refundMapper; + @Resource + private PayNoRedisDAO noRedisDAO; @Resource private PayOrderService orderService; @@ -112,8 +112,9 @@ public class PayRefundServiceImpl implements PayRefundService { } // 2.1 插入退款单 + String no = noRedisDAO.generate(payProperties.getRefundNoPrefix()); refund = PayRefundConvert.INSTANCE.convert(reqDTO) - .setNo(generateRefundNo()).setOrderId(order.getId()) + .setNo(no).setOrderId(order.getId()) .setChannelId(order.getChannelId()).setChannelCode(order.getChannelCode()) // 商户相关的字段 .setNotifyUrl(app.getRefundNotifyUrl()) @@ -123,20 +124,27 @@ public class PayRefundServiceImpl implements PayRefundService { .setStatus(PayRefundStatusEnum.WAITING.getStatus()) .setPayPrice(order.getPrice()).setRefundPrice(reqDTO.getPrice()); refundMapper.insert(refund); - // 2.2 向渠道发起退款申请 - PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId()); - PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO() - .setPayPrice(order.getPrice()) - .setRefundPrice(reqDTO.getPrice()) - .setOutTradeNo(orderExtension.getNo()) - .setOutRefundNo(refund.getNo()) - .setNotifyUrl(genChannelRefundNotifyUrl(channel)) - .setReason(reqDTO.getReason()); - PayRefundRespDTO refundRespDTO = client.unifiedRefund(unifiedReqDTO); - // 2.3 处理退款返回 - notifyRefund(channel, refundRespDTO); + try { + // 2.2 向渠道发起退款申请 + PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO() + .setPayPrice(order.getPrice()) + .setRefundPrice(reqDTO.getPrice()) + .setOutTradeNo(order.getNo()) + .setOutRefundNo(refund.getNo()) + .setNotifyUrl(genChannelRefundNotifyUrl(channel)) + .setReason(reqDTO.getReason()); + PayRefundRespDTO refundRespDTO = client.unifiedRefund(unifiedReqDTO); + // 2.3 处理退款返回 + getSelf().notifyRefund(channel, refundRespDTO); + } catch (Throwable e) { + // 注意:这里仅打印异常,不进行抛出。 + // 原因是:虽然调用支付渠道进行退款发生异常(网络请求超时),实际退款成功。这个结果,后续通过退款回调、或者退款轮询补偿可以拿到。 + // 最终,在异常的情况下,支付中心会异步回调业务的退款回调接口,提供退款结果 + log.error("[createPayRefund][退款 id({}) requestDTO({}) 发生异常]", + refund.getId(), reqDTO, e); + } - // 成功在 退款回调中处理 + // 返回退款编号 return refund.getId(); } @@ -151,12 +159,12 @@ public class PayRefundServiceImpl implements PayRefundService { if (order == null) { throw exception(ErrorCodeConstants.ORDER_NOT_FOUND); } - // 校验状态,必须是支付状态 - if (!PayOrderStatusEnum.SUCCESS.getStatus().equals(order.getStatus())) { - throw exception(ErrorCodeConstants.ORDER_STATUS_IS_NOT_SUCCESS); + // 校验状态,必须是已支付、或者已退款 + if (!PayOrderStatusEnum.isSuccessOrRefund(order.getStatus())) { + throw exception(ORDER_REFUND_FAIL_STATUS_ERROR); } - // 校验金额 退款金额不能大于原定的金额 + // 校验金额,退款金额不能大于原定的金额 if (reqDTO.getPrice() + order.getRefundPrice() > order.getPrice()){ throw exception(ErrorCodeConstants.REFUND_PRICE_EXCEED); } @@ -178,38 +186,22 @@ public class PayRefundServiceImpl implements PayRefundService { return payProperties.getRefundNotifyUrl() + "/" + channel.getId(); } - private String generateRefundNo() { -// wx -// 2014 -// 10 -// 27 -// 20 -// 09 -// 39 -// 5522657 -// a690389285100 - // 目前的算法 - // 时间序列,年月日时分秒 14 位 - // 纯随机,6 位 TODO 芋艿:此处估计是会有问题的,后续在调整 - return DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss") + // 时间序列 - RandomUtil.randomInt(100000, 999999) // 随机。为什么是这个范围,因为偷懒 - ; - } - @Override public void notifyRefund(Long channelId, PayRefundRespDTO notify) { - // 校验支付渠道是否有效 - channelService.validPayChannel(channelId); - // 通知结果 - // 校验支付渠道是否有效 PayChannelDO channel = channelService.validPayChannel(channelId); // 更新退款订单 - TenantUtils.execute(channel.getTenantId(), () -> notifyRefund(channel, notify)); + TenantUtils.execute(channel.getTenantId(), () -> getSelf().notifyRefund(channel, notify)); } - // TODO 芋艿:事务问题 - private void notifyRefund(PayChannelDO channel, PayRefundRespDTO notify) { + /** + * 通知并更新订单的退款结果 + * + * @param channel 支付渠道 + * @param notify 通知 + */ + @Transactional(rollbackFor = Exception.class) // 注意,如果是方法内调用该方法,需要通过 getSelf().notifyRefund(channel, notify) 调用,否则事务不生效 + public void notifyRefund(PayChannelDO channel, PayRefundRespDTO notify) { // 情况一:退款成功 if (PayRefundStatusRespEnum.isSuccess(notify.getStatus())) { notifyRefundSuccess(channel, notify); @@ -226,14 +218,14 @@ public class PayRefundServiceImpl implements PayRefundService { PayRefundDO refund = refundMapper.selectByAppIdAndNo( channel.getAppId(), notify.getOutRefundNo()); if (refund == null) { - throw exception(ErrorCodeConstants.REFUND_NOT_FOUND); + throw exception(REFUND_NOT_FOUND); } if (PayRefundStatusEnum.isSuccess(refund.getStatus())) { // 如果已经是成功,直接返回,不用重复更新 log.info("[notifyRefundSuccess][退款订单({}) 已经是退款成功,无需更新]", refund.getId()); return; } if (!PayRefundStatusEnum.WAITING.getStatus().equals(refund.getStatus())) { - throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); + throw exception(REFUND_STATUS_IS_NOT_WAITING); } // 1.2 更新 PayRefundDO PayRefundDO updateRefundObj = new PayRefundDO() @@ -243,7 +235,7 @@ public class PayRefundServiceImpl implements PayRefundService { .setChannelNotifyData(toJsonString(notify)); int updateCounts = refundMapper.updateByIdAndStatus(refund.getId(), refund.getStatus(), updateRefundObj); if (updateCounts == 0) { // 校验状态,必须是等待状态 - throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); + throw exception(REFUND_STATUS_IS_NOT_WAITING); } log.info("[notifyRefundSuccess][退款订单({}) 更新为退款成功]", refund.getId()); @@ -261,14 +253,14 @@ public class PayRefundServiceImpl implements PayRefundService { PayRefundDO refund = refundMapper.selectByAppIdAndNo( channel.getAppId(), notify.getOutRefundNo()); if (refund == null) { - throw exception(ErrorCodeConstants.REFUND_NOT_FOUND); + throw exception(REFUND_NOT_FOUND); } if (PayRefundStatusEnum.isFailure(refund.getStatus())) { // 如果已经是成功,直接返回,不用重复更新 log.info("[notifyRefundSuccess][退款订单({}) 已经是退款关闭,无需更新]", refund.getId()); return; } if (!PayRefundStatusEnum.WAITING.getStatus().equals(refund.getStatus())) { - throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); + throw exception(REFUND_STATUS_IS_NOT_WAITING); } // 1.2 更新 PayRefundDO PayRefundDO updateRefundObj = new PayRefundDO() @@ -278,7 +270,7 @@ public class PayRefundServiceImpl implements PayRefundService { .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg()); int updateCounts = refundMapper.updateByIdAndStatus(refund.getId(), refund.getStatus(), updateRefundObj); if (updateCounts == 0) { // 校验状态,必须是等待状态 - throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); + throw exception(REFUND_STATUS_IS_NOT_WAITING); } log.info("[notifyRefundFailure][退款订单({}) 更新为退款失败]", refund.getId()); @@ -287,4 +279,13 @@ public class PayRefundServiceImpl implements PayRefundService { .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build()); } + /** + * 获得自身的代理对象,解决 AOP 生效问题 + * + * @return 自己 + */ + private PayRefundServiceImpl getSelf() { + return SpringUtil.getBean(getClass()); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java index e81568480..35bc7a835 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java @@ -30,7 +30,6 @@ import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatcher; import org.mockito.MockedStatic; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -44,8 +43,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -85,6 +83,51 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { when(properties.getOrderNotifyUrl()).thenReturn("http://127.0.0.1"); } + @Test + public void testGetOrder_id() { + // mock 数据(PayOrderDO) + PayOrderDO order = randomPojo(PayOrderDO.class); + orderMapper.insert(order); + // 准备参数 + Long id = order.getId(); + + // 调用 + PayOrderDO dbOrder = orderService.getOrder(id); + // 断言 + assertPojoEquals(dbOrder, order); + } + + @Test + public void testGetOrder_appIdAndMerchantOrderId() { + // mock 数据(PayOrderDO) + PayOrderDO order = randomPojo(PayOrderDO.class); + orderMapper.insert(order); + // 准备参数 + Long appId = order.getAppId(); + String merchantOrderId = order.getMerchantOrderId(); + + // 调用 + PayOrderDO dbOrder = orderService.getOrder(appId, merchantOrderId); + // 断言 + assertPojoEquals(dbOrder, order); + } + + @Test + public void testGetOrderCountByAppId() { + // mock 数据(PayOrderDO) + PayOrderDO order01 = randomPojo(PayOrderDO.class); + orderMapper.insert(order01); + PayOrderDO order02 = randomPojo(PayOrderDO.class); + orderMapper.insert(order02); + // 准备参数 + Long appId = order01.getAppId(); + + // 调用 + Long count = orderService.getOrderCountByAppId(appId); + // 断言 + assertEquals(count, 1L); + } + @Test public void testGetOrderPage() { // mock 数据 @@ -350,7 +393,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { // mock 方法(client) PayClient client = mock(PayClient.class); when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); - // mock 方法() + // mock 方法(支付渠道的调用) PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null) .setDisplayMode(PayOrderDisplayModeEnum.URL.getMode()).setDisplayContent("tudou")); when(client.unifiedOrder(argThat(payOrderUnifiedReqDTO -> { @@ -553,14 +596,193 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { assertPojoEquals(order, orderMapper.selectOne(null), "updateTime", "updater"); // 断言,调用 - verify(notifyService).createPayNotifyTask(argThat(new ArgumentMatcher() { - @Override - public boolean matches(PayNotifyTaskCreateReqDTO reqDTO) { - assertEquals(reqDTO.getType(), PayNotifyTypeEnum.ORDER.getType()); - assertEquals(reqDTO.getDataId(), orderExtension.getOrderId()); - return true; - } + verify(notifyService).createPayNotifyTask(argThat(reqDTO -> { + assertEquals(reqDTO.getType(), PayNotifyTypeEnum.ORDER.getType()); + assertEquals(reqDTO.getDataId(), orderExtension.getOrderId()); + return true; })); } + @Test + public void testNotifyOrderClosed_orderExtension_notFound() { + // 准备参数 + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)); + PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus())); + + // 调用,并断言异常 + assertServiceException(() -> orderService.notifyOrder(channel, notify), + ORDER_EXTENSION_NOT_FOUND); + } + + @Test + public void testNotifyOrderClosed_orderExtension_closed() { + // mock 数据(PayOrderExtensionDO) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus()) + .setNo("P110")); + orderExtensionMapper.insert(orderExtension); + // 准备参数 + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)); + PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus()) + .setOutTradeNo("P110")); + + // 调用,并断言 + orderService.notifyOrder(channel, notify); + // 断言 PayOrderExtensionDO :数据未更新,因为它是 CLOSED + assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null)); + } + + @Test + public void testNotifyOrderClosed_orderExtension_paid() { + // mock 数据(PayOrderExtensionDO) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()) + .setNo("P110")); + orderExtensionMapper.insert(orderExtension); + // 准备参数 + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)); + PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus()) + .setOutTradeNo("P110")); + + // 调用,并断言 + orderService.notifyOrder(channel, notify); + // 断言 PayOrderExtensionDO :数据未更新,因为它是 SUCCESS + assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null)); + } + + @Test + public void testNotifyOrderClosed_orderExtension_refund() { + // mock 数据(PayOrderExtensionDO) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setStatus(PayOrderStatusEnum.REFUND.getStatus()) + .setNo("P110")); + orderExtensionMapper.insert(orderExtension); + // 准备参数 + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)); + PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus()) + .setOutTradeNo("P110")); + + // 调用,并断言异常 + assertServiceException(() -> orderService.notifyOrder(channel, notify), + ORDER_EXTENSION_STATUS_IS_NOT_WAITING); + } + + @Test + public void testNotifyOrderClosed_orderExtension_waiting() { + // mock 数据(PayOrderExtensionDO) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()) + .setNo("P110")); + orderExtensionMapper.insert(orderExtension); + // 准备参数 + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)); + PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus()) + .setOutTradeNo("P110")); + + // 调用 + orderService.notifyOrder(channel, notify); + // 断言 PayOrderExtensionDO + orderExtension.setStatus(PayOrderStatusEnum.CLOSED.getStatus()).setChannelNotifyData(toJsonString(notify)) + .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg()); + assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null), + "updateTime", "updater"); + } + + @Test + public void testUpdateOrderRefundPrice_notFound() { + // 准备参数 + Long id = randomLongId(); + Integer incrRefundPrice = randomInteger(); + + // 调用,并断言异常 + assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice), + ORDER_NOT_FOUND); + } + + @Test + public void testUpdateOrderRefundPrice_waiting() { + testUpdateOrderRefundPrice_waitingOrClosed(PayOrderStatusEnum.WAITING.getStatus()); + } + + @Test + public void testUpdateOrderRefundPrice_closed() { + testUpdateOrderRefundPrice_waitingOrClosed(PayOrderStatusEnum.CLOSED.getStatus()); + } + + private void testUpdateOrderRefundPrice_waitingOrClosed(Integer status) { + // mock 数据(PayOrderDO) + PayOrderDO order = randomPojo(PayOrderDO.class, + o -> o.setStatus(status)); + orderMapper.insert(order); + // 准备参数 + Long id = order.getId(); + Integer incrRefundPrice = randomInteger(); + + // 调用,并断言异常 + assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice), + ORDER_REFUND_FAIL_STATUS_ERROR); + } + + @Test + public void testUpdateOrderRefundPrice_priceExceed() { + // mock 数据(PayOrderDO) + PayOrderDO order = randomPojo(PayOrderDO.class, + o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()) + .setRefundPrice(1).setPrice(10)); + orderMapper.insert(order); + // 准备参数 + Long id = order.getId(); + Integer incrRefundPrice = 10; + + // 调用,并断言异常 + assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice), + REFUND_PRICE_EXCEED); + } + + @Test + public void testUpdateOrderRefundPrice_refund() { + testUpdateOrderRefundPrice_refundOrSuccess(PayOrderStatusEnum.REFUND.getStatus()); + } + + @Test + public void testUpdateOrderRefundPrice_success() { + testUpdateOrderRefundPrice_refundOrSuccess(PayOrderStatusEnum.SUCCESS.getStatus()); + } + + private void testUpdateOrderRefundPrice_refundOrSuccess(Integer status) { + // mock 数据(PayOrderDO) + PayOrderDO order = randomPojo(PayOrderDO.class, + o -> o.setStatus(status).setRefundPrice(1).setPrice(10)); + orderMapper.insert(order); + // 准备参数 + Long id = order.getId(); + Integer incrRefundPrice = 8; + + // 调用 + orderService.updateOrderRefundPrice(id, incrRefundPrice); + // 断言 + order.setRefundPrice(9).setStatus(PayOrderStatusEnum.REFUND.getStatus()); + assertPojoEquals(order, orderMapper.selectOne(null), + "updateTime", "updater"); + } + + @Test + public void testGetOrderExtension() { + // mock 数据(PayOrderExtensionDO) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class); + orderExtensionMapper.insert(orderExtension); + // 准备参数 + Long id = orderExtension.getId(); + + // 调用 + PayOrderExtensionDO dbOrderExtension = orderService.getOrderExtension(id); + // 断言 + assertPojoEquals(dbOrderExtension, orderExtension); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java index 53f3cab26..fa01d6698 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java @@ -1,14 +1,19 @@ package cn.iocoder.yudao.module.pay.service.refund; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; @@ -24,12 +29,25 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -@Import(PayRefundServiceImpl.class) +/** + * {@link PayRefundServiceImpl} 的单元测试类 + * + * @author 芋艿 + */ +@Import({PayRefundServiceImpl.class, PayNoRedisDAO.class}) public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { @Resource @@ -56,45 +74,41 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { // mock 数据 PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 o.setAppId(1L); - o.setChannelId(1L); o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setOrderId(1L); - o.setNo("OT0000001"); o.setMerchantOrderId("MOT0000001"); o.setMerchantRefundId("MRF0000001"); - o.setNotifyUrl("https://www.cancanzi.com"); o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - o.setPayPrice(100); - o.setRefundPrice(500); - o.setReason("就是想退款了,你有意见吗"); - o.setUserIp("127.0.0.1"); o.setChannelOrderNo("CH0000001"); o.setChannelRefundNo("CHR0000001"); - o.setChannelErrorCode(""); - o.setChannelErrorMsg(""); - o.setSuccessTime(LocalDateTime.of(2021, 1, 1, 10, 10, 15)); - o.setCreateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 10)); - o.setUpdateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 35)); + o.setCreateTime(buildTime(2021, 1, 10)); }); refundMapper.insert(dbRefund); // 测试 appId 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); // 测试 channelCode 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantRefundNo 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112"))); + // 测试 merchantOrderId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantOrderId(randomString()))); + // 测试 merchantRefundId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId(randomString()))); + // 测试 channelOrderNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelOrderNo(randomString()))); + // 测试 channelRefundNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelRefundNo(randomString()))); // 测试 status 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); // 测试 createTime 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> - o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10)))); + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 PayRefundPageReqVO reqVO = new PayRefundPageReqVO(); reqVO.setAppId(1L); reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + reqVO.setMerchantOrderId("MOT0000001"); reqVO.setMerchantRefundId("MRF0000001"); - reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)})); + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + reqVO.setChannelOrderNo("CH0000001"); + reqVO.setChannelRefundNo("CHR0000001"); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 9, 2021, 1, 11)); // 调用 PageResult pageResult = refundService.getRefundPage(reqVO); @@ -109,45 +123,41 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { // mock 数据 PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 o.setAppId(1L); - o.setChannelId(1L); o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setOrderId(1L); - o.setNo("OT0000001"); o.setMerchantOrderId("MOT0000001"); o.setMerchantRefundId("MRF0000001"); - o.setNotifyUrl("https://www.cancanzi.com"); o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - o.setPayPrice(100); - o.setRefundPrice(500); - o.setReason("就是想退款了,你有意见吗"); - o.setUserIp("127.0.0.1"); o.setChannelOrderNo("CH0000001"); o.setChannelRefundNo("CHR0000001"); - o.setChannelErrorCode(""); - o.setChannelErrorMsg(""); - o.setSuccessTime(LocalDateTime.of(2021, 1, 1, 10, 10, 15)); - o.setCreateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 10)); - o.setUpdateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 35)); + o.setCreateTime(buildTime(2021, 1, 10)); }); refundMapper.insert(dbRefund); // 测试 appId 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); // 测试 channelCode 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantRefundNo 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112"))); + // 测试 merchantOrderId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantOrderId(randomString()))); + // 测试 merchantRefundId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId(randomString()))); + // 测试 channelOrderNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelOrderNo(randomString()))); + // 测试 channelRefundNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelRefundNo(randomString()))); // 测试 status 不匹配 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); // 测试 createTime 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> - o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10)))); - + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 PayRefundExportReqVO reqVO = new PayRefundExportReqVO(); reqVO.setAppId(1L); reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)})); + reqVO.setMerchantOrderId("MOT0000001"); + reqVO.setMerchantRefundId("MRF0000001"); + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + reqVO.setChannelOrderNo("CH0000001"); + reqVO.setChannelRefundNo("CHR0000001"); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 9, 2021, 1, 11)); // 调用 List list = refundService.getRefundList(reqVO); @@ -156,4 +166,151 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { assertPojoEquals(dbRefund, list.get(0)); } + @Test + public void testCreateRefund_orderNotFound() { + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L)); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + ORDER_NOT_FOUND); + } + + @Test + public void testCreateRefund_orderWaiting() { + testCreateRefund_orderWaitingOrClosed(PayOrderStatusEnum.WAITING.getStatus()); + } + + @Test + public void testCreateRefund_orderClosed() { + testCreateRefund_orderWaitingOrClosed(PayOrderStatusEnum.CLOSED.getStatus()); + } + + private void testCreateRefund_orderWaitingOrClosed(Integer status) { + // 准备参数 + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L).setMerchantOrderId("100")); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(status)); + when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + ORDER_REFUND_FAIL_STATUS_ERROR); + } + + @Test + public void testCreateRefund_refundPriceExceed() { + // 准备参数 + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(10)); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> + o.setStatus(PayOrderStatusEnum.REFUND.getStatus()) + .setPrice(10).setRefundPrice(1)); + when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + REFUND_PRICE_EXCEED); + } + + @Test + public void testCreateRefund_orderHasRefunding() { + // 准备参数 + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(10)); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> + o.setStatus(PayOrderStatusEnum.REFUND.getStatus()) + .setPrice(10).setRefundPrice(1)); + when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); + // mock 数据(refund 在退款中) + PayRefundDO refund = randomPojo(PayRefundDO.class, o -> + o.setOrderId(order.getId()).setStatus(PayOrderStatusEnum.WAITING.getStatus())); + refundMapper.insert(refund); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + REFUND_PRICE_EXCEED); + } + + @Test + public void testCreateRefund_channelNotFound() { + // 准备参数 + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(9)); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> + o.setStatus(PayOrderStatusEnum.REFUND.getStatus()) + .setPrice(10).setRefundPrice(1) + .setChannelId(1L).setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())); + when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); + // mock 方法(channel) + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L) + .setCode(PayChannelEnum.ALIPAY_APP.getCode())); + when(channelService.validPayChannel(eq(1L))).thenReturn(channel); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + CHANNEL_NOT_FOUND); + } + + @Test + public void testCreateRefund_refundExists() { + // 准备参数 + PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class, + o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(9) + .setReason("测试退款")); + // mock 方法(app) + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); + when(appService.validPayApp(eq(1L))).thenReturn(app); + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> + o.setStatus(PayOrderStatusEnum.REFUND.getStatus()) + .setPrice(10).setRefundPrice(1) + .setChannelId(1L).setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())); + when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); + // mock 方法(channel) + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L) + .setCode(PayChannelEnum.ALIPAY_APP.getCode())); + when(channelService.validPayChannel(eq(1L))).thenReturn(channel); + // mock 方法(client) + PayClient client = mock(PayClient.class); + when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); + // mock 数据(refund 已存在) + PayRefundDO refund = randomPojo(PayRefundDO.class, o -> + o.setOrderId(order.getId()).setStatus(PayOrderStatusEnum.WAITING.getStatus())); + refundMapper.insert(refund); + + // 调用,并断言异常 + assertServiceException(() -> refundService.createPayRefund(reqDTO), + REFUND_EXISTS); + } + + @Test + public void testCreateRefund_invokeException() { + + } + + @Test + public void testCreateRefund_invokeSuccess() { + + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql index a748b2340..7d7d2435c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql @@ -82,29 +82,25 @@ CREATE TABLE IF NOT EXISTS `pay_order_extension` ( CREATE TABLE IF NOT EXISTS `pay_refund` ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, + `no` varchar(64) NOT NULL, `app_id` bigint(20) NOT NULL, `channel_id` bigint(20) NOT NULL, `channel_code` varchar(32) NOT NULL, `order_id` bigint(20) NOT NULL, - `trade_no` varchar(64) NOT NULL, `merchant_order_id` varchar(64) NOT NULL, - `merchant_refund_no` varchar(64) NOT NULL, + `merchant_refund_id` varchar(64) NOT NULL, `notify_url` varchar(1024) NOT NULL, - `notify_status` tinyint(4) NOT NULL, `status` tinyint(4) NOT NULL, - `type` tinyint(4) NOT NULL, - `pay_amount` bigint(20) NOT NULL, - `refund_amount` bigint(20) NOT NULL, + `pay_price` bigint(20) NOT NULL, + `refund_price` bigint(20) NOT NULL, `reason` varchar(256) NOT NULL, `user_ip` varchar(50) NULL DEFAULT NULL, `channel_order_no` varchar(64) NOT NULL, `channel_refund_no` varchar(64) NULL DEFAULT NULL, + `success_time` datetime(0) NULL DEFAULT NULL, `channel_error_code` varchar(128) NULL DEFAULT NULL, `channel_error_msg` varchar(256) NULL DEFAULT NULL, - `channel_extras` varchar(1024) NULL DEFAULT NULL, - `expire_time` datetime(0) NULL DEFAULT NULL, - `success_time` datetime(0) NULL DEFAULT NULL, - `notify_time` datetime(0) NULL DEFAULT NULL, + `channel_notify_data` varchar(1024) NULL, `creator` varchar(64) NULL DEFAULT '', `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, `updater` varchar(64) NULL DEFAULT '', From f46a0371640d4ceb14e361a2284c9b51455c2285 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 22 Jul 2023 11:19:42 +0800 Subject: [PATCH 213/232] =?UTF-8?q?mall=20+=20pay=EF=BC=9A=201.=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E4=BB=98=E5=AE=9D=20Client=20?= =?UTF-8?q?=E7=9A=84=E6=9F=A5=E8=AF=A2=E8=AE=A2=E5=8D=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/pay/core/client/PayClient.java | 10 ++++- .../client/dto/order/PayOrderRespDTO.java | 44 ++++++++++--------- .../core/client/impl/AbstractPayClient.java | 14 ++++++ .../impl/alipay/AbstractAlipayPayClient.java | 42 +++++++++++++++--- .../impl/weixin/AbstractWxPayClient.java | 11 +++-- .../client/impl/weixin/WxBarPayClient.java | 2 +- 6 files changed, 91 insertions(+), 32 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index 9362466a6..15ce53e95 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -27,7 +27,7 @@ public interface PayClient { * 调用支付渠道,统一下单 * * @param reqDTO 下单信息 - * @return 各支付渠道的返回结果 + * @return 支付订单信息 */ PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO); @@ -40,6 +40,14 @@ public interface PayClient { */ PayOrderRespDTO parseOrderNotify(Map params, String body); + /** + * 获得支付订单信息 + * + * @param outTradeNo 外部订单号 + * @return 支付订单信息 + */ + PayOrderRespDTO getOrder(String outTradeNo); + // ============ 退款相关 ========== /** diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java index 163ffce65..82050a6fc 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java @@ -94,38 +94,40 @@ public class PayOrderRespDTO { /** * 创建【SUCCESS】状态的订单返回 */ - public PayOrderRespDTO(String channelOrderNo, String channelUserId, LocalDateTime successTime, - String outTradeNo, Object rawData) { - this.status = PayOrderStatusRespEnum.SUCCESS.getStatus(); - this.channelOrderNo = channelOrderNo; - this.channelUserId = channelUserId; - this.successTime = successTime; + public static PayOrderRespDTO successOf(String channelOrderNo, String channelUserId, LocalDateTime successTime, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.status = PayOrderStatusRespEnum.SUCCESS.getStatus(); + respDTO.channelOrderNo = channelOrderNo; + respDTO.channelUserId = channelUserId; + respDTO.successTime = successTime; // 相对通用的字段 - this.outTradeNo = outTradeNo; - this.rawData = rawData; + respDTO.outTradeNo = outTradeNo; + respDTO.rawData = rawData; + return respDTO; } /** - * 创建【SUCCESS】或【CLOSED】状态的订单返回,适合支付渠道回调时 + * 创建指定状态的订单返回,适合支付渠道回调时 */ - public PayOrderRespDTO(Integer status, String channelOrderNo, String channelUserId, LocalDateTime successTime, - String outTradeNo, Object rawData) { - this.status = status; - this.channelOrderNo = channelOrderNo; - this.channelUserId = channelUserId; - this.successTime = successTime; + public static PayOrderRespDTO of(Integer status, String channelOrderNo, String channelUserId, LocalDateTime successTime, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.status = status; + respDTO.channelOrderNo = channelOrderNo; + respDTO.channelUserId = channelUserId; + respDTO.successTime = successTime; // 相对通用的字段 - this.outTradeNo = outTradeNo; - this.rawData = rawData; + respDTO.outTradeNo = outTradeNo; + respDTO.rawData = rawData; + return respDTO; } /** * 创建【CLOSED】状态的订单返回,适合调用支付渠道失败时 - * - * 参数和 {@link #PayOrderRespDTO(String, String, String, Object)} 冲突,所以独立个方法出来 */ - public static PayOrderRespDTO build(String channelErrorCode, String channelErrorMsg, - String outTradeNo, Object rawData) { + public static PayOrderRespDTO closedOf(String channelErrorCode, String channelErrorMsg, + String outTradeNo, Object rawData) { PayOrderRespDTO respDTO = new PayOrderRespDTO(); respDTO.status = PayOrderStatusRespEnum.CLOSED.getStatus(); respDTO.channelErrorCode = channelErrorCode; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index 194432738..bd4580e2d 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -107,6 +107,20 @@ public abstract class AbstractPayClient implemen protected abstract PayOrderRespDTO doParseOrderNotify(Map params, String body) throws Throwable; + @Override + public PayOrderRespDTO getOrder(String outTradeNo) { + try { + return doGetOrder(outTradeNo); + } catch (Throwable ex) { + log.error("[getOrder][客户端({}) outTradeNo({}) 查询支付单异常]", + getId(), outTradeNo, ex); + throw buildPayException(ex); + } + } + + protected abstract PayOrderRespDTO doGetOrder(String outTradeNo) + throws Throwable; + // ============ 退款相关 ========== @Override diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index 8c4a66b11..44dea94ce 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -17,9 +17,12 @@ import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConfig; import com.alipay.api.AlipayResponse; import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.AlipayTradeQueryModel; import com.alipay.api.domain.AlipayTradeRefundModel; import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.request.AlipayTradeQueryRequest; import com.alipay.api.request.AlipayTradeRefundRequest; +import com.alipay.api.response.AlipayTradeQueryResponse; import com.alipay.api.response.AlipayTradeRefundResponse; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -63,7 +66,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient 0) { status = PayOrderStatusRespEnum.REFUND.getStatus(); @@ -87,10 +87,40 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient) () -> { throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body)); }); - return new PayOrderRespDTO(status, bodyObj.get("trade_no"), bodyObj.get("seller_id"), parseTime(params.get("gmt_payment")), + return PayOrderRespDTO.of(status, bodyObj.get("trade_no"), bodyObj.get("seller_id"), parseTime(params.get("gmt_payment")), bodyObj.get("out_trade_no"), body); } + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable { + // 1.1 构建 AlipayTradeRefundModel 请求 + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + model.setOutTradeNo(outTradeNo); + // 1.2 构建 AlipayTradeQueryRequest 请求 + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + request.setBizModel(model); + + // 2.1 执行请求 + AlipayTradeQueryResponse response = client.execute(request); + if (!response.isSuccess()) { + return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + outTradeNo, response); + } + // 2.2 解析订单的状态 + Integer status = parseStatus(response.getTradeStatus()); + Assert.notNull(status, (Supplier) () -> { + throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody())); + }); + return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()), + outTradeNo, response); + } + + private Integer parseStatus(String tradeStatus) { + return Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusRespEnum.WAITING.getStatus() + : ObjectUtils.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusRespEnum.SUCCESS.getStatus() + : Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusRespEnum.CLOSED.getStatus() : null; + } + // ============ 退款相关 ========== /** diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index eeef301c0..e15b06a5f 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -90,7 +90,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Sat, 22 Jul 2023 12:07:18 +0800 Subject: [PATCH 214/232] =?UTF-8?q?mall=20+=20pay=EF=BC=9A=201.=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=20Client?= =?UTF-8?q?=20=E7=9A=84=E6=9F=A5=E8=AF=A2=E8=AE=A2=E5=8D=95=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/alipay/AbstractAlipayPayClient.java | 2 +- .../impl/weixin/AbstractWxPayClient.java | 65 +++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index 44dea94ce..f5c072a2d 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -115,7 +115,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body) throws WxPayException { - // 微信支付 v2 回调结果处理 switch (config.getApiVersion()) { case API_VERSION_V2: return doParseOrderNotifyV2(body); @@ -130,7 +133,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Sat, 22 Jul 2023 13:19:22 +0800 Subject: [PATCH 215/232] =?UTF-8?q?mall=20+=20pay=EF=BC=9A=201.=20?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E6=94=AF=E4=BB=98=E6=97=B6=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=AE=9E=E9=99=85=E5=B7=B2=E6=94=AF=E4=BB=98=E7=9A=84?= =?UTF-8?q?=E4=BA=8C=E6=AC=A1=E6=A0=A1=E9=AA=8C=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/pay/enums/ErrorCodeConstants.java | 3 +- .../admin/refund/PayRefundController.java | 3 - .../mysql/order/PayOrderExtensionMapper.java | 6 ++ .../service/order/PayOrderServiceImpl.java | 46 +++++++++++-- .../service/order/PayOrderServiceTest.java | 66 ++++++++++++++++++- yudao-ui-admin/src/views/pay/app/index.vue | 1 - .../src/views/pay/cashier/index.vue | 1 - 7 files changed, 114 insertions(+), 12 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 7cc1b815c..8e2f935fc 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -23,7 +23,7 @@ public interface ErrorCodeConstants { // ========== ORDER 模块 1007002000 ========== ErrorCode ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); ErrorCode ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); - ErrorCode ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); + ErrorCode ORDER_STATUS_IS_SUCCESS = new ErrorCode(1007002002, "订单已支付,请刷新页面"); ErrorCode ORDER_IS_EXPIRED = new ErrorCode(1007002003, "支付订单已经过期"); ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}"); ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款"); @@ -31,6 +31,7 @@ public interface ErrorCodeConstants { // ========== ORDER 模块(拓展单) 1007003000 ========== ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); ErrorCode ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); + ErrorCode ORDER_EXTENSION_IS_PAID = new ErrorCode(1007003002, "订单已支付,请等待支付结果"); // ========== 支付模块(退款) 1007006000 ========== ErrorCode REFUND_PRICE_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java index 24e2b22e5..df131ddd3 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.service.app.PayAppService; -import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -44,8 +43,6 @@ public class PayRefundController { private PayRefundService refundService; @Resource private PayAppService appService; - @Resource - private PayOrderService orderService; @GetMapping("/get") @Operation(summary = "获得退款订单") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java index a8918f441..145818417 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface PayOrderExtensionMapper extends BaseMapperX { @@ -17,4 +19,8 @@ public interface PayOrderExtensionMapper extends BaseMapperX selectListByOrderId(Long orderId) { + return selectList(PayOrderExtensionDO::getOrderId, orderId); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java index 64ecaff94..ee9bcc0aa 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.pay.service.order; -import cn.hutool.core.lang.Pair; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; @@ -33,6 +32,7 @@ import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; import cn.iocoder.yudao.module.pay.util.MoneyUtils; +import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -129,10 +129,10 @@ public class PayOrderServiceImpl implements PayOrderService { @Override // 注意,这里不能添加事务注解,避免调用支付渠道失败时,将 PayOrderExtensionDO 回滚了 public PayOrderSubmitRespVO submitOrder(PayOrderSubmitReqVO reqVO, String userIp) { - // 1. 获得 PayOrderDO ,并校验其是否存在 + // 1.1 获得 PayOrderDO ,并校验其是否存在 PayOrderDO order = validateOrderCanSubmit(reqVO.getId()); - // 1.2 校验支付渠道是否有效 - PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqVO.getChannelCode()); + // 1.32 校验支付渠道是否有效 + PayChannelDO channel = validateChannelCanSubmit(order.getAppId(), reqVO.getChannelCode()); PayClient client = payClientFactory.getPayClient(channel.getId()); // 2. 插入 PayOrderExtensionDO @@ -173,16 +173,52 @@ public class PayOrderServiceImpl implements PayOrderService { if (order == null) { // 是否存在 throw exception(ORDER_NOT_FOUND); } + if (PayOrderStatusEnum.isSuccess(order.getStatus())) { // 校验状态,发现已支付 + throw exception(ORDER_STATUS_IS_SUCCESS); + } if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 throw exception(ORDER_STATUS_IS_NOT_WAITING); } if (LocalDateTimeUtils.beforeNow(order.getExpireTime())) { // 校验是否过期 throw exception(ORDER_IS_EXPIRED); } + + // 【重要】校验是否支付拓展单已支付,只是没有回调、或者数据不正常 + validateOrderActuallyPaid(id); return order; } - private PayChannelDO validatePayChannelCanSubmit(Long appId, String channelCode) { + /** + * 校验支付订单实际已支付 + * + * @param id 支付编号 + */ + @VisibleForTesting + void validateOrderActuallyPaid(Long id) { + List orderExtensions = orderExtensionMapper.selectListByOrderId(id); + orderExtensions.forEach(orderExtension -> { + // 情况一:校验数据库中的 orderExtension 是不是已支付 + if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) { + log.warn("[validateOrderCanSubmit][order({}) 的 extension({}) 已支付,可能是数据不一致]", + id, orderExtension.getId()); + throw exception(ORDER_EXTENSION_IS_PAID); + } + // 情况二:调用三方接口,查询支付单状态,是不是已支付 + PayClient payClient = payClientFactory.getPayClient(orderExtension.getChannelId()); + if (payClient == null) { + log.error("[validateOrderCanSubmit][渠道编号({}) 找不到对应的支付客户端]", orderExtension.getChannelId()); + return; + } + PayOrderRespDTO respDTO = payClient.getOrder(orderExtension.getNo()); + if (respDTO != null && PayOrderStatusRespEnum.isSuccess(respDTO.getStatus())) { + log.warn("[validateOrderCanSubmit][order({}) 的 PayOrderRespDTO({}) 已支付,可能是回调延迟]", + id, toJsonString(respDTO)); + throw exception(ORDER_EXTENSION_IS_PAID); + } + }); + } + + private PayChannelDO validateChannelCanSubmit(Long appId, String channelCode) { // 校验 App appService.validPayApp(appId); // 校验支付渠道是否有效 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java index 35bc7a835..06088eb35 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java @@ -267,7 +267,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { @Test public void testSubmitOrder_notWaiting() { // mock 数据(order) - PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.REFUND.getStatus())); orderMapper.insert(order); // 准备参数 PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId())); @@ -277,6 +277,19 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { assertServiceException(() -> orderService.submitOrder(reqVO, userIp), ORDER_STATUS_IS_NOT_WAITING); } + @Test + public void testSubmitOrder_isSuccess() { + // mock 数据(order) + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); + orderMapper.insert(order); + // 准备参数 + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId())); + String userIp = randomString(); + + // 调用, 并断言异常 + assertServiceException(() -> orderService.submitOrder(reqVO, userIp), ORDER_STATUS_IS_SUCCESS); + } + @Test public void testSubmitOrder_expired() { // mock 数据(order) @@ -426,6 +439,57 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { } } + @Test + public void testValidateOrderActuallyPaid_dbPaid() { + // 准备参数 + Long id = randomLongId(); + // mock 方法(OrderExtension 已支付) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); + orderExtensionMapper.insert(orderExtension); + + // 调用,并断言异常 + assertServiceException(() -> orderService.validateOrderActuallyPaid(id), + ORDER_EXTENSION_IS_PAID); + } + + @Test + public void testValidateOrderActuallyPaid_remotePaid() { + // 准备参数 + Long id = randomLongId(); + // mock 方法(OrderExtension 已支付) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus())); + orderExtensionMapper.insert(orderExtension); + // mock 方法(PayClient 已支付) + PayClient client = mock(PayClient.class); + when(payClientFactory.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); + when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()))); + + // 调用,并断言异常 + assertServiceException(() -> orderService.validateOrderActuallyPaid(id), + ORDER_EXTENSION_IS_PAID); + } + + @Test + public void testValidateOrderActuallyPaid_success() { + // 准备参数 + Long id = randomLongId(); + // mock 方法(OrderExtension 已支付) + PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class, + o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus())); + orderExtensionMapper.insert(orderExtension); + // mock 方法(PayClient 已支付) + PayClient client = mock(PayClient.class); + when(payClientFactory.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); + when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); + + // 调用,并断言异常 + orderService.validateOrderActuallyPaid(id); + } + @Test public void testNotifyOrder_channelId() { PayOrderServiceImpl payOrderServiceImpl = mock(PayOrderServiceImpl.class); diff --git a/yudao-ui-admin/src/views/pay/app/index.vue b/yudao-ui-admin/src/views/pay/app/index.vue index be92e0dae..8c83856cb 100644 --- a/yudao-ui-admin/src/views/pay/app/index.vue +++ b/yudao-ui-admin/src/views/pay/app/index.vue @@ -43,7 +43,6 @@ @change="handleStatusChange(scope.row)"/> -