diff --git a/common/common-framework/pom.xml b/common/common-framework/pom.xml
index 0b3edec38..1d7f7eefb 100644
--- a/common/common-framework/pom.xml
+++ b/common/common-framework/pom.xml
@@ -76,6 +76,12 @@
test
+
+
+ cn.hutool
+ hutool-all
+
+
diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
index 6fd9940ab..ca00b4b0b 100644
--- a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
+++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
@@ -30,10 +30,11 @@ public class ServiceExceptionUtil {
/**
* 错误枚举的接口
*/
- public interface Enumerable {
+ public interface Enumerable {
int getCode();
-
+ String getMessage();
+ int getGroup();
}
/**
@@ -48,6 +49,9 @@ public class ServiceExceptionUtil {
public static void put(Integer code, String message) {
ServiceExceptionUtil.messages.put(code, message);
}
+ public static void delete(Integer code, String message) {
+ ServiceExceptionUtil.messages.remove(code, message);
+ }
public static CommonResult error(Enumerable enumerable) {
return error(enumerable.getCode());
diff --git a/mall-dependencies/pom.xml b/mall-dependencies/pom.xml
index a9d251a8b..b49490bbc 100644
--- a/mall-dependencies/pom.xml
+++ b/mall-dependencies/pom.xml
@@ -38,6 +38,8 @@
1.2.56
6.0.16.Final
+ 5.2.5
+ 3.2.5.RELEASE
@@ -141,11 +143,25 @@
${fastjson.version}
+
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+
+
org.hibernate
hibernate-validator
${hibernate-validator.version}
+
+
+
+ com.github.vanroy
+ spring-boot-starter-data-jest
+ ${spring-boot-starter-data-jest.version}
+
diff --git a/order/order-biz/pom.xml b/order/order-biz/pom.xml
index 3a30bd194..08e3f4b4f 100644
--- a/order/order-biz/pom.xml
+++ b/order/order-biz/pom.xml
@@ -48,6 +48,12 @@
1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
org.mapstruct
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/OrderCommentConvert.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/OrderCommentConvert.java
deleted file mode 100644
index 8f8ddb4e7..000000000
--- a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/OrderCommentConvert.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package cn.iocoder.mall.order.biz.convert;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-/**
- *
- * 订单评论 convert
- *
- * @author wtz
- * @time 2019-05-31 18:30
- */
-@Mapper
-public interface OrderCommentConvert {
-
- OrderCommentConvert INSTANCE = Mappers.getMapper(OrderCommentConvert.class);
-
-// @Mappings({})
-// OrderCommentStateInfoPageBO.OrderCommentStateInfoItem convertOrderCommentStateInfoItem(
-// OrderCommentDO orderCommentDO);
-//
-// @Mappings({})
-// List convertOrderCommentStateInfoItems(
-// List orderCommentDOList);
-//
-// @Mappings({})
-// OrderCommentDO convertOrderCommentDO(OrderCommentCreateDTO orderCommentCreateDTO);
-//
-// @Mappings({})
-// OrderCommentCreateBO convertOrderCommentCreateBO(OrderCommentDO orderCommentDO);
-//
-// @Mappings({})
-// OrderCommentInfoBO convertOrderCommentInfoBO(OrderCommentDO orderCommentDO);
-//
-// @Mappings({})
-// OrderCommentTimeOutBO convertOrderCommentTimeOutBO(OrderCommentDO orderCommentDO);
-//
-// @Mappings({})
-// List convertOrderCommentTimeOutBOList(
-// List orderCommentDOList);
-
-
-
-}
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/comment/OrderCommentConvert.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/comment/OrderCommentConvert.java
new file mode 100644
index 000000000..57a059a10
--- /dev/null
+++ b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/convert/comment/OrderCommentConvert.java
@@ -0,0 +1,28 @@
+package cn.iocoder.mall.order.biz.convert.comment;
+
+import cn.iocoder.mall.order.biz.dataobject.comment.OrderCommentDO;
+import cn.iocoder.mall.order.biz.dto.comment.OrderCommentAddDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 订单评论转换
+ *
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/19 23:06
+ */
+@Mapper
+public interface OrderCommentConvert {
+
+ OrderCommentConvert INSTANCE = Mappers.getMapper(OrderCommentConvert.class);
+
+ /**
+ * 参数转成 DO
+ *
+ * @param orderCommentAddDTO
+ * @return
+ */
+ OrderCommentDO convert(OrderCommentAddDTO orderCommentAddDTO);
+
+}
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/OrderCommentDO.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/comment/OrderCommentDO.java
similarity index 80%
rename from order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/OrderCommentDO.java
rename to order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/comment/OrderCommentDO.java
index 916361748..c551b0b83 100644
--- a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/OrderCommentDO.java
+++ b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dataobject/comment/OrderCommentDO.java
@@ -1,25 +1,24 @@
-package cn.iocoder.mall.order.biz.dataobject;
+package cn.iocoder.mall.order.biz.dataobject.comment;
import cn.iocoder.mall.mybatis.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
/**
- * 订单评论表
- *
- * @author wtz
- * @time 2019-05-14 20:48
+ * 订单评论 MONGODB
*
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/19 22:30
*/
@Data
@Accessors(chain = true)
-@TableName(value = "order_comment")
+@Document(collection = "order_comment")
public class OrderCommentDO extends BaseDO {
- /**
- * 评论 id // TODO FROM 芋艿 TO wtz 中英文之间,要有空格
- */
+ @Id
private Integer id;
/**
@@ -103,7 +102,7 @@ public class OrderCommentDO extends BaseDO {
private Integer replayCount;
/**
- * 点赞数 // TODO FROM 芋艿 TO wtz collect 是收藏的意思,最好换个单词噢。
+ * 点赞数
*/
private Integer likeCount;
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentAddDTO.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentAddDTO.java
new file mode 100644
index 000000000..885960c5b
--- /dev/null
+++ b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentAddDTO.java
@@ -0,0 +1,63 @@
+package cn.iocoder.mall.order.biz.dto.comment;
+
+import java.io.Serializable;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 订单评论创建
+ *
+ * @author wtz
+ * @update xiaofeng
+ * @time 2019-05-15 20:42
+ * @update time 2020-05-13 0:07
+ */
+@Data
+@Accessors(chain = true)
+public class OrderCommentAddDTO implements Serializable {
+
+ @NotNull(message = "订单 id 不能为空")
+ private Integer orderId;
+
+ @NotEmpty(message = "订单编号不能为空")
+ private String orderNo;
+
+ @NotNull(message = "商品的 spu id 不能为空")
+ private Integer productSpuId;
+
+ @NotEmpty(message = "商品的 spu name 不能为空")
+ private String productSpuName;
+
+ @NotNull(message = "商品的 sku id 不能为空")
+ private Integer productSkuId;
+
+ @NotEmpty(message = "商品的 sku attrs 不能为空")
+ private String productSkuAttrs;
+
+ @NotNull(message = "商品的 sku price 不能为空")
+ private Integer productSkuPrice;
+
+ @NotEmpty(message = "商品的 sku url 不能为空")
+ private String productSkuPicUrl;
+
+ private Integer userId;
+
+ private String userAvatar;
+
+ @NotEmpty(message = "用户昵称不能为空")
+ private String userNickName;
+
+ private Integer star;
+
+ private Integer productDescriptionStar;
+
+ private Integer logisticsStar;
+
+ private Integer merchantStar;
+
+ private String commentContent;
+
+ private String commentPics;
+}
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentService.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentService.java
new file mode 100644
index 000000000..6ea648af3
--- /dev/null
+++ b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentService.java
@@ -0,0 +1,26 @@
+package cn.iocoder.mall.order.biz.service.comment;
+
+import cn.iocoder.mall.order.biz.bo.comment.OrderCommentBO;
+import cn.iocoder.mall.order.biz.dto.comment.OrderCommentAddDTO;
+import javax.validation.Valid;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 订单评论业务
+ *
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/17 15:24
+ */
+@Validated
+public interface OrderCommentService {
+
+ /**
+ * 添加订单评论
+ *
+ * @param orderCommentAddDTO
+ * @return
+ */
+ Boolean addOrderComment(@Valid OrderCommentAddDTO orderCommentAddDTO);
+
+}
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentServiceImpl.java b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentServiceImpl.java
new file mode 100644
index 000000000..d37963593
--- /dev/null
+++ b/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/service/comment/OrderCommentServiceImpl.java
@@ -0,0 +1,34 @@
+package cn.iocoder.mall.order.biz.service.comment;
+
+import cn.iocoder.mall.order.biz.convert.comment.OrderCommentConvert;
+import cn.iocoder.mall.order.biz.dataobject.comment.OrderCommentDO;
+import cn.iocoder.mall.order.biz.dto.comment.OrderCommentAddDTO;
+import javax.validation.Valid;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Service;
+
+/**
+ * OrderCommentServiceImpl
+ *
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/17 15:32
+ */
+@Service
+public class OrderCommentServiceImpl implements OrderCommentService {
+
+ private final MongoTemplate mongoTemplate;
+
+ public OrderCommentServiceImpl(final MongoTemplate mongoTemplate) {
+ this.mongoTemplate = mongoTemplate;
+ }
+
+ @Override
+ public Boolean addOrderComment(
+ @Valid OrderCommentAddDTO orderCommentAddDTO) {
+
+ OrderCommentDO orderCommentDO = mongoTemplate
+ .save(OrderCommentConvert.INSTANCE.convert(orderCommentAddDTO));
+ return null != orderCommentDO ? Boolean.TRUE : Boolean.FALSE;
+ }
+}
diff --git a/order/order-biz/src/main/resources/biz.yaml b/order/order-biz/src/main/resources/biz.yaml
index fb1c302dd..3adf8f6ea 100644
--- a/order/order-biz/src/main/resources/biz.yaml
+++ b/order/order-biz/src/main/resources/biz.yaml
@@ -6,6 +6,12 @@ spring:
username: root
password: 3WLiVUBEwTbvAfsh
+ #mongodb
+ data:
+ mongodb:
+ uri: mongodb://localhost/order-comment
+
+
# MyBatis Plus 配置项
mybatis-plus:
configuration:
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/UsersCartController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java
similarity index 99%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/UsersCartController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java
index 9b8b4e16a..3f4adc508 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/UsersCartController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.users;
+package cn.iocoder.mall.order.rest.controller.cart;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentReplyController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/OrderCommentReplyController.java
similarity index 96%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentReplyController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/OrderCommentReplyController.java
index b9787a203..f5e927865 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentReplyController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/OrderCommentReplyController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.users;
+package cn.iocoder.mall.order.rest.controller.comment;
import cn.iocoder.common.framework.constant.MallConstants;
import io.swagger.annotations.Api;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/UsersOrderCommentController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/UsersOrderCommentController.java
new file mode 100644
index 000000000..2d61e1d90
--- /dev/null
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/comment/UsersOrderCommentController.java
@@ -0,0 +1,48 @@
+package cn.iocoder.mall.order.rest.controller.comment;
+
+import cn.iocoder.common.framework.constant.MallConstants;
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.order.biz.service.comment.OrderCommentService;
+import cn.iocoder.mall.order.rest.convert.comment.UsersOrderCommentConvert;
+import cn.iocoder.mall.order.rest.request.comment.UsersOrderCommentAddRequest;
+import cn.iocoder.mall.security.core.context.UserSecurityContextHolder;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+/**
+ * UsersOrderCommentController
+ *
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/12 22:56
+ */
+@RestController
+@RequestMapping(MallConstants.ROOT_PATH_USER + "/order_comment")
+@Api("订单商品评论模块")
+public class UsersOrderCommentController {
+
+ private final OrderCommentService orderCommentService;
+
+ public UsersOrderCommentController(
+ OrderCommentService orderCommentService) {
+ this.orderCommentService = orderCommentService;
+ }
+
+ @PostMapping("/add")
+ @ApiOperation(value = "添加订单评论")
+ public CommonResult add(
+ @RequestBody @Validated UsersOrderCommentAddRequest request) {
+ Integer userId = UserSecurityContextHolder.getContext().getUserId();
+ request.setUserId(userId);
+
+ return CommonResult.success(orderCommentService.addOrderComment(
+ UsersOrderCommentConvert.INSTANCE.convert(request)));
+ }
+
+
+}
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminOrderReturnController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminOrderReturnController.java
similarity index 96%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminOrderReturnController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminOrderReturnController.java
index e0a2e3ba6..029d3a00f 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminOrderReturnController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminOrderReturnController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.admins;
+package cn.iocoder.mall.order.rest.controller.order;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminsOrderController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminsOrderController.java
similarity index 98%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminsOrderController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminsOrderController.java
index fa2eb03d6..2d919f2d4 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/admins/AdminsOrderController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/AdminsOrderController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.admins;
+package cn.iocoder.mall.order.rest.controller.order;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderController.java
similarity index 98%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderController.java
index ab0d08c95..925d8592b 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.users;
+package cn.iocoder.mall.order.rest.controller.order;
import io.swagger.annotations.Api;
@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("users/order")
@Api(description = "用户订单") // TODO FROM 芋艿 to 小范,description 已经废弃啦
-public class OrderController {
+public class UsersOrderController {
// @Reference(validation = "true", version = "${dubbo.provider.OrderReturnService.version}")
// private OrderService orderService;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderLogisticsController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderLogisticsController.java
similarity index 96%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderLogisticsController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderLogisticsController.java
index 43bfd8bfd..4eaa37156 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderLogisticsController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderLogisticsController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.users;
+package cn.iocoder.mall.order.rest.controller.order;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("users/order_logistics")
@Api(description = "订单物流信息")
-public class OrderLogisticsController {
+public class UsersOrderLogisticsController {
// @Reference(validation = "true", version = "${dubbo.provider.OrderLogisticsService.version}")
// private OrderLogisticsService orderLogisticsService;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderReturnController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderReturnController.java
similarity index 95%
rename from order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderReturnController.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderReturnController.java
index d9ea9dfdd..ab9a1e7db 100644
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderReturnController.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/order/UsersOrderReturnController.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.order.rest.controller.users;
+package cn.iocoder.mall.order.rest.controller.order;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("users/order_return")
-public class OrderReturnController {
+public class UsersOrderReturnController {
// @Reference(validation = "true", version = "${dubbo.provider.OrderReturnService.version}")
// private OrderReturnService orderReturnService;
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentController.java
deleted file mode 100644
index d13a233e7..000000000
--- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/users/OrderCommentController.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package cn.iocoder.mall.order.rest.controller.users;
-
-import cn.iocoder.common.framework.constant.MallConstants;
-import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- *
- * 订单评论 Api(user)
- *
- * @author wtz
- * @time 2019-05-27 20:46
- */
-@RestController
-@RequestMapping(MallConstants.ROOT_PATH_USER + "/order_comment")
-@Api("用户评论模块")
-public class OrderCommentController {
-
-// @Reference(validation = "true", version = "${dubbo.provider.OrderCommentService.version}")
-// private OrderCommentService orderCommentService;
-//
-// @Reference(validation = "true", version = "${dubbo.provider.OrderCommentReplyService.version}")
-// private OrderCommentReplyService orderCommentReplyService;
-//
-//
-// @PostMapping("create_order_comment")
-// //@RequiresLogin
-// @ApiOperation(value = "创建订单评论")
-// public CommonResult createOrderComment(@RequestBody @Validated OrderCommentCreateDTO orderCommentCreateDTO) {
-// Integer userId = UserSecurityContextHolder.getContext().getUserId();
-// orderCommentCreateDTO.setUserId(userId);
-// return success(orderCommentService.createOrderComment(orderCommentCreateDTO));
-// }
-//
-// @GetMapping("order_comment_page")
-// @ApiOperation(value = "获取评论分页")
-// public CommonResult getOrderCommentPage(@Validated OrderCommentPageDTO orderCommentPageDTO){
-// return success(orderCommentService.getOrderCommentPage(orderCommentPageDTO));
-// }
-//
-// @GetMapping("order_comment_info_merchant_reply")
-// @ApiOperation(value = "获取评论和商家回复")
-// public CommonResult geOrderCommentInfoAndMerchantReply(@RequestParam("commentId") Integer commentId){
-// OrderCommentInfoAndMerchantReplyBO orderCommentInfoAndMerchantReplyBO=new OrderCommentInfoAndMerchantReplyBO();
-// orderCommentInfoAndMerchantReplyBO.setOrderCommentInfoBO(orderCommentService.getOrderCommentInfo(commentId));
-// orderCommentInfoAndMerchantReplyBO.setOrderCommentMerchantReplyBOS(orderCommentReplyService.getOrderCommentMerchantReply(commentId));
-// return success(orderCommentInfoAndMerchantReplyBO);
-// }
-//
-// @GetMapping
-// //@RequiresLogin
-// @ApiOperation(value = "获取订单评论状态分页")
-// public CommonResult getOrderCommentStateInfoPage(@Validated OrderCommentStateInfoPageDTO orderCommentStateInfoPageDTO){
-// //Integer userId = UserSecurityContextHolder.getContext().getUserId();
-// //orderCommentStateInfoPageDTO.setUserId(userId);
-// return success(orderCommentService.getOrderCommentStateInfoPage(orderCommentStateInfoPageDTO));
-// }
-
-
-}
diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/convert/comment/UsersOrderCommentConvert.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/convert/comment/UsersOrderCommentConvert.java
new file mode 100644
index 000000000..00d86ec7b
--- /dev/null
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/convert/comment/UsersOrderCommentConvert.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.order.rest.convert.comment;
+
+import cn.iocoder.mall.order.biz.dto.comment.OrderCommentAddDTO;
+import cn.iocoder.mall.order.rest.request.comment.UsersOrderCommentAddRequest;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * UsersOrderCommentConvert
+ *
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/13 0:15
+ */
+@Mapper
+public interface UsersOrderCommentConvert {
+
+ UsersOrderCommentConvert INSTANCE = Mappers.getMapper(UsersOrderCommentConvert.class);
+
+
+ /**
+ * 保存订单评论参数转换
+ *
+ * @param request
+ * @return
+ */
+ OrderCommentAddDTO convert(UsersOrderCommentAddRequest request);
+
+}
diff --git a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentCreateDTO.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/request/comment/UsersOrderCommentAddRequest.java
similarity index 85%
rename from order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentCreateDTO.java
rename to order/order-rest/src/main/java/cn/iocoder/mall/order/rest/request/comment/UsersOrderCommentAddRequest.java
index 5c788825c..4bd07063c 100644
--- a/order/order-biz/src/main/java/cn/iocoder/mall/order/biz/dto/comment/OrderCommentCreateDTO.java
+++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/request/comment/UsersOrderCommentAddRequest.java
@@ -1,26 +1,23 @@
-package cn.iocoder.mall.order.biz.dto.comment;
+package cn.iocoder.mall.order.rest.request.comment;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-
/**
- * 订单评论创建
- *
- * @author wtz
- * @time 2019-05-15 20:42
+ * 添加订单评论
*
+ * @author xiaofeng
+ * @version 1.0
+ * @date 2020/05/12 23:02
*/
-@ApiModel("订单创建 DTO")
+@ApiModel("用户 - Order 模块 - 添加订单评论")
@Data
@Accessors(chain = true)
-public class OrderCommentCreateDTO implements Serializable {
-
+public class UsersOrderCommentAddRequest {
@ApiModelProperty(value = "订单 id", required = true)
@NotNull(message = "订单 id 不能为空")
@@ -64,21 +61,22 @@ public class OrderCommentCreateDTO implements Serializable {
@NotEmpty(message = "用户昵称不能为空")
private String userNickName;
- @ApiModelProperty(value = "评价星级", required = true,example = "1-5")
+ @ApiModelProperty(value = "评价星级", required = true, example = "1-5")
private Integer star;
- @ApiModelProperty(value = "商品描述星级", required = true,example = "1-5")
+ @ApiModelProperty(value = "商品描述星级", required = true, example = "1-5")
private Integer productDescriptionStar;
- @ApiModelProperty(value = "物流评价星级", required = true,example = "1-5")
+ @ApiModelProperty(value = "物流评价星级", required = true, example = "1-5")
private Integer logisticsStar;
- @ApiModelProperty(value = "商家评价星级", required = true,example = "1-5")
+ @ApiModelProperty(value = "商家评价星级", required = true, example = "1-5")
private Integer merchantStar;
- @ApiModelProperty(value = "商家评价内容", required = true,example = "1-5")
+ @ApiModelProperty(value = "商家评价内容", required = true, example = "1-5")
private String commentContent;
@ApiModelProperty(value = "评价图片", required = true)
private String commentPics;
+
}
diff --git a/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/ProductErrorCodeEnum.java b/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/ProductErrorCodeEnum.java
index f2e7c10ae..3543d2d34 100644
--- a/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/ProductErrorCodeEnum.java
+++ b/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/ProductErrorCodeEnum.java
@@ -51,6 +51,11 @@ public enum ProductErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
return message;
}
+ @Override
+ public int getGroup() {
+ return 0;
+ }
+
@Override
public int getCode() {
return code;
diff --git a/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryConstants.java b/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryConstants.java
deleted file mode 100644
index 4039f3cdf..000000000
--- a/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryConstants.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.iocoder.mall.product.biz.enums.category;
-
-public interface ProductCategoryConstants {
-
- /**
- * 状态 - 开启
- */
- Integer STATUS_ENABLE = 1;
- /**
- * 状态 - 关闭
- */
- Integer STATUS_DISABLE = 2;
-
- /**
- * 父分类编号 - 根节点
- */
- Integer PID_ROOT = 0;
-
-}
\ No newline at end of file
diff --git a/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryNodeEnum.java b/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryNodeEnum.java
new file mode 100644
index 000000000..9f32d1df7
--- /dev/null
+++ b/product/product-biz-api/src/main/java/cn/iocoder/mall/product/biz/enums/category/ProductCategoryNodeEnum.java
@@ -0,0 +1,28 @@
+package cn.iocoder.mall.product.biz.enums.category;
+
+import cn.iocoder.common.framework.core.IntArrayValuable;
+
+import java.util.Arrays;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/12
+ * @Description: 商品分类节点枚举
+ */
+public enum ProductCategoryNodeEnum{
+
+ /**
+ * 根节点
+ */
+ ROOT(0);
+
+ private final Integer id;
+
+ ProductCategoryNodeEnum(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java
deleted file mode 100644
index 75e9e17c7..000000000
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package cn.iocoder.mall.product.biz.bo.product;
-
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 商品分类 BO
- */
-@Data
-@Accessors(chain = true)
-@Deprecated // TODO jiangweifan 后面确认无使用后删除
-public class ProductCategoryBO implements Serializable {
-
- /**
- * 分类编号
- */
- private Integer id;
- /**
- * 父分类编号
- *
- * 如果不存在父级,则 pid = 0 。
- */
- private Integer pid;
- /**
- * 名称
- */
- private String name;
- /**
- * 描述
- */
- private String description;
- /**
- * 分类图片
- */
- private String picUrl;
- /**
- * 排序值
- */
- private Integer sort;
- /**
- * 状态
- *
- * 1-开启
- * 2-关闭
- */
- private Integer status;
- /**
- * 创建时间
- */
- private Date createTime;
-
-}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/sku/ProductSpuConvert.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/sku/ProductSpuConvert.java
index 624980de3..2c898bdeb 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/sku/ProductSpuConvert.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/sku/ProductSpuConvert.java
@@ -40,15 +40,9 @@ public interface ProductSpuConvert {
})
ProductSpuBO convert(ProductSpuDO spu);
- @Named("translatePicUrlsFromString")
- default List translatePicUrlsFromString(String picUrls) {
- return StringUtil.split(picUrls, ",");
- }
-
@Mappings({})
List convert(List spus);
-
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
})
@@ -131,4 +125,9 @@ public interface ProductSpuConvert {
return spuDetailList;
}
+ @Named("translatePicUrlsFromString")
+ default List translatePicUrlsFromString(String picUrls) {
+ return StringUtil.split(picUrls, ",");
+ }
+
}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/category/ProductCategoryMapper.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/category/ProductCategoryMapper.java
index 792a19e81..1dd557202 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/category/ProductCategoryMapper.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/category/ProductCategoryMapper.java
@@ -2,6 +2,7 @@ package cn.iocoder.mall.product.biz.dao.category;
import cn.iocoder.mall.product.biz.dataobject.category.ProductCategoryDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Repository;
/**
@@ -11,5 +12,14 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public interface ProductCategoryMapper extends BaseMapper {
-
+ /**
+ * 查询商品分类的下一级子分类数量
+ * @param productCategoryId
+ * @return
+ */
+ default Integer selectChildCategoryCount(Integer productCategoryId) {
+ return this.selectCount(
+ Wrappers.lambdaQuery().eq(ProductCategoryDO::getPid, productCategoryId)
+ );
+ }
}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/sku/ProductSpuAddDTO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/sku/ProductSpuAddDTO.java
index d4e0455d1..7543dcf6b 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/sku/ProductSpuAddDTO.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/sku/ProductSpuAddDTO.java
@@ -12,6 +12,7 @@ import java.util.List;
*/
@Data
@Accessors(chain = true)
+// TODO FROM 芋艿 to sunderui && q2118cs:貌似重复了,只要保留一个哈
public class ProductSpuAddDTO {
// ========== 基本信息 =========
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/category/ProductCategoryServiceImpl.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/category/ProductCategoryServiceImpl.java
index c540ab8fb..2a43d3abc 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/category/ProductCategoryServiceImpl.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/category/ProductCategoryServiceImpl.java
@@ -11,9 +11,8 @@ import cn.iocoder.mall.product.biz.dto.category.ProductCategoryDeleteDTO;
import cn.iocoder.mall.product.biz.dto.category.ProductCategoryUpdateDTO;
import cn.iocoder.mall.product.biz.dto.category.ProductCategoryUpdateStatusDTO;
import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
-import cn.iocoder.mall.product.biz.enums.category.ProductCategoryConstants;
+import cn.iocoder.mall.product.biz.enums.category.ProductCategoryNodeEnum;
import cn.iocoder.mall.product.biz.enums.category.ProductCategoryStatusEnum;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -68,7 +67,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_NOT_SELF);
}
// 校验父分类是否存在
- if (!ProductCategoryConstants.PID_ROOT.equals(productCategoryUpdateDTO.getPid())
+ if (!ProductCategoryNodeEnum.ROOT.getId().equals(productCategoryUpdateDTO.getPid())
&& productCategoryMapper.selectById(productCategoryUpdateDTO.getPid()) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS);
}
@@ -114,9 +113,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_DELETE_ONLY_DISABLE);
}
// 只有不存在子分类才可以删除
- Integer childCount = productCategoryMapper.selectCount(
- Wrappers.lambdaQuery().eq(ProductCategoryDO::getPid, productCategoryId)
- );
+ // TODO FROM 芋艿 to jiangweifan:Wrappers 只用在 Mapper 层 [DONE]
+ Integer childCount = productCategoryMapper.selectChildCategoryCount(productCategoryId);
if (childCount > 0) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_DELETE_ONLY_NO_CHILD);
}
@@ -128,14 +126,14 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
}
private void validParent(Integer pid) {
- if (!ProductCategoryConstants.PID_ROOT.equals(pid)) {
+ if (!ProductCategoryNodeEnum.ROOT.getId().equals(pid)) {
ProductCategoryDO parentCategory = productCategoryMapper.selectById(pid);
// 校验父分类是否存在
if (parentCategory == null) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS);
}
// 父分类必须是一级分类
- if (!ProductCategoryConstants.PID_ROOT.equals(parentCategory.getPid())) {
+ if (!ProductCategoryNodeEnum.ROOT.getId().equals(parentCategory.getPid())) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2);
}
}
@@ -149,7 +147,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode());
}
// 只有禁用的商品分类才可以删除
- if (ProductCategoryConstants.STATUS_DISABLE.equals(productCategory.getStatus())) {
+ if (ProductCategoryStatusEnum.DISABLED.getStatus().equals(productCategory.getStatus())) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_MUST_ENABLE.getCode());
}
// 返回结果
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/spu/ProductSpuServiceImpl.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/spu/ProductSpuServiceImpl.java
index a03d39452..5f3a6f601 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/spu/ProductSpuServiceImpl.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/spu/ProductSpuServiceImpl.java
@@ -15,7 +15,7 @@ import cn.iocoder.mall.product.biz.dataobject.spu.ProductSpuDO;
import cn.iocoder.mall.product.biz.dto.sku.ProductSkuAddOrUpdateDTO;
import cn.iocoder.mall.product.biz.dto.sku.ProductSpuAddDTO;
import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
-import cn.iocoder.mall.product.biz.enums.category.ProductCategoryConstants;
+import cn.iocoder.mall.product.biz.enums.category.ProductCategoryNodeEnum;
import cn.iocoder.mall.product.biz.enums.spu.ProductSpuConstants;
import cn.iocoder.mall.product.biz.service.attr.ProductAttrService;
import cn.iocoder.mall.product.biz.service.category.ProductCategoryService;
@@ -76,7 +76,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
public ProductSpuDetailBO addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
// 校验商品分类分类存在
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuAddDTO.getCid());
- if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) {
+ if (ProductCategoryNodeEnum.ROOT.getId().equals(category.getPid())) {
// 商品只能添加到二级分类下
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/category/AdminsProductCategoryController.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/category/AdminsProductCategoryController.java
index daf7b64d9..77cb69d27 100644
--- a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/category/AdminsProductCategoryController.java
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/category/AdminsProductCategoryController.java
@@ -7,7 +7,7 @@ import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
import cn.iocoder.mall.product.biz.dto.category.ProductCategoryDeleteDTO;
import cn.iocoder.mall.product.biz.dto.category.ProductCategoryUpdateDTO;
import cn.iocoder.mall.product.biz.dto.category.ProductCategoryUpdateStatusDTO;
-import cn.iocoder.mall.product.biz.enums.category.ProductCategoryConstants;
+import cn.iocoder.mall.product.biz.enums.category.ProductCategoryNodeEnum;
import cn.iocoder.mall.product.biz.service.category.ProductCategoryService;
import cn.iocoder.mall.product.rest.convert.category.AdminsProductCategoryConvert;
import cn.iocoder.mall.product.rest.request.category.AdminsProductCategoryAddRequest;
@@ -49,7 +49,7 @@ public class AdminsProductCategoryController {
Map treeNodeMap = productCategories.stream().collect(Collectors.toMap(ProductCategoryBO::getId, AdminsProductCategoryConvert.INSTANCE::convertToTreeNodeResponse));
// 处理父子关系
treeNodeMap.values().stream()
- .filter(node -> !node.getPid().equals(ProductCategoryConstants.PID_ROOT))
+ .filter(node -> !node.getPid().equals(ProductCategoryNodeEnum.ROOT.getId()))
.forEach((childNode) -> {
// 获得父节点
AdminsProductCategoryTreeNodeResponse parentNode = treeNodeMap.get(childNode.getPid());
@@ -61,7 +61,7 @@ public class AdminsProductCategoryController {
});
// 获得到所有的根节点
List rootNodes = treeNodeMap.values().stream()
- .filter(node -> node.getPid().equals(ProductCategoryConstants.PID_ROOT))
+ .filter(node -> node.getPid().equals(ProductCategoryNodeEnum.ROOT.getId()))
.sorted(Comparator.comparing(AdminsProductCategoryTreeNodeResponse::getSort))
.collect(Collectors.toList());
return success(rootNodes);
diff --git a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/bo/banner/BannerListBO.java b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/bo/banner/BannerListBO.java
index 7cf13983b..935f5897d 100644
--- a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/bo/banner/BannerListBO.java
+++ b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/bo/banner/BannerListBO.java
@@ -15,6 +15,7 @@ import java.util.Date;
*/
@Data
@Accessors(chain = true)
+// TODO FROM 芋艿 to 小范:捉摸是不是先统一的 BannerBO;另外,biz 不使用 swagger 注解哈,其他 banner 的 dto 和 bo 也一起改改哈;
public class BannerListBO implements Serializable {
diff --git a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/dao/BannerMapper.java b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/dao/BannerMapper.java
index 39cdfb5d0..5d3d46ca3 100644
--- a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/dao/BannerMapper.java
+++ b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/dao/BannerMapper.java
@@ -26,6 +26,7 @@ public interface BannerMapper extends BaseMapper {
* @param dto
* @return
*/
+ // TODO FROM 芋艿 to 小范:Page 方法哈
default IPage selectBannerList(BannerListDTO dto) {
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isEmpty(dto.getStatus())) {
@@ -41,4 +42,4 @@ public interface BannerMapper extends BaseMapper {
return result;
}
-}
\ No newline at end of file
+}
diff --git a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/service/banner/BannerService.java b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/service/banner/BannerService.java
index aea1db0d2..c526c9339 100644
--- a/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/service/banner/BannerService.java
+++ b/promotion/promotion-biz/src/main/java/cn/iocoder/mall/promotion/biz/service/banner/BannerService.java
@@ -48,6 +48,7 @@ public interface BannerService {
*/
void updateBanner(BannerUpdateDTO adminsBannerUpdateDTO);
+ // TODO FROM 芋艿 to 小范:貌似要把 dto 搞起来,嘿嘿;
/**
* 更新 - banner 状态
*
diff --git a/promotion/promotion-rest/src/main/java/cn/iocoder/mall/promotion/rest/request/banner/BannerAddRequest.java b/promotion/promotion-rest/src/main/java/cn/iocoder/mall/promotion/rest/request/banner/BannerAddRequest.java
index 654f363a5..ffb49b443 100644
--- a/promotion/promotion-rest/src/main/java/cn/iocoder/mall/promotion/rest/request/banner/BannerAddRequest.java
+++ b/promotion/promotion-rest/src/main/java/cn/iocoder/mall/promotion/rest/request/banner/BannerAddRequest.java
@@ -17,7 +17,7 @@ import java.io.Serializable;
@Accessors(chain = true)
public class BannerAddRequest implements Serializable {
- @NotNull
+ @NotNull // TODO FROM 芋艿 to 小范:提示要加下,哈哈哈
@ApiModelProperty("跳转链接")
private Integer url;
diff --git a/search/pom.xml b/search/pom.xml
index 865c280c6..410ab0701 100644
--- a/search/pom.xml
+++ b/search/pom.xml
@@ -13,8 +13,13 @@
pom
search-application
- search-service-api
- search-service-impl
+ search-biz
+ search-biz-api
+
+
+ search-rpc
+ search-rest
+ search-rpc-api
diff --git a/search/search-application/pom.xml b/search/search-application/pom.xml
index 1f0fbc325..0e839c136 100644
--- a/search/search-application/pom.xml
+++ b/search/search-application/pom.xml
@@ -15,92 +15,15 @@
cn.iocoder.mall
- common-framework
+ search-rest
1.0-SNAPSHOT
cn.iocoder.mall
- mall-spring-boot
+ search-rpc
1.0-SNAPSHOT
-
- cn.iocoder.mall
- user-sdk
- 1.0-SNAPSHOT
-
-
- cn.iocoder.mall
- search-service-api
- 1.0-SNAPSHOT
-
-
- cn.iocoder.mall
- search-service-impl
- 1.0-SNAPSHOT
-
-
- cn.iocoder.mall
- system-service-api
- 1.0-SNAPSHOT
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- io.springfox
- springfox-swagger2
-
-
- com.github.xiaoymin
- swagger-bootstrap-ui
-
-
-
-
- com.alibaba.cloud
- spring-cloud-starter-alibaba-sentinel
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
-
- io.micrometer
- micrometer-registry-prometheus
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
diff --git a/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java b/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java
index 228823e29..1f1257971 100644
--- a/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java
+++ b/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java
@@ -2,13 +2,22 @@ package cn.iocoder.mall.search.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.search"})
@EnableAsync(proxyTargetClass = true)
public class SearchApplication {
-
+ /**
+ * 设置需要读取的配置文件的名字。
+ * 基于 {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY} 实现。
+ */
+ private static final String CONFIG_NAME_VALUE = "biz,rest,rpc,application";
public static void main(String[] args) {
+
+ // 设置环境变量
+ System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE);
+
// 解决 ES java.lang.IllegalStateException: availableProcessors is already
System.setProperty("es.set.netty.runtime.available.processors", "false");
SpringApplication.run(SearchApplication.class, args);
diff --git a/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java b/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java
deleted file mode 100644
index 508356672..000000000
--- a/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cn.iocoder.mall.search.application.controller.users;
-
-import cn.iocoder.common.framework.util.StringUtil;
-import cn.iocoder.common.framework.vo.CommonResult;
-import cn.iocoder.common.framework.vo.SortingField;
-import cn.iocoder.mall.search.api.ProductSearchService;
-import cn.iocoder.mall.search.api.bo.ProductConditionBO;
-import cn.iocoder.mall.search.api.bo.ProductPageBO;
-import cn.iocoder.mall.search.api.dto.ProductConditionDTO;
-import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
-import org.apache.dubbo.config.annotation.Reference;
-import io.swagger.annotations.Api;
-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.util.Collections;
-
-import static cn.iocoder.common.framework.vo.CommonResult.success;
-
-// TODO 芋艿,搜索关键字的配置
-// TODO 芋艿,搜索日志
-
-@RestController
-@RequestMapping("users/product")
-@Api("商品搜索")
-public class UsersProductSearchController {
-
- @Reference(validation = "true", version = "${dubbo.provider.ProductSearchService.version}")
- private ProductSearchService productSearchService;
-
- @GetMapping("/page") // TODO 芋艿,后面把 BO 改成 VO
- public CommonResult page(@RequestParam(value = "cid", required = false) Integer cid,
- @RequestParam(value = "keyword", required = false) String keyword,
- @RequestParam(value = "pageNo", required = false) Integer pageNo,
- @RequestParam(value = "pageSize", required = false) Integer pageSize,
- @RequestParam(value = "sortField", required = false) String sortField,
- @RequestParam(value = "sortOrder", required = false) String sortOrder) {
- // 创建 ProductSearchPageDTO 对象
- ProductSearchPageDTO productSearchPageDTO = new ProductSearchPageDTO().setCid(cid).setKeyword(keyword)
- .setPageNo(pageNo).setPageSize(pageSize);
- if (StringUtil.hasText(sortField) && StringUtil.hasText(sortOrder)) {
- productSearchPageDTO.setSorts(Collections.singletonList(new SortingField(sortField, sortOrder)));
- }
- // 执行搜索
- return success(productSearchService.getSearchPage(productSearchPageDTO));
- }
-
- @GetMapping("/condition") // TODO 芋艿,后面把 BO 改成 VO
- public CommonResult condition(@RequestParam(value = "keyword", required = false) String keyword) {
- // 创建 ProductConditionDTO 对象
- ProductConditionDTO productConditionDTO = new ProductConditionDTO().setKeyword(keyword)
- .setFields(Collections.singleton(ProductConditionDTO.FIELD_CATEGORY));
- // 执行搜索
- return success(productSearchService.getSearchCondition(productConditionDTO));
- }
-
-}
diff --git a/search/search-application/src/main/resources/application.yaml b/search/search-application/src/main/resources/application.yaml
index c531b15d9..4ddc8d284 100644
--- a/search/search-application/src/main/resources/application.yaml
+++ b/search/search-application/src/main/resources/application.yaml
@@ -1,29 +1,6 @@
spring:
application:
name: search-application
-
- # Spring Cloud 配置项
- cloud:
- # Spring Cloud Sentinel 配置项
- sentinel:
- transport:
- dashboard: s1.iocoder.cn:12088 # Sentinel Dashboard 服务地址
- eager: true # 项目启动时,直接连接到 Sentinel
-
-# server
-server:
- port: 18086
- servlet:
- context-path: /search-api/
-
-swagger:
- enable: false
-
-
-management:
- endpoints:
- web:
- exposure:
- include: health,info,env,metrics,prometheus
- metrics:
- enabled: true
+ # Profile 的配置项
+ profiles:
+ active: local
diff --git a/search/search-biz-api/pom.xml b/search/search-biz-api/pom.xml
new file mode 100644
index 000000000..b8d93c0db
--- /dev/null
+++ b/search/search-biz-api/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ search
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ search-biz-api
+
+
+
+
+ cn.iocoder.mall
+ common-framework
+ 1.0-SNAPSHOT
+
+
+
+
diff --git a/search/search-biz/pom.xml b/search/search-biz/pom.xml
new file mode 100644
index 000000000..7a6c27c57
--- /dev/null
+++ b/search/search-biz/pom.xml
@@ -0,0 +1,110 @@
+
+
+
+ search
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ search-biz
+
+
+
+
+ cn.iocoder.mall
+ mall-spring-boot
+ 1.0-SNAPSHOT
+
+
+
+ search-biz-api
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+
+
+ cn.iocoder.mall
+ product-rpc-api
+ 1.0-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-elasticsearch
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-dubbo
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-stream-rocketmq
+
+
+
+
+ com.google.guava
+ guava
+
+
+
+ org.mapstruct
+ mapstruct
+
+
+ org.mapstruct
+ mapstruct-jdk8
+
+
+ org.projectlombok
+ lombok
+
+
+
+ com.alibaba
+ fastjson
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ com.github.vanroy
+ spring-boot-starter-data-jest
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+
+
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductBO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductBO.java
new file mode 100644
index 000000000..7ba301041
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductBO.java
@@ -0,0 +1,86 @@
+package cn.iocoder.mall.search.biz.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 商品 ES BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductBO implements Serializable {
+
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ private String name;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+ /**
+ * 描述
+ */
+ private String description;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 分类名
+ */
+ private String categoryName;
+ /**
+ * 商品主图地数组
+ */
+ private List picUrls;
+
+ // ========== 其他信息 =========
+ /**
+ * 是否上架商品(是否可见)。
+ *
+ * true 为已上架
+ * false 为已下架
+ */
+ private Boolean visible;
+ /**
+ * 排序字段
+ */
+ private Integer sort;
+
+ // ========== Sku 相关字段 =========
+ /**
+ * 原价格,单位:分
+ */
+ private Integer originalPrice;
+ /**
+ * 购买价格,单位:分。
+ */
+ private Integer buyPrice;
+ /**
+ * 库存数量
+ */
+ private Integer quantity;
+
+ // ========== 促销活动相关字段 =========
+ // 目前只促销单体商品促销,目前仅限制折扣。
+ /**
+ * 促销活动编号
+ */
+ private Integer promotionActivityId;
+ /**
+ * 促销活动标题
+ */
+ private String promotionActivityTitle;
+ /**
+ * 促销活动类型
+ */
+ private Integer promotionActivityType;
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductConditionBO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductConditionBO.java
new file mode 100644
index 000000000..b8eebbfe6
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductConditionBO.java
@@ -0,0 +1,35 @@
+package cn.iocoder.mall.search.biz.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 商品搜索条件返回 BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductConditionBO {
+
+ /**
+ * 商品分类数组
+ */
+ private List categories;
+
+ @Data
+ @Accessors(chain = true)
+ public static class Category {
+
+ /**
+ * 分类编号
+ */
+ private Integer id;
+ /**
+ * 分类名称
+ */
+ private String name;
+
+ }
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductPageBO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductPageBO.java
new file mode 100644
index 000000000..827b7996f
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/bo/ProductPageBO.java
@@ -0,0 +1,22 @@
+package cn.iocoder.mall.search.biz.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+public class ProductPageBO implements Serializable {
+
+ /**
+ * 管理员数组
+ */
+ private List list;
+ /**
+ * 总量
+ */
+ private Integer total;
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/config/JPAConfiguration.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/config/JPAConfiguration.java
new file mode 100644
index 000000000..acb35fd21
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/config/JPAConfiguration.java
@@ -0,0 +1,9 @@
+package cn.iocoder.mall.search.biz.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
+
+@Configuration
+@EnableElasticsearchRepositories(basePackages = "cn.iocoder.mall.search.biz.dao")
+public class JPAConfiguration {
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/constant/FieldAnalyzer.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/constant/FieldAnalyzer.java
new file mode 100644
index 000000000..5b5315769
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/constant/FieldAnalyzer.java
@@ -0,0 +1,26 @@
+package cn.iocoder.mall.search.biz.constant;
+
+/**
+ * ES 字段分析器的枚举类
+ *
+ * 关于 IK 分词,文章 https://blog.csdn.net/xsdxs/article/details/72853288 不错。
+ * 目前项目使用的 ES 版本是 6.7.1 ,可以在 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-7-1 下载。
+ * 如果不知道怎么安装 ES ,可以看 https://blog.csdn.net/chengyuqiang/article/details/78837712 简单。
+ */
+public class FieldAnalyzer {
+
+ /**
+ * IK 最大化分词
+ *
+ * 会将文本做最细粒度的拆分
+ */
+ public static final String IK_MAX_WORD = "ik_max_word";
+
+ /**
+ * IK 智能分词
+ *
+ * 会做最粗粒度的拆分
+ */
+ public static final String IK_SMART = "ik_smart";
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
new file mode 100644
index 000000000..9227f3615
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
@@ -0,0 +1,17 @@
+package cn.iocoder.mall.search.biz.convert;
+
+import cn.iocoder.mall.search.biz.bo.ProductBO;
+import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface ProductSearchConvert {
+
+ ProductSearchConvert INSTANCE = Mappers.getMapper(ProductSearchConvert.class);
+
+ List convert(List list);
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dao/ProductRepository.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dao/ProductRepository.java
new file mode 100644
index 000000000..1b4b869d0
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dao/ProductRepository.java
@@ -0,0 +1,69 @@
+package cn.iocoder.mall.search.biz.dao;
+
+import cn.iocoder.common.framework.util.CollectionUtil;
+import cn.iocoder.common.framework.util.StringUtil;
+import cn.iocoder.common.framework.vo.SortingField;
+import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
+import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
+import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
+import org.elasticsearch.search.sort.SortBuilders;
+import org.elasticsearch.search.sort.SortOrder;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+
+@Repository
+public interface ProductRepository extends ElasticsearchRepository {
+
+ @Deprecated
+ ESProductDO findByName(String name);
+
+ default Page search(Integer cid, String keyword, Integer pageNo, Integer pageSize,
+ List sortFields) {
+ NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder()
+ .withPageable(PageRequest.of(pageNo - 1, pageSize));
+ // 筛选条件 cid
+ if (cid != null) {
+ nativeSearchQueryBuilder.withFilter(QueryBuilders.termQuery("cid", cid));
+ }
+ // 筛选
+ if (StringUtil.hasText(keyword)) {
+ FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = { // TODO 芋艿,分值随便打的
+ new FunctionScoreQueryBuilder.FilterFunctionBuilder(matchQuery("name", keyword),
+ ScoreFunctionBuilders.weightFactorFunction(10)),
+ new FunctionScoreQueryBuilder.FilterFunctionBuilder(matchQuery("sellPoint", keyword),
+ ScoreFunctionBuilders.weightFactorFunction(2)),
+ new FunctionScoreQueryBuilder.FilterFunctionBuilder(matchQuery("categoryName", keyword),
+ ScoreFunctionBuilders.weightFactorFunction(3)),
+// new FunctionScoreQueryBuilder.FilterFunctionBuilder(matchQuery("description", keyword),
+// ScoreFunctionBuilders.weightFactorFunction(2)), // TODO 芋艿,目前这么做,如果商品描述很长,在按照价格降序,会命中超级多的关键字。
+ };
+ FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(functions)
+ .scoreMode(FunctionScoreQuery.ScoreMode.SUM)
+ .setMinScore(2F); // TODO 芋艿,需要考虑下 score
+ nativeSearchQueryBuilder.withQuery(functionScoreQueryBuilder);
+ } else {
+ nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
+ }
+ // 排序
+ if (!CollectionUtil.isEmpty(sortFields)) {
+ sortFields.forEach(sortField -> nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField.getField())
+ .order(SortOrder.fromString(sortField.getOrder()))));
+ } else if (StringUtil.hasText(keyword)) {
+ nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
+ } else {
+ nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("sort").order(SortOrder.DESC));
+ }
+ // 执行查询
+ return search(nativeSearchQueryBuilder.build());
+ }
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dataobject/ESProductDO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dataobject/ESProductDO.java
new file mode 100644
index 000000000..bd06b0abf
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dataobject/ESProductDO.java
@@ -0,0 +1,96 @@
+package cn.iocoder.mall.search.biz.dataobject;
+
+import cn.iocoder.mall.search.biz.constant.FieldAnalyzer;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
+
+import java.util.List;
+
+/**
+ * 商品 ES DO
+ */
+@Document(indexName = "product", type = "spu", shards = 1, replicas = 0)
+@Data
+@Accessors(chain = true)
+public class ESProductDO {
+
+ @Id
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ @Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
+ private String name;
+ /**
+ * 卖点
+ */
+ @Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
+ private String sellPoint;
+ /**
+ * 描述
+ */
+ @Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
+ private String description;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 分类名
+ */
+ @Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
+ private String categoryName;
+ /**
+ * 商品主图地数组
+ */
+ private List picUrls;
+
+ // ========== 其他信息 =========
+ /**
+ * 是否上架商品(是否可见)。
+ *
+ * true 为已上架
+ * false 为已下架
+ */
+ private Boolean visible;
+ /**
+ * 排序字段
+ */
+ private Integer sort;
+
+ // ========== Sku 相关字段 =========
+ /**
+ * 原价格,单位:分
+ */
+ private Integer originalPrice;
+ /**
+ * 购买价格,单位:分。
+ */
+ private Integer buyPrice;
+ /**
+ * 库存数量
+ */
+ private Integer quantity;
+
+ // ========== 促销活动相关字段 =========
+ // 目前只促销单体商品促销,目前仅限制折扣。
+ /**
+ * 促销活动编号
+ */
+ private Integer promotionActivityId;
+ /**
+ * 促销活动标题
+ */
+ private String promotionActivityTitle;
+ /**
+ * 促销活动类型
+ */
+ private Integer promotionActivityType;
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductConditionDTO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductConditionDTO.java
new file mode 100644
index 000000000..4bfe0fead
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductConditionDTO.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.search.biz.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Collection;
+
+/**
+ * 获得商品检索条件 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductConditionDTO {
+
+ /**
+ * Field - 商品分类
+ */
+ public static final String FIELD_CATEGORY = "category";
+
+ /**
+ * 关键字
+ */
+ private String keyword;
+ /**
+ * 需要返回的搜索条件的 fields 名
+ */
+ private Collection fields;
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductSearchPageDTO.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductSearchPageDTO.java
new file mode 100644
index 000000000..430a32ed0
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/dto/ProductSearchPageDTO.java
@@ -0,0 +1,43 @@
+package cn.iocoder.mall.search.biz.dto;
+
+import cn.iocoder.common.framework.util.CollectionUtil;
+import cn.iocoder.common.framework.vo.SortingField;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 商品检索分页 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductSearchPageDTO {
+
+ public static final Set SORT_FIELDS = CollectionUtil.asSet("buyPrice");
+
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 关键字
+ */
+ private String keyword;
+
+ /**
+ * 页码
+ */
+ private Integer pageNo;
+ /**
+ * 分页大小
+ */
+ private Integer pageSize;
+
+ /**
+ * 排序字段数组
+ */
+ private List sorts;
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchService.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchService.java
new file mode 100644
index 000000000..50101d746
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchService.java
@@ -0,0 +1,20 @@
+package cn.iocoder.mall.search.biz.service;
+
+
+public interface ProductSearchService {
+
+ Integer rebuild();
+
+ /**
+ * 构建商品的搜索索引
+ *
+ * @param id 商品编号
+ * @return 构建结果
+ */
+ Boolean save(Integer id);
+//
+// ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO);
+//
+// ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO);
+
+}
diff --git a/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java
new file mode 100644
index 000000000..af4b0880c
--- /dev/null
+++ b/search/search-biz/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java
@@ -0,0 +1,147 @@
+package cn.iocoder.mall.search.biz.service;
+
+import cn.iocoder.common.framework.util.CollectionUtil;
+import cn.iocoder.common.framework.vo.SortingField;
+import cn.iocoder.mall.search.biz.dao.ProductRepository;
+import cn.iocoder.mall.search.biz.dto.ProductSearchPageDTO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import java.util.List;
+
+@Service
+@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.ProductSearchService.version}")
+public class ProductSearchServiceImpl implements ProductSearchService {
+
+ private static final Integer REBUILD_FETCH_PER_SIZE = 100;
+
+ @Autowired
+ private ProductRepository productRepository;
+ @Autowired
+ private ElasticsearchTemplate elasticsearchTemplate; // 因为需要使用到聚合操作,只好引入 ElasticsearchTemplate 。
+
+// @Reference(validation = "true", version = "${dubbo.consumer.ProductSpuService.version}")
+// private ProductSpuService productSpuService;
+// @Reference(validation = "true", version = "${dubbo.consumer.ProductCategoryService.version}")
+// private ProductCategoryService productCategoryService;
+// @Reference(validation = "true", version = "${dubbo.consumer.CartService.version}")
+// private CartService cartService;
+
+// @Override
+// public Integer rebuild() {
+// // TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构
+// Integer lastId = null;
+// int rebuildCounts = 0;
+// while (true) {
+// List spus = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE);
+// rebuildCounts += spus.size();
+// // 存储到 ES 中
+// List products = spus.stream().map(this::convert).collect(Collectors.toList());
+// productRepository.saveAll(products);
+// // 设置新的 lastId ,或者结束
+// if (spus.size() < REBUILD_FETCH_PER_SIZE) {
+// break;
+// } else {
+// lastId = spus.get(spus.size() - 1).getId();
+// }
+// }
+// // 返回成功
+// return rebuildCounts;
+// }
+//
+// @Override
+// public Boolean save(Integer id) {
+// // 获得商品性情
+// ProductSpuDetailBO result = productSpuService.getProductSpuDetail(id);
+// // 存储到 ES 中
+// ESProductDO product = convert(result);
+// productRepository.save(product);
+// // 返回成功
+// return true;
+// }
+//
+// @SuppressWarnings("OptionalGetWithoutIsPresent")
+// private ESProductDO convert(ProductSpuDetailBO spu) {
+// // 获得最小价格的 SKU ,用于下面的价格计算
+// ProductSpuDetailBO.Sku sku = spu.getSkus().stream().min(Comparator.comparing(ProductSpuDetailBO.Sku::getPrice)).get();
+// // 价格计算
+// CalcSkuPriceBO calSkuPriceResult = cartService.calcSkuPrice(sku.getId());
+// // 拼装结果
+// return ProductSearchConvert.INSTANCE.convert(spu, calSkuPriceResult);
+// }
+//
+// @Override
+// public ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO) {
+// checkSortFieldInvalid(searchPageDTO.getSorts());
+// // 执行查询
+// Page searchPage = productRepository.search(searchPageDTO.getCid(), searchPageDTO.getKeyword(),
+// searchPageDTO.getPageNo(), searchPageDTO.getPageSize(), searchPageDTO.getSorts());
+// // 转换结果
+// return new ProductPageBO()
+// .setList(ProductSearchConvert.INSTANCE.convert(searchPage.getContent()))
+// .setTotal((int) searchPage.getTotalElements());
+// }
+
+ private void checkSortFieldInvalid(List sorts) {
+ if (CollectionUtil.isEmpty(sorts)) {
+ return;
+ }
+ sorts.forEach(sortingField -> Assert.isTrue(ProductSearchPageDTO.SORT_FIELDS.contains(sortingField.getField()),
+ String.format("排序字段(%s) 不在允许范围内", sortingField.getField())));
+ }
+
+ @Override
+ public Integer rebuild() {
+ return null;
+ }
+
+ @Override
+ public Boolean save(Integer id) {
+ return null;
+ }
+
+// @Override
+// public ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO) {
+// // 创建 ES 搜索条件
+// NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
+// // 筛选
+// if (StringUtil.hasText(conditionDTO.getKeyword())) { // 如果有 keyword ,就去匹配
+// nativeSearchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery(conditionDTO.getKeyword(),
+// "name", "sellPoint", "categoryName"));
+// } else {
+// nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
+// }
+// // 聚合
+// if (conditionDTO.getFields().contains(ProductConditionDTO.FIELD_CATEGORY)) { // 商品分类
+// nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("cids").field("cid"));
+// }
+// // 执行查询
+// ProductConditionBO condition = elasticsearchTemplate.query(nativeSearchQueryBuilder.build(), response -> {
+// ProductConditionBO result = new ProductConditionBO();
+// // categoryIds 聚合
+// Aggregation categoryIdsAggregation = response.getAggregations().get("cids");
+// if (categoryIdsAggregation != null) {
+// result.setCategories(new ArrayList<>());
+// for (LongTerms.Bucket bucket : (((LongTerms) categoryIdsAggregation).getBuckets())) {
+// result.getCategories().add(new ProductConditionBO.Category().setId(bucket.getKeyAsNumber().intValue()));
+// }
+// }
+// // 返回结果
+// return result;
+// });
+// // 聚合其它数据源
+// if (!CollectionUtil.isEmpty(condition.getCategories())) {
+// // 查询指定的 ProductCategoryBO 数组,并转换成 ProductCategoryBO Map
+// Map categoryMap = productCategoryService.getListByIds(
+// condition.getCategories().stream().map(ProductConditionBO.Category::getId).collect(Collectors.toList()))
+// .stream().collect(Collectors.toMap(ProductCategoryBO::getId, category -> category));
+// // 设置分类名
+// condition.getCategories().forEach(category -> category.setName(categoryMap.get(category.getId()).getName()));
+// }
+// // 返回结果
+// return condition;
+// }
+
+}
diff --git a/search/search-biz/src/main/resources/biz.properties b/search/search-biz/src/main/resources/biz.properties
new file mode 100644
index 000000000..197907aff
--- /dev/null
+++ b/search/search-biz/src/main/resources/biz.properties
@@ -0,0 +1,8 @@
+##################### 业务模块 #####################
+## OAuth2CodeService
+modules.oauth2-code-service.access-token-expire-time-millis = 2880000
+modules.oauth2-code-service.refresh-token-expire-time-millis = 43200000
+## OAuth2MobileCodeService
+modules.oauth2-mobile-code-service.code-expire-time-millis = 600000
+modules.oauth2-mobile-code-service.send-maximum-quantity-per-day = 10
+modules.oauth2-mobile-code-service.send-frequency = 60000
diff --git a/search/search-biz/src/main/resources/biz.yaml b/search/search-biz/src/main/resources/biz.yaml
new file mode 100644
index 000000000..fc41b8a93
--- /dev/null
+++ b/search/search-biz/src/main/resources/biz.yaml
@@ -0,0 +1,7 @@
+spring:
+ data:
+ # Jest 配置项
+ jest:
+ uri: http://127.0.0.1:9200
+
+
diff --git a/search/search-rest/pom.xml b/search/search-rest/pom.xml
new file mode 100644
index 000000000..fa0bbe14f
--- /dev/null
+++ b/search/search-rest/pom.xml
@@ -0,0 +1,42 @@
+
+
+
+ search
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ search-rest
+ 提供 商品搜索服务的 Rest 接口的实现,提供对外调用
+
+
+
+
+ cn.iocoder.mall
+ search-biz
+ 1.0-SNAPSHOT
+
+
+
+
+ cn.iocoder.mall
+ mall-spring-boot-starter-web
+ 1.0-SNAPSHOT
+
+
+ cn.iocoder.mall
+ mall-spring-boot-starter-security
+ 1.0-SNAPSHOT
+
+
+ cn.iocoder.mall
+ mall-spring-boot-starter-swagger
+ 1.0-SNAPSHOT
+
+
+
+
+
\ No newline at end of file
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/controller/user/UsersProductSearchController.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/controller/user/UsersProductSearchController.java
new file mode 100644
index 000000000..9a44420be
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/controller/user/UsersProductSearchController.java
@@ -0,0 +1,72 @@
+package cn.iocoder.mall.search.rest.controller.user;
+
+import cn.iocoder.common.framework.constant.MallConstants;
+import cn.iocoder.common.framework.util.StringUtil;
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.common.framework.vo.SortingField;
+import cn.iocoder.mall.search.biz.service.ProductSearchService;
+import cn.iocoder.mall.search.rest.response.user.ProductPageResponse;
+import io.swagger.annotations.Api;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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 cn.iocoder.mall.search.rest.request.user.ProductConditionRequest;
+import cn.iocoder.mall.search.rest.request.user.ProductSearchPageRequest;
+import cn.iocoder.mall.search.rest.response.user.ProductConditionResponse;
+
+import java.util.Collections;
+
+import static cn.iocoder.common.framework.vo.CommonResult.success;
+
+/**
+ * Created with IDEA
+ *
+ * @author : lhl
+ * @version : 1.0
+ * @Time : 19:26
+ * @date : 2020/5/14
+ */
+@RestController
+@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "users/product")
+@Api(tags = "商品查询 API")
+@Slf4j
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class UsersProductSearchController {
+
+
+ private final ProductSearchService productSearchService;
+
+ @GetMapping("/page") // TODO 芋艿,后面把 BO 改成 VO
+ public CommonResult page(@RequestParam(value = "cid", required = false) Integer cid,
+ @RequestParam(value = "keyword", required = false) String keyword,
+ @RequestParam(value = "pageNo", required = false) Integer pageNo,
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,
+ @RequestParam(value = "sortField", required = false) String sortField,
+ @RequestParam(value = "sortOrder", required = false) String sortOrder) {
+ // 创建 ProductSearchPageDTO 对象
+ ProductSearchPageRequest productSearchPageDTO = new ProductSearchPageRequest().setCid(cid).setKeyword(keyword)
+ .setPageNo(pageNo).setPageSize(pageSize);
+ if (StringUtil.hasText(sortField) && StringUtil.hasText(sortOrder)) {
+ productSearchPageDTO.setSorts(Collections.singletonList(new SortingField(sortField, sortOrder)));
+ }
+ // 执行搜索
+// return success(productSearchService.getSearchPage(productSearchPageDTO));
+ return success(null);
+ }
+
+ @GetMapping("/condition") // TODO 芋艿,后面把 BO 改成 VO
+ public CommonResult condition(@RequestParam(value = "keyword", required = false) String keyword) {
+ // 创建 ProductConditionDTO 对象
+ ProductConditionRequest productConditionDTO = new ProductConditionRequest().setKeyword(keyword)
+ .setFields(Collections.singleton(ProductConditionRequest.FIELD_CATEGORY));
+ // 执行搜索
+// return success(productSearchService.getSearchCondition(productConditionDTO));
+ return success(null);
+ }
+
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/convert/user/UsersProductSearchConvert.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/convert/user/UsersProductSearchConvert.java
new file mode 100644
index 000000000..4fcdac3bd
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/convert/user/UsersProductSearchConvert.java
@@ -0,0 +1,35 @@
+package cn.iocoder.mall.search.rest.convert.user;
+
+import cn.iocoder.mall.search.biz.bo.ProductBO;
+import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface UsersProductSearchConvert {
+
+ cn.iocoder.mall.search.biz.convert.ProductSearchConvert INSTANCE = Mappers.getMapper(cn.iocoder.mall.search.biz.convert.ProductSearchConvert.class);
+
+// @Mappings({})
+// ESProductDO convert(ProductSpuDetailBO spu);
+
+// @Mappings({})
+// default ESProductDO convert(ProductSpuDetailBO spu, CalcSkuPriceBO calcSkuPrice) {
+// // Spu 的基础数据
+// ESProductDO product = this.convert(spu);
+// product.setOriginalPrice(calcSkuPrice.getOriginalPrice()).setBuyPrice(calcSkuPrice.getBuyPrice());
+// // 设置促销活动相关字段
+// if (calcSkuPrice.getTimeLimitedDiscount() != null) {
+// PromotionActivityBO activity = calcSkuPrice.getTimeLimitedDiscount();
+// product.setPromotionActivityId(activity.getId()).setPromotionActivityTitle(activity.getTitle())
+// .setPromotionActivityType(activity.getActivityType());
+// }
+// // 返回
+// return product;
+// }
+
+ List convert(List list);
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductConditionRequest.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductConditionRequest.java
new file mode 100644
index 000000000..c90b0b957
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductConditionRequest.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.search.rest.request.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Collection;
+
+/**
+ * 获得商品检索条件 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class UsersProductConditionRequest{
+
+ /**
+ * Field - 商品分类
+ */
+ public static final String FIELD_CATEGORY = "category";
+
+ /**
+ * 关键字
+ */
+ private String keyword;
+ /**
+ * 需要返回的搜索条件的 fields 名
+ */
+ private Collection fields;
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductSearchPageRequest.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductSearchPageRequest.java
new file mode 100644
index 000000000..bdb2c52f8
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/request/user/UsersProductSearchPageRequest.java
@@ -0,0 +1,48 @@
+package cn.iocoder.mall.search.rest.request.user;
+
+import cn.iocoder.common.framework.util.CollectionUtil;
+import cn.iocoder.common.framework.vo.SortingField;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created with IDEA
+ *
+ * @author : lhl
+ * @version : 1.0
+ * @Time : 19:09
+ * @date : 2020/5/14
+ */
+@Data
+@Accessors(chain = true)
+public class UsersProductSearchPageRequest {
+
+ public static final Set SORT_FIELDS = CollectionUtil.asSet("buyPrice");
+
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 关键字
+ */
+ private String keyword;
+
+ /**
+ * 页码
+ */
+ private Integer pageNo;
+ /**
+ * 分页大小
+ */
+ private Integer pageSize;
+
+ /**
+ * 排序字段数组
+ */
+ private List sorts;
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductConditionResponse.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductConditionResponse.java
new file mode 100644
index 000000000..4b008a8ff
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductConditionResponse.java
@@ -0,0 +1,35 @@
+package cn.iocoder.mall.search.rest.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 商品搜索条件返回 BO
+ */
+@Data
+@Accessors(chain = true)
+public class UsersProductConditionResponse {
+
+ /**
+ * 商品分类数组
+ */
+ private List categories;
+
+ @Data
+ @Accessors(chain = true)
+ public static class Category {
+
+ /**
+ * 分类编号
+ */
+ private Integer id;
+ /**
+ * 分类名称
+ */
+ private String name;
+
+ }
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductPageResponse.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductPageResponse.java
new file mode 100644
index 000000000..56ece1465
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductPageResponse.java
@@ -0,0 +1,22 @@
+package cn.iocoder.mall.search.rest.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+public class UsersProductPageResponse implements Serializable {
+
+ /**
+ * 管理员数组
+ */
+ private List list;
+ /**
+ * 总量
+ */
+ private Integer total;
+
+}
diff --git a/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductResponse.java b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductResponse.java
new file mode 100644
index 000000000..5d5127fc7
--- /dev/null
+++ b/search/search-rest/src/main/java/cn/iocoder/mall/search/rest/response/user/UsersProductResponse.java
@@ -0,0 +1,86 @@
+package cn.iocoder.mall.search.rest.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 商品 ES BO
+ */
+@Data
+@Accessors(chain = true)
+public class UsersProductResponse implements Serializable {
+
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ private String name;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+ /**
+ * 描述
+ */
+ private String description;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 分类名
+ */
+ private String categoryName;
+ /**
+ * 商品主图地数组
+ */
+ private List picUrls;
+
+ // ========== 其他信息 =========
+ /**
+ * 是否上架商品(是否可见)。
+ *
+ * true 为已上架
+ * false 为已下架
+ */
+ private Boolean visible;
+ /**
+ * 排序字段
+ */
+ private Integer sort;
+
+ // ========== Sku 相关字段 =========
+ /**
+ * 原价格,单位:分
+ */
+ private Integer originalPrice;
+ /**
+ * 购买价格,单位:分。
+ */
+ private Integer buyPrice;
+ /**
+ * 库存数量
+ */
+ private Integer quantity;
+
+ // ========== 促销活动相关字段 =========
+ // 目前只促销单体商品促销,目前仅限制折扣。
+ /**
+ * 促销活动编号
+ */
+ private Integer promotionActivityId;
+ /**
+ * 促销活动标题
+ */
+ private String promotionActivityTitle;
+ /**
+ * 促销活动类型
+ */
+ private Integer promotionActivityType;
+
+}
diff --git a/search/search-rest/src/main/resources/rest.yaml b/search/search-rest/src/main/resources/rest.yaml
new file mode 100644
index 000000000..778308fcf
--- /dev/null
+++ b/search/search-rest/src/main/resources/rest.yaml
@@ -0,0 +1,12 @@
+# 服务器的配置项
+server:
+ port: 18099
+ servlet:
+ context-path: /search-api/
+
+# Swagger 配置项
+swagger:
+ title: 商品查询子系统
+ description: 商品查询子系统
+ version: 1.0.0
+ base-package: cn.iocoder.mall.search.rest.controller
diff --git a/search/search-rpc-api/pom.xml b/search/search-rpc-api/pom.xml
new file mode 100644
index 000000000..2dd3c6c5c
--- /dev/null
+++ b/search/search-rpc-api/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+ search
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ search-rpc-api
+
+
+
+
+
+ search-biz-api
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+
+
+
+ javax.validation
+ validation-api
+
+
+ org.projectlombok
+ lombok
+
+
+
\ No newline at end of file
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/api/user/ProductSearchRPC.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/api/user/ProductSearchRPC.java
new file mode 100644
index 000000000..57a7e83aa
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/api/user/ProductSearchRPC.java
@@ -0,0 +1,21 @@
+package cn.iocoder.mall.search.biz.api.user;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+
+public interface ProductSearchRPC {
+
+ CommonResult rebuild();
+
+ /**
+ * 构建商品的搜索索引
+ *
+ * @param id 商品编号
+ * @return 构建结果
+ */
+ CommonResult save(Integer id);
+
+// ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO);
+//
+// ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO);
+
+}
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductConditionRequest.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductConditionRequest.java
new file mode 100644
index 000000000..eb9fd74ec
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductConditionRequest.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.search.biz.request.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Collection;
+
+/**
+ * 获得商品检索条件 DTO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductConditionRequest {
+
+ /**
+ * Field - 商品分类
+ */
+ public static final String FIELD_CATEGORY = "category";
+
+ /**
+ * 关键字
+ */
+ private String keyword;
+ /**
+ * 需要返回的搜索条件的 fields 名
+ */
+ private Collection fields;
+
+}
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductSearchPageRequest.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductSearchPageRequest.java
new file mode 100644
index 000000000..a722eea46
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/request/user/ProductSearchPageRequest.java
@@ -0,0 +1,48 @@
+package cn.iocoder.mall.search.biz.request.user;
+
+import cn.iocoder.common.framework.util.CollectionUtil;
+import cn.iocoder.common.framework.vo.SortingField;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created with IDEA
+ *
+ * @author : lhl
+ * @version : 1.0
+ * @Time : 19:09
+ * @date : 2020/5/14
+ */
+@Data
+@Accessors(chain = true)
+public class ProductSearchPageRequest {
+
+ public static final Set SORT_FIELDS = CollectionUtil.asSet("buyPrice");
+
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 关键字
+ */
+ private String keyword;
+
+ /**
+ * 页码
+ */
+ private Integer pageNo;
+ /**
+ * 分页大小
+ */
+ private Integer pageSize;
+
+ /**
+ * 排序字段数组
+ */
+ private List sorts;
+
+}
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductConditionResponse.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductConditionResponse.java
new file mode 100644
index 000000000..2b48816f1
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductConditionResponse.java
@@ -0,0 +1,35 @@
+package cn.iocoder.mall.search.biz.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 商品搜索条件返回 BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductConditionResponse {
+
+ /**
+ * 商品分类数组
+ */
+ private List categories;
+
+ @Data
+ @Accessors(chain = true)
+ public static class Category {
+
+ /**
+ * 分类编号
+ */
+ private Integer id;
+ /**
+ * 分类名称
+ */
+ private String name;
+
+ }
+
+}
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductPageResponse.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductPageResponse.java
new file mode 100644
index 000000000..56db936ad
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductPageResponse.java
@@ -0,0 +1,22 @@
+package cn.iocoder.mall.search.biz.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+public class ProductPageResponse implements Serializable {
+
+ /**
+ * 管理员数组
+ */
+ private List list;
+ /**
+ * 总量
+ */
+ private Integer total;
+
+}
diff --git a/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductResponse.java b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductResponse.java
new file mode 100644
index 000000000..31952582b
--- /dev/null
+++ b/search/search-rpc-api/src/main/java/cn/iocoder/mall/search/biz/response/user/ProductResponse.java
@@ -0,0 +1,86 @@
+package cn.iocoder.mall.search.biz.response.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 商品 ES BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductResponse implements Serializable {
+
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ private String name;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+ /**
+ * 描述
+ */
+ private String description;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 分类名
+ */
+ private String categoryName;
+ /**
+ * 商品主图地数组
+ */
+ private List picUrls;
+
+ // ========== 其他信息 =========
+ /**
+ * 是否上架商品(是否可见)。
+ *
+ * true 为已上架
+ * false 为已下架
+ */
+ private Boolean visible;
+ /**
+ * 排序字段
+ */
+ private Integer sort;
+
+ // ========== Sku 相关字段 =========
+ /**
+ * 原价格,单位:分
+ */
+ private Integer originalPrice;
+ /**
+ * 购买价格,单位:分。
+ */
+ private Integer buyPrice;
+ /**
+ * 库存数量
+ */
+ private Integer quantity;
+
+ // ========== 促销活动相关字段 =========
+ // 目前只促销单体商品促销,目前仅限制折扣。
+ /**
+ * 促销活动编号
+ */
+ private Integer promotionActivityId;
+ /**
+ * 促销活动标题
+ */
+ private String promotionActivityTitle;
+ /**
+ * 促销活动类型
+ */
+ private Integer promotionActivityType;
+
+}
diff --git a/search/search-rpc/pom.xml b/search/search-rpc/pom.xml
new file mode 100644
index 000000000..d46e9e2f4
--- /dev/null
+++ b/search/search-rpc/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ search
+ cn.iocoder.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ search-rpc
+
+
+
+
+
+ cn.iocoder.mall
+ search-rpc-api
+ 1.0-SNAPSHOT
+
+
+
+ cn.iocoder.mall
+ search-biz
+ 1.0-SNAPSHOT
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-dubbo
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.github.vanroy
+ spring-boot-starter-data-jest
+
+
+
+
\ No newline at end of file
diff --git a/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java b/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
new file mode 100644
index 000000000..b83142908
--- /dev/null
+++ b/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
@@ -0,0 +1,35 @@
+package cn.iocoder.mall.search.biz.convert;
+
+import cn.iocoder.mall.search.biz.bo.ProductBO;
+import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface ProductSearchConvert {
+
+ ProductSearchConvert INSTANCE = Mappers.getMapper(ProductSearchConvert.class);
+
+// @Mappings({})
+// ESProductDO convert(ProductSpuDetailBO spu);
+
+// @Mappings({})
+// default ESProductDO convert(ProductSpuDetailBO spu, CalcSkuPriceBO calcSkuPrice) {
+// // Spu 的基础数据
+// ESProductDO product = this.convert(spu);
+// product.setOriginalPrice(calcSkuPrice.getOriginalPrice()).setBuyPrice(calcSkuPrice.getBuyPrice());
+// // 设置促销活动相关字段
+// if (calcSkuPrice.getTimeLimitedDiscount() != null) {
+// PromotionActivityBO activity = calcSkuPrice.getTimeLimitedDiscount();
+// product.setPromotionActivityId(activity.getId()).setPromotionActivityTitle(activity.getTitle())
+// .setPromotionActivityType(activity.getActivityType());
+// }
+// // 返回
+// return product;
+// }
+
+ List convert(List list);
+
+}
diff --git a/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/rpc/user/ProductSearchRPCImpl.java b/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/rpc/user/ProductSearchRPCImpl.java
new file mode 100644
index 000000000..129068bdf
--- /dev/null
+++ b/search/search-rpc/src/main/java/cn/iocoder/mall/search/biz/rpc/user/ProductSearchRPCImpl.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.search.biz.rpc.user;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.search.biz.api.user.ProductSearchRPC;
+import cn.iocoder.mall.search.biz.service.ProductSearchService;
+import org.apache.dubbo.config.annotation.Service;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+@Service(validation = "true", version = "${dubbo.provider.ProductSearchRpc.version}")
+public class ProductSearchRPCImpl implements ProductSearchRPC {
+
+ @Autowired
+ private ProductSearchService productSearchService;
+
+ @Override
+ public CommonResult rebuild() {
+ return null;
+ }
+
+ @Override
+ public CommonResult save(Integer id){
+// ProductSpuDetailBO productSpuDetail = productSpuService.getProductSpuDetail(spuId);
+// return ProductSpuConvert.INSTANCE.convertDetail(productSpuDetail);
+ return CommonResult.success(true);
+ }
+
+
+}
diff --git a/search/search-rpc/src/main/resources/rpc-local.yaml b/search/search-rpc/src/main/resources/rpc-local.yaml
new file mode 100644
index 000000000..e056170af
--- /dev/null
+++ b/search/search-rpc/src/main/resources/rpc-local.yaml
@@ -0,0 +1,14 @@
+spring:
+ # Spring Cloud 配置项
+ cloud:
+ nacos:
+ # Spring Cloud Nacos Discovery 配置项
+ discovery:
+ server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
+ namespace: local # Nacos 命名空间
+
+# Dubbo 配置项
+dubbo:
+ # Dubbo 注册中心
+ registry:
+ address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
diff --git a/search/search-rpc/src/main/resources/rpc-test.yaml b/search/search-rpc/src/main/resources/rpc-test.yaml
new file mode 100644
index 000000000..d3d0e9e69
--- /dev/null
+++ b/search/search-rpc/src/main/resources/rpc-test.yaml
@@ -0,0 +1,14 @@
+spring:
+ # Spring Cloud 配置项
+ cloud:
+ nacos:
+ # Spring Cloud Nacos Discovery 配置项
+ discovery:
+ server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
+ namespace: test # Nacos 命名空间
+
+# Dubbo 配置项
+dubbo:
+ # Dubbo 注册中心
+ registry:
+ address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
diff --git a/search/search-rpc/src/main/resources/rpc.yaml b/search/search-rpc/src/main/resources/rpc.yaml
new file mode 100644
index 000000000..398fbf430
--- /dev/null
+++ b/search/search-rpc/src/main/resources/rpc.yaml
@@ -0,0 +1,22 @@
+# Dubbo 配置项
+dubbo:
+ # Spring Cloud Alibaba Dubbo 专属配置
+ cloud:
+ subscribed-services: 'search-application' # 设置订阅的应用列表,默认为 * 订阅所有应用
+ # Dubbo 提供者的协议
+ protocol:
+ name: dubbo
+ port: -1
+ # Dubbo 提供服务的扫描基础包
+ scan:
+ base-packages: cn.iocoder.mall.search.rpc.rpc
+ # Dubbo 服务提供者的配置
+ provider:
+# filter: -exception
+# ProductSpuService:
+# version: 1.0.0
+
+ # Dubbo 服务消费者的配置
+ consumer:
+# ProductSpuService:
+# version: 1.0.0
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java
index ca4f714a0..6d4bbf1d6 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java
@@ -1,9 +1,9 @@
-package cn.iocoder.mall.search.api;
+package cn.iocoder.mall.search.biz;
-import cn.iocoder.mall.search.api.bo.ProductConditionBO;
-import cn.iocoder.mall.search.api.bo.ProductPageBO;
-import cn.iocoder.mall.search.api.dto.ProductConditionDTO;
-import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
+import cn.iocoder.mall.search.biz.bo.ProductConditionBO;
+import cn.iocoder.mall.search.biz.bo.ProductPageBO;
+import cn.iocoder.mall.search.biz.dto.ProductConditionDTO;
+import cn.iocoder.mall.search.biz.dto.ProductSearchPageDTO;
public interface ProductSearchService {
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductBO.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductBO.java
index acaa15fce..7ba301041 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductBO.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductBO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.api.bo;
+package cn.iocoder.mall.search.biz.bo;
import lombok.Data;
import lombok.experimental.Accessors;
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductConditionBO.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductConditionBO.java
index 238b0dbb2..b8eebbfe6 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductConditionBO.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductConditionBO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.api.bo;
+package cn.iocoder.mall.search.biz.bo;
import lombok.Data;
import lombok.experimental.Accessors;
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductPageBO.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductPageBO.java
index b18871a53..827b7996f 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductPageBO.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/bo/ProductPageBO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.api.bo;
+package cn.iocoder.mall.search.biz.bo;
import lombok.Data;
import lombok.experimental.Accessors;
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductConditionDTO.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductConditionDTO.java
index ff1d54c0b..4bfe0fead 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductConditionDTO.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductConditionDTO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.api.dto;
+package cn.iocoder.mall.search.biz.dto;
import lombok.Data;
import lombok.experimental.Accessors;
diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductSearchPageDTO.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductSearchPageDTO.java
index bfc465bd1..430a32ed0 100644
--- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductSearchPageDTO.java
+++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/dto/ProductSearchPageDTO.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.api.dto;
+package cn.iocoder.mall.search.biz.dto;
import cn.iocoder.common.framework.util.CollectionUtil;
import cn.iocoder.common.framework.vo.SortingField;
diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
index ed239635d..6a42e33ca 100644
--- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
+++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/convert/ProductSearchConvert.java
@@ -3,7 +3,7 @@ package cn.iocoder.mall.search.biz.convert;
import cn.iocoder.mall.order.api.bo.CalcSkuPriceBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.promotion.api.bo.PromotionActivityBO;
-import cn.iocoder.mall.search.api.bo.ProductBO;
+import cn.iocoder.mall.search.biz.bo.ProductBO;
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java
index 81d4fa6e9..d2b3156e2 100644
--- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java
+++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java
@@ -1,7 +1,7 @@
package cn.iocoder.mall.search.biz.mq;
import cn.iocoder.mall.product.api.message.ProductUpdateMessage;
-import cn.iocoder.mall.search.api.ProductSearchService;
+import cn.iocoder.mall.search.biz.ProductSearchService;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java
index 1a787a8a2..1adda27c5 100644
--- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java
+++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.biz.service;
+package cn.iocoder.mall.search.biz.api;
import cn.iocoder.common.framework.util.CollectionUtil;
import cn.iocoder.common.framework.util.StringUtil;
@@ -9,11 +9,11 @@ import cn.iocoder.mall.product.api.ProductCategoryService;
import cn.iocoder.mall.product.api.ProductSpuService;
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
-import cn.iocoder.mall.search.api.ProductSearchService;
-import cn.iocoder.mall.search.api.bo.ProductConditionBO;
-import cn.iocoder.mall.search.api.bo.ProductPageBO;
-import cn.iocoder.mall.search.api.dto.ProductConditionDTO;
-import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
+import cn.iocoder.mall.search.biz.ProductSearchService;
+import cn.iocoder.mall.search.biz.bo.ProductConditionBO;
+import cn.iocoder.mall.search.biz.bo.ProductPageBO;
+import cn.iocoder.mall.search.biz.dto.ProductConditionDTO;
+import cn.iocoder.mall.search.biz.dto.ProductSearchPageDTO;
import cn.iocoder.mall.search.biz.convert.ProductSearchConvert;
import cn.iocoder.mall.search.biz.dao.ProductRepository;
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
diff --git a/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java b/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java
index 440478552..06ffc3b2f 100644
--- a/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java
+++ b/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java
@@ -1,4 +1,4 @@
-package cn.iocoder.mall.search.biz.service;
+package cn.iocoder.mall.search.biz.api;
import cn.iocoder.mall.search.biz.dao.ProductRepository;
import org.junit.Test;
diff --git a/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java b/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java
index eb632381f..69a0e2956 100644
--- a/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java
+++ b/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java
@@ -7,7 +7,7 @@ import cn.iocoder.common.framework.util.ServiceExceptionUtil;
*
* system 系统,使用 1-002-000-000 段
*/
-public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
+public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
// ========== OAUTH2 模块 ==========
OAUTH2_UNKNOWN(1001001000, "未知错误"), // 预留
@@ -113,8 +113,16 @@ public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
return code;
}
+ @Override
public String getMessage() {
return message;
}
+ // TODO: 2020-05-22 封装成start的时候,直接在start中定义一个统一的枚举,从中取值;
+ @Override
+ public int getGroup() {
+ return 0;
+ }
+
+
}
diff --git a/system/system-biz/pom.xml b/system/system-biz/pom.xml
index 2375b2c26..6f2ee0145 100644
--- a/system/system-biz/pom.xml
+++ b/system/system-biz/pom.xml
@@ -85,6 +85,22 @@
fastjson
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework
+ spring-webmvc
+ compile
+
+
+ javax.servlet
+ servlet-api
+ compile
+
+
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/systemlog/AccessLogBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/systemlog/AccessLogBO.java
index c423596f5..ad2f62595 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/systemlog/AccessLogBO.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/systemlog/AccessLogBO.java
@@ -6,7 +6,7 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
-/**
+/** // TODO FROM 芋艿 to 2447007062:最好加下字段的注释哈;
* @author:mac
* @descriptio
* @create: 2020-5-12 20:43:00
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/config/ServiceExceptionConfiguration.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/config/ServiceExceptionConfiguration.java
index 50400ee5b..56d69ca98 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/config/ServiceExceptionConfiguration.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/config/ServiceExceptionConfiguration.java
@@ -20,11 +20,12 @@ public class ServiceExceptionConfiguration {
@EventListener(ApplicationReadyEvent.class) // 可参考 https://www.cnblogs.com/ssslinppp/p/7607509.html
public void initMessages() {
- List list = errorCodeService.getErrorCodeList();
+ errorCodeService.deleteSyStemErrorCode(SystemErrorCodeEnum.ADMIN_NOT_FOUND.getGroup());
+ errorCodeService.addSystemErrorCodeList(SystemErrorCodeEnum.values());
for (SystemErrorCodeEnum item : SystemErrorCodeEnum.values()) {
ServiceExceptionUtil.put(item.getCode(), item.getMessage());
}
- for (ErrorCodeBO bo : list) {
+ for (ErrorCodeBO bo : errorCodeService.getErrorCodeByGroup(SystemErrorCodeEnum.ADMIN_NOT_FOUND.getGroup())) {
ServiceExceptionUtil.put(bo.getCode(),bo.getMessage());
}
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/errorcode/ErrorCodeMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/errorcode/ErrorCodeMapper.java
index 1fd45cc24..5314e8e79 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/errorcode/ErrorCodeMapper.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/errorcode/ErrorCodeMapper.java
@@ -2,12 +2,14 @@ package cn.iocoder.mall.system.biz.dao.errorcode;
import cn.iocoder.mall.mybatis.query.QueryWrapperX;
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
+import cn.iocoder.mall.system.biz.dataobject.authorization.RoleResourceDO;
import cn.iocoder.mall.system.biz.dataobject.errorcode.ErrorCodeDO;
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodeDTO;
import cn.iocoder.mall.system.biz.dto.errorcode.ErrorCodePageDTO;
import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum;
import cn.iocoder.mall.system.biz.enums.errorcode.ErrorCodeTypeEnum;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -42,4 +44,9 @@ public interface ErrorCodeMapper extends BaseMapper {
default List selectByGroup(Integer group) {
return selectList(new QueryWrapperX().eqIfPresent("group", group));
}
+
+
+ default int deleteSyStemErrorCode(int group){
+ return delete(new QueryWrapper().eq("group", group));
+ }
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/user/UserMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/user/UserMapper.java
index 3cac873f8..fc636771f 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/user/UserMapper.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/user/UserMapper.java
@@ -1,5 +1,7 @@
package cn.iocoder.mall.system.biz.dao.user;
+import cn.iocoder.mall.mybatis.query.QueryWrapperX;
+import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
import cn.iocoder.mall.system.biz.dataobject.user.UserDO;
import cn.iocoder.mall.system.biz.dto.user.UserPageDTO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -25,12 +27,11 @@ public interface UserMapper extends BaseMapper {
* @return
*/
default IPage selectUserPage(UserPageDTO userPageDTO) {
- // TODO FROM 芋艿 to jwf1173:看下 QueryWrapperX 噢,已经提供判空啦
- // TODO FROM 伟帆 to 芋艿: 这里是使用MP原生的判空,支持lambda好,还是使用QueryWrapperX,使用字段名字符串的好呢
+ // TODO FROM 芋艿 to jwf1173:看下 QueryWrapperX 噢,已经提供判空啦 [DONE]
return this.selectPage(new Page<>(userPageDTO.getPageNo(), userPageDTO.getPageSize()),
- Wrappers.query().lambda()
- .eq(StringUtils.isNotBlank(userPageDTO.getNickname()), UserDO::getNickname, userPageDTO.getNickname())
- .eq(null != userPageDTO.getStatus(), UserDO::getStatus, userPageDTO.getStatus())
+ new QueryWrapperX()
+ .eq(StringUtils.isNotBlank(userPageDTO.getNickname()), "nickname", userPageDTO.getNickname())
+ .eq(null != userPageDTO.getStatus(), "status", userPageDTO.getStatus())
);
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/system/AccessLogPageDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/system/AccessLogPageDTO.java
index 4af88b553..6e7a6fe85 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/system/AccessLogPageDTO.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/system/AccessLogPageDTO.java
@@ -4,14 +4,13 @@ import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
-import java.util.Date;
/**
* 访问日志添加 DTO
*/
@Data
@Accessors(chain = true)
-public class AccessLogPageDTO {
+public class AccessLogPageDTO { // TODO FROM 芋艿 to 2447007062:有个 PageParams 类哈,可以继承
/**
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/annotation/OperationLogging.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/annotation/OperationLogging.java
new file mode 100644
index 000000000..db597757f
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/annotation/OperationLogging.java
@@ -0,0 +1,20 @@
+package cn.iocoder.mall.system.biz.log.operation.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author Hccake
+ * @version 1.0
+ * @date 2019/10/15 18:09
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface OperationLogging {
+
+ /**
+ * 日志信息
+ * @return
+ */
+ String value();
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/aspect/OperationLogAspect.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/aspect/OperationLogAspect.java
new file mode 100644
index 000000000..a89b1f2e4
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/aspect/OperationLogAspect.java
@@ -0,0 +1,118 @@
+package cn.iocoder.mall.system.biz.log.operation.aspect;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.URLUtil;
+import cn.hutool.json.JSONUtil;
+import cn.iocoder.common.framework.util.HttpUtil;
+import cn.iocoder.common.framework.util.MallUtil;
+import cn.iocoder.mall.system.biz.log.operation.annotation.OperationLogging;
+import cn.iocoder.mall.system.biz.log.operation.enums.LogStatus;
+import cn.iocoder.mall.system.biz.log.operation.event.OperationLogEvent;
+import cn.iocoder.mall.system.biz.log.operation.model.dto.OperationLogDTO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.core.annotation.Order;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Hccake
+ * @version 1.0
+ * @date 2019/10/15 18:16
+ */
+@Slf4j
+@Aspect
+@Order(0)
+@RequiredArgsConstructor
+public class OperationLogAspect {
+ private final ApplicationEventPublisher publisher;
+
+ @Around("@annotation(operationLogging)")
+ public Object around(ProceedingJoinPoint joinPoint, OperationLogging operationLogging) throws Throwable {
+ Signature signature = joinPoint.getSignature();
+ String strClassName = joinPoint.getTarget().getClass().getName();
+ String strMethodName = signature.getName();
+ log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
+
+ // 获取日志
+ OperationLogDTO operationLogDTO = prodOperationLog();
+ operationLogDTO.setMsg(operationLogging.value());
+ // 记录参数
+ MethodSignature methodSignature = (MethodSignature) signature;
+ operationLogDTO.setParams(getParams(joinPoint, methodSignature));
+ // 开始时间
+ long startTime = System.currentTimeMillis();
+ Object result;
+ try {
+ result = joinPoint.proceed();
+ } catch (Throwable throwable) {
+ operationLogDTO.setStatus(LogStatus.FAIL.getValue());
+ throw throwable;
+ }
+ // 结束时间
+ operationLogDTO.setResponseTime((int) (System.currentTimeMillis() - startTime));
+ // 发布事件
+ publisher.publishEvent(new OperationLogEvent(operationLogDTO));
+
+ return result;
+ }
+
+
+ /**
+ * 获取方法参数
+ * @param joinPoint joinPoint
+ * @param methodSignature 方法签名
+ * @return 方法参数的Json字符串形式
+ */
+ private String getParams(ProceedingJoinPoint joinPoint, MethodSignature methodSignature) {
+ String[] parameterNames = methodSignature.getParameterNames();
+ Object[] args = joinPoint.getArgs();
+ if(ArrayUtil.isEmpty(parameterNames)){
+ return null;
+ }
+ Map paramsMap = new HashMap<>();
+ for (int i = 0; i < parameterNames.length; i++) {
+ paramsMap.put(parameterNames[i], args[i]);
+ }
+ return JSONUtil.toJsonStr(paramsMap);
+ }
+
+
+ /**
+ * 根据请求生成操作日志
+ * @return 操作日志DTO
+ */
+ private OperationLogDTO prodOperationLog() {
+ HttpServletRequest request = ((ServletRequestAttributes) Objects
+ .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+
+ return new OperationLogDTO()
+ .setTraceId(MallUtil.getTraceId())
+ .setUri(URLUtil.getPath(request.getRequestURI()))
+ .setUserAgent(HttpUtil.getUserAgent(request))
+ .setIp(HttpUtil.getIp(request))
+ .setMethod(request.getMethod())
+ // TODO 获取管理员用户名 或者 用户ID
+ // .setOperator(Objects.requireNonNull(LogUtils.getUsername()))
+ .setStatus(LogStatus.SUCCESS.getValue());
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/enums/LogStatus.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/enums/LogStatus.java
new file mode 100644
index 000000000..c6a6ae5d9
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/enums/LogStatus.java
@@ -0,0 +1,27 @@
+package cn.iocoder.mall.system.biz.log.operation.enums;
+
+/**
+ * @author Hccake
+ * @version 1.0
+ * @date 2020/5/15 14:47
+ */
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 操作状态
+ */
+@Getter
+@AllArgsConstructor
+public enum LogStatus {
+ /**
+ * 成功
+ */
+ SUCCESS(1),
+ /**
+ * 失败
+ */
+ FAIL(0);
+
+ private final int value;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogEvent.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogEvent.java
new file mode 100644
index 000000000..40051f3a6
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogEvent.java
@@ -0,0 +1,15 @@
+package cn.iocoder.mall.system.biz.log.operation.event;
+
+import cn.iocoder.mall.system.biz.log.operation.model.dto.OperationLogDTO;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author
+ * 系统日志事件
+ */
+@Getter
+@AllArgsConstructor
+public class OperationLogEvent {
+ private final OperationLogDTO operationLogDTO;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogListener.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogListener.java
new file mode 100644
index 000000000..2a41ef616
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/event/OperationLogListener.java
@@ -0,0 +1,26 @@
+package cn.iocoder.mall.system.biz.log.operation.event;
+
+import cn.iocoder.mall.system.biz.log.operation.service.OperationLogSaveService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Async;
+
+/**
+ * @author
+ * 异步监听日志事件
+ */
+@Slf4j
+public class OperationLogListener {
+
+ @Autowired
+ private OperationLogSaveService operationLogSaveService;
+
+ @Async
+ @Order
+ @EventListener(OperationLogEvent.class)
+ public void saveSysLog(OperationLogEvent event) {
+ operationLogSaveService.saveLog(event.getOperationLogDTO());
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/dto/OperationLogDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/dto/OperationLogDTO.java
new file mode 100644
index 000000000..dd675d12c
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/dto/OperationLogDTO.java
@@ -0,0 +1,87 @@
+package cn.iocoder.mall.system.biz.log.operation.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+/**
+ * 操作日志
+ *
+ * @author hccake
+ * @date 2020-05-15 15:12:53
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "操作日志")
+public class OperationLogDTO{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 链路追踪编号
+ */
+ @ApiModelProperty(value = "链路追踪编号")
+ private String traceId;
+ /**
+ * 账号编号
+ */
+ @ApiModelProperty(value = "账号编号")
+ private Integer accountId;
+ /**
+ * 应用名
+ */
+ @ApiModelProperty(value = "应用名")
+ private String applicationName;
+ /**
+ * 访问地址
+ */
+ @ApiModelProperty(value = "访问地址")
+ private String uri;
+ /**
+ * 参数
+ */
+ @ApiModelProperty(value = "参数")
+ private String params;
+ /**
+ * http 方法
+ */
+ @ApiModelProperty(value = "http 方法")
+ private String method;
+ /**
+ * userAgent
+ */
+ @ApiModelProperty(value = "userAgent")
+ private String userAgent;
+ /**
+ * ip
+ */
+ @ApiModelProperty(value = "ip")
+ private String ip;
+ /**
+ * 请求时间
+ */
+ @ApiModelProperty(value = "请求时间")
+ private LocalDateTime startTime;
+ /**
+ * 响应时长 -- 毫秒级
+ */
+ @ApiModelProperty(value = "响应时长 -- 毫秒级")
+ private Integer responseTime;
+ /**
+ * 日志消息
+ */
+ @ApiModelProperty(value = "日志消息")
+ private String msg;
+ /**
+ * 操作状态
+ */
+ @ApiModelProperty(value = "操作状态")
+ private Integer status;
+ /**
+ * 创建者
+ */
+ @ApiModelProperty(value = "创建者")
+ private String operator;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/po/OperationLogPO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/po/OperationLogPO.java
new file mode 100644
index 000000000..a6e348630
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/model/po/OperationLogPO.java
@@ -0,0 +1,89 @@
+package cn.iocoder.mall.system.biz.log.operation.model.po;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 操作日志
+ *
+ * @author hccake
+ * @date 2020-05-15 15:12:53
+ */
+@Data
+@TableName("operation_log")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "操作日志")
+public class OperationLogPO extends Model {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 编号
+ */
+ @TableId
+ private Integer id;
+ /**
+ * 链路追踪编号
+ */
+ private String traceId;
+ /**
+ * 账号编号
+ */
+ private Integer accountId;
+ /**
+ * 应用名
+ */
+ private String applicationName;
+ /**
+ * 访问地址
+ */
+ private String uri;
+ /**
+ * 参数
+ */
+ private String params;
+ /**
+ * http 方法
+ */
+ private String method;
+ /**
+ * userAgent
+ */
+ private String userAgent;
+ /**
+ * ip
+ */
+ private String ip;
+ /**
+ * 请求时间
+ */
+ private LocalDateTime startTime;
+ /**
+ * 响应时长 -- 毫秒级
+ */
+ private Integer responseTime;
+ /**
+ * 日志消息
+ */
+ private String msg;
+ /**
+ * 操作状态
+ */
+ private Integer status;
+ /**
+ * 创建者
+ */
+ private String operator;
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/service/OperationLogSaveService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/service/OperationLogSaveService.java
new file mode 100644
index 000000000..159d85691
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/log/operation/service/OperationLogSaveService.java
@@ -0,0 +1,20 @@
+package cn.iocoder.mall.system.biz.log.operation.service;
+
+
+import cn.iocoder.mall.system.biz.log.operation.model.dto.OperationLogDTO;
+
+/**
+ * 操作日志业务类
+ * @author Hccake
+ * @version 1.0
+ * @date 2019/10/15 19:57
+ */
+public interface OperationLogSaveService {
+
+ /**
+ * 保存操作日志
+ * @param operationLogDTO
+ * @return true/false
+ */
+ boolean saveLog(OperationLogDTO operationLogDTO);
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeService.java
index 9a355de6e..d69a5ee39 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeService.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeService.java
@@ -1,5 +1,6 @@
package cn.iocoder.mall.system.biz.service.errorcode;
+import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.errorcode.ErrorCodeBO;
import cn.iocoder.mall.system.biz.dataobject.errorcode.ErrorCodeDO;
@@ -53,6 +54,13 @@ public interface ErrorCodeService extends IService{
*/
Boolean addErrorCodeList(List list);
+ /**
+ * 批量添加错误码信息,项目启动时初始化错误码信息。
+ * @param enumerable 错误码枚举类
+ * @return 是否成功
+ */
+ Boolean addSystemErrorCodeList(ServiceExceptionUtil.Enumerable[] enumerable);
+
/**
* 更新错误码,系统内置错误码是不允许更新
* @param errorCodeUpdateDTO 错误码信息
@@ -64,4 +72,10 @@ public interface ErrorCodeService extends IService{
* @param errorCodeDeleteDTO 只允许删除自定义错误码
*/
void deleteErrorCode(ErrorCodeDeleteDTO errorCodeDeleteDTO);
+
+ /**
+ * 删除分组下的错误码,只提供给服务初始化时候
+ * @param group 分组
+ */
+ void deleteSyStemErrorCode(int group);
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeServiceImpl.java
index c41404780..ad1dffaa9 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeServiceImpl.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/errorcode/ErrorCodeServiceImpl.java
@@ -85,6 +85,21 @@ public class ErrorCodeServiceImpl extends ServiceImpl doList = new ArrayList<>();
+ for (ServiceExceptionUtil.Enumerable errorCodeEnum : enumerable){
+ ErrorCodeDO errorCode = new ErrorCodeDO().setCode(errorCodeEnum.getCode()).
+ setMessage(errorCodeEnum.getMessage()).setType(ErrorCodeTypeEnum.SYSTEM.getType())
+ .setGroup(errorCodeEnum.getGroup());
+ errorCode.setCreateTime(new Date());
+ errorCode.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
+ doList.add(errorCode);
+ }
+ // TODO 插入操作日志
+ return this.saveBatch(doList);
+ }
+
@Override
public void updateErrorCode(ErrorCodeUpdateDTO errorCodeUpdateDTO) {
// 校验错误码是否存在
@@ -118,8 +133,12 @@ public class ErrorCodeServiceImpl extends ServiceImpl mobileList, String sign, String templateCode,
String template, Map templateParams) {
-
// 最大发送数为 1000,我们设置为 500 个, 分段发送
int maxSendSize = MAX_BATCH_SIZE;
int maxSendSizeCount = mobileList.size() % maxSendSize == 0
? mobileList.size() / maxSendSize
: mobileList.size() / maxSendSize + 1;
-
+ // 处理批量
SendResult sendResult = null;
for (int i = 0; i < maxSendSizeCount; i++) {
// 分批发送
List batchSendMobile = mobileList
.subList(i * maxSendSize, (i + 1) * maxSendSize);
-
// params
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
@@ -111,7 +108,6 @@ public class AliYunSmsClient implements SmsClient {
request.putQueryParameter("SignNameJson", JSON.toJSONString(Collections.singletonList(sign)));
request.putQueryParameter("TemplateCode", templateCode);
request.putQueryParameter("TemplateParamJson", JSON.toJSONString(Collections.singletonList(templateParams)));
-
// 发送请求
sendResult = doSend(request);
}
@@ -125,9 +121,7 @@ public class AliYunSmsClient implements SmsClient {
CommonResponse response = client.getCommonResponse(request);
Result result = JSON.parseObject(response.getData(), Result.class);
if (!SUCCESS_CODE.equals(result.getCode())) {
-
LOGGER.info("发送验证码失败 params {} res {}", JSON.toJSON(request), JSON.toJSON(result));
-
// 错误发送失败
return new SendResult()
.setIsSuccess(false)
@@ -135,7 +129,6 @@ public class AliYunSmsClient implements SmsClient {
.setMessage(result.getMessage());
} else {
LOGGER.info("发送验证码失败 params {} res", JSON.toJSON(request), JSON.toJSON(result));
-
// 发送成功
return new SendResult()
.setIsSuccess(true)
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java
index 83ce9159a..820650686 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java
@@ -23,6 +23,7 @@ import cn.iocoder.mall.system.biz.dto.smsTemplate.ListSmsTemplateDTO;
import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum;
import cn.iocoder.mall.system.biz.enums.sms.SmsApplyStatusEnum;
import cn.iocoder.mall.system.biz.enums.sms.SmsPlatformEnum;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -70,16 +71,14 @@ public class SmsServiceImpl implements SmsService {
@Override
public PageResult listSmsTemplate(ListSmsTemplateDTO listSmsTemplateDTO) {
+ // 获取 template
IPage signPage = smsTemplateMapper.listSmsTemplate(listSmsTemplateDTO);
-
- List templateList
- = SmsTemplateConvert.INSTANCE.convert(signPage.getRecords());
-
- if (CollectionUtils.isEmpty(templateList)) {
+ if (CollectionUtils.isEmpty(signPage.getRecords())) {
// TODO DOME FROM 芋艿 to 小范,Collections.EMPTY_LIST =》Collections.emptyList();另外,可以考虑直接 Convert 哈
return new PageResult().setList(Collections.emptyList()).setTotal(signPage.getTotal());
}
-
+ // 转换bo
+ List templateList = SmsTemplateConvert.INSTANCE.convert(signPage.getRecords());
// 获取 sign
Set smsSignIds = templateList.stream().map(
ListSmsTemplateBO::getSmsSignId).collect(Collectors.toSet());
@@ -88,37 +87,32 @@ public class SmsServiceImpl implements SmsService {
new QueryWrapper().in("id", smsSignIds));
List signList = SmsTemplateConvert.INSTANCE.convertTemplateSign(smsSignDOList);
-
+ // sign 转换为 map
Map smsSignDOMap = signList
.stream().collect(Collectors.toMap(ListSmsTemplateBO.Sign::getId, o -> o));
-
// 设置 sign
-
templateList.forEach(template -> {
if (smsSignDOMap.containsKey(template.getSmsSignId())) {
template.setSign(smsSignDOMap.get(template.getSmsSignId()));
}
});
-
return new PageResult().setList(templateList).setTotal(signPage.getTotal());
}
@Override
@Transactional
public void addSign(AddSignDTO addSignDTO) {
-
// 避免重复
SmsSignDO smsSignDO = smsSignMapper.selectOne(
new QueryWrapper()
.eq("platform", addSignDTO.getPlatform())
.eq("sign", addSignDTO.getSign())
);
-
+ // 处理 null 情况
if (smsSignDO != null) {
// TODO DOME FROM 芋艿 to 小范:可以使用 ServiceExceptionUtil.exception(SystemErrorCodeEnum.SMS_SIGN_IS_EXISTENT);
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.SMS_SIGN_IS_EXISTENT);
}
-
// 保存数据库
smsSignMapper.insert(
(SmsSignDO) new SmsSignDO()
@@ -133,16 +127,17 @@ public class SmsServiceImpl implements SmsService {
@Override
public SmsSignBO getSign(Integer signId) {
+ // 查询数据库
SmsSignDO smsSignDO = smsSignMapper.selectOne(
new QueryWrapper()
.eq("id", signId)
.eq("deleted", DeletedStatusEnum.DELETED_NO.getValue()));
-
+ // 处理 null
if (smsSignDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
+ // 转换vo返回
return SmsSignConvert.INSTANCE.convert(smsSignDO);
}
@@ -154,12 +149,11 @@ public class SmsServiceImpl implements SmsService {
new QueryWrapper()
.eq("sign", updateSignDTO.getSign())
.eq("platform", updateSignDTO.getPlatform()));
-
+ // 处理 null
if (smsSignDO != null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getMessage());
}
-
// 更新
smsSignMapper.update(
(SmsSignDO) new SmsSignDO()
@@ -172,15 +166,13 @@ public class SmsServiceImpl implements SmsService {
@Override
public void deleteSign(Integer id) {
- SmsSignDO smsSignDO = smsSignMapper.selectOne(
- new QueryWrapper()
- .eq("id", id));
-
+ // 根据id查询
+ SmsSignDO smsSignDO = smsSignMapper.selectById(id);
+ // 处理 null
if (smsSignDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
// 更新 deleted 为 YES
smsSignMapper.delete(new UpdateWrapper()
.set("deleted", DeletedStatusEnum.DELETED_YES.getName())
@@ -192,15 +184,13 @@ public class SmsServiceImpl implements SmsService {
@Transactional
public void addTemplate(Integer smsSignId, String templateCode,
String template, Integer platform, Integer smsType) {
-
- SmsSignDO smsSignDO = smsSignMapper.selectOne(
- new QueryWrapper().eq("id", smsSignId));
-
+ // 根据id查询
+ SmsSignDO smsSignDO = smsSignMapper.selectById(smsSignId);
+ // 处理 null
if (smsSignDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
// 保存数据库
smsTemplateMapper.insert(
(SmsTemplateDO) new SmsTemplateDO()
@@ -219,16 +209,17 @@ public class SmsServiceImpl implements SmsService {
@Override
public SmsTemplateBO getTemplate(Integer id, Integer platform) {
+ // 获取数据
SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
new QueryWrapper()
.eq("platform", platform)
.eq("id", id));
-
+ // 处理 null
if (smsTemplateDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
}
-
+ // 转换bo返回
return SmsTemplateConvert.INSTANCE.convert(smsTemplateDO);
}
@@ -236,22 +227,20 @@ public class SmsServiceImpl implements SmsService {
@Transactional
public void updateTemplate(Integer id, Integer smsSignId, String templateCode,
String template, Integer platform, Integer smsType) {
- SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
- new QueryWrapper().eq("id", id));
-
+ // 获取 template
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(id);
if (smsTemplateDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
}
-
+ // 获取 sign
SmsSignDO smsSignDO = smsSignMapper.selectOne(
new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
-
if (smsSignDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
+ // 更新数据库
smsTemplateMapper.update(
(SmsTemplateDO) new SmsTemplateDO()
.setSmsSignId(smsSignId)
@@ -269,13 +258,12 @@ public class SmsServiceImpl implements SmsService {
public void deleteTemplate(Integer id) {
SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
new QueryWrapper().eq("id", id));
-
+ // 处理不存在情况
if (smsTemplateDO == null
|| smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
throw new ServiceException(SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
}
-
// 删除 数据库模板
SmsTemplateDO updateTemplate =new SmsTemplateDO();
updateTemplate.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
@@ -287,29 +275,24 @@ public class SmsServiceImpl implements SmsService {
@Override
public void singleSend(String mobile, Integer smsTemplateId, Map params) {
- SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
- new QueryWrapper().eq("id", smsTemplateId));
-
+ // 获取 template
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(smsTemplateId);
if (smsTemplateDO == null
|| smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
throw new ServiceException(SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
}
-
- SmsSignDO smsSignDO = smsSignMapper.selectOne(
- new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
-
+ // 获取 sign
+ SmsSignDO smsSignDO = smsSignMapper.selectById(smsTemplateDO.getSmsSignId());
if (smsSignDO == null) {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
// 获取 client
SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform());
// 发送短信
SmsClient.SendResult sendResult = smsClient.singleSend(mobile, smsSignDO.getSign(),
smsTemplateDO.getTemplateCode(), smsTemplateDO.getTemplate(), params);
-
// 添加日志
smsSendMapper.insert(
(SmsSendLogDO) new SmsSendLogDO()
@@ -322,18 +305,15 @@ public class SmsServiceImpl implements SmsService {
@Override
public void batchSend(List mobileList, Integer smsTemplateId, Map params) {
- SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
- new QueryWrapper().eq("id", smsTemplateId));
-
+ // 获取 template
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(smsTemplateId);
if (smsTemplateDO == null
|| smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
throw new ServiceException(SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
}
-
- SmsSignDO smsSignDO = smsSignMapper.selectOne(
- new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
-
+ // 获取 sign
+ SmsSignDO smsSignDO = smsSignMapper.selectById(smsTemplateDO.getSmsSignId());
if (smsSignDO == null) {
// 添加日志
smsSendMapper.insert(
@@ -347,14 +327,11 @@ public class SmsServiceImpl implements SmsService {
throw new ServiceException(SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
SystemErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
}
-
// 获取 client
SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform());
-
// 发送短信
SmsClient.SendResult sendResult = smsClient.batchSend(mobileList, smsSignDO.getSign(),
smsTemplateDO.getTemplateCode(), smsTemplateDO.getTemplate(), params);
-
// 添加日志
smsSendMapper.insert(
(SmsSendLogDO) new SmsSendLogDO()
@@ -373,18 +350,18 @@ public class SmsServiceImpl implements SmsService {
*/
private SmsClient getSmsClient(Integer platform) {
SmsClient smsClient = null;
+ // 阿里云和云片
if (SmsPlatformEnum.YunPian.getValue().equals(platform)) {
smsClient = smsYunPianClient;
} else if (SmsPlatformEnum.AliYun.getValue().equals(platform)) {
smsClient = smsAliYunClient;
}
-
+ // 没有支持的平台
if (smsClient == null) {
throw new ServiceException(
SystemErrorCodeEnum.SMS_NOT_SEND_CLIENT.getCode(),
SystemErrorCodeEnum.SMS_NOT_SEND_CLIENT.getMessage());
}
-
return smsClient;
}
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/YunPianSmsClient.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/YunPianSmsClient.java
index b1778ff16..749264bb2 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/YunPianSmsClient.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/YunPianSmsClient.java
@@ -88,7 +88,6 @@ public class YunPianSmsClient implements SmsClient {
*/
private static final String URL_SEND_BATCH = "https://sms.yunpian.com/v2/sms/batch_send.json";
-
//编码格式。发送编码格式统一用UTF-8
private static String ENCODING = "UTF-8";
@@ -99,7 +98,6 @@ public class YunPianSmsClient implements SmsClient {
public SendResult singleSend(String mobile, String sign, String templateCode, String template, Map templateParams) {
// build 模板
template = buildTemplate(sign, template, templateParams);
-
// 请求参数
Map params = new LinkedHashMap<>();
params.put("apikey", apiKey);
@@ -114,7 +112,7 @@ public class YunPianSmsClient implements SmsClient {
throw new ServiceException(SystemErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
jsonObject.getString("detail"));
}
-
+ // 转换 result
return new SendResult()
.setIsSuccess(SUCCESS_CODE == jsonObject.getInteger("code"))
.setCode(jsonObject.getInteger("code"))
@@ -127,7 +125,6 @@ public class YunPianSmsClient implements SmsClient {
Map templateParams) {
// build 模板
template = buildTemplate(sign, template, templateParams);
-
// 最大发送数为 1000,我们设置为 500 个, 分段发送
int maxSendSize = MAX_BATCH_SIZE;
int maxSendSizeCount = mobileList.size() % maxSendSize == 0
@@ -142,9 +139,7 @@ public class YunPianSmsClient implements SmsClient {
sendMobileStr.append(",");
sendMobileStr.append(mobileList.get(k));
}
-
String dividedMobile = sendMobileStr.toString().substring(1);
-
// 发送手机号
Map params = new LinkedHashMap<>();
params.put("apikey", apiKey);
@@ -159,12 +154,10 @@ public class YunPianSmsClient implements SmsClient {
throw new ServiceException(SystemErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
jsonObject.getString("detail"));
}
-
// 用于递增 maxSendSize
j = j2;
j2 = j + maxSendSize;
}
-
return new SendResult()
.setIsSuccess(true)
.setCode(SUCCESS_CODE)
@@ -181,18 +174,17 @@ public class YunPianSmsClient implements SmsClient {
*/
private static String buildTemplate(String sign, String template,
Map templateParams) {
-
+ // 不处理 empty 数据
if (CollectionUtils.isEmpty(templateParams)) {
return template;
}
-
+ // 处理template参数
for (Map.Entry entry : templateParams.entrySet()) {
String paramsKey = entry.getKey();
String value = entry.getValue();
String paramPlace = String.format(PARAM_TEMPLATE, paramsKey);
template = template.replaceAll(paramPlace, value);
}
-
template = String.format(SIGN_TEMPLATE, sign, template);
return template;
}
@@ -234,7 +226,6 @@ public class YunPianSmsClient implements SmsClient {
e.printStackTrace();
}
}
-
LOGGER.debug("云片短信平台 res: {}", responseText);
return responseText;
}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/systemlog/SystemLogServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/systemlog/SystemLogServiceImpl.java
index 85c86f71d..769f4e5c2 100644
--- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/systemlog/SystemLogServiceImpl.java
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/systemlog/SystemLogServiceImpl.java
@@ -48,7 +48,7 @@ public class SystemLogServiceImpl implements SystemLogService {
@SuppressWarnings("Duplicates")
public PageResult getAccessLogPage(AccessLogPageDTO accessLogPageDTO) {
PageResult accessLogPageBOPageResult = SystemLogConvert.INSTANCE.convertPage(
- accessLogMapper.selectPage(accessLogPageDTO));
+ accessLogMapper.selectPage(accessLogPageDTO)); // TODO FROM 芋艿 to 2447007062:可以考虑直接 return,简洁 + IDEA 不告警;
return accessLogPageBOPageResult;
}
}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/systemlog/SystemLogController.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/systemlog/SystemLogController.java
index 5f7a1d471..096fa19ec 100644
--- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/systemlog/SystemLogController.java
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/systemlog/SystemLogController.java
@@ -41,7 +41,8 @@ public class SystemLogController {
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
-
+ // TODO FROM 芋艿 to 2447007062:不要留这么大的空行;
+ // TODO FROM 芋艿 to 2447007062:使用 Request 接收参数噢;
AccessLogPageDTO accessLogPageDTO = new AccessLogPageDTO().setAccountId(accountId)
.setPageNo(pageNo).setPageSize(pageSize);
// 查询分页
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/systemlog/AccessLogConvert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/systemlog/AccessLogConvert.java
index a07b36c4e..e5f20cf7b 100644
--- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/systemlog/AccessLogConvert.java
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/systemlog/AccessLogConvert.java
@@ -19,7 +19,7 @@ public interface AccessLogConvert {
AccessLogConvert INSTANCE = Mappers.getMapper(AccessLogConvert.class);
- @Mappings({})
+ @Mappings({}) // TODO FROM 芋艿 to 2447007062:注意空行哟;另外,如果不需要专门 mapping,可以不添加该注解,嘿嘿。
PageResult convert(PageResult result);
diff --git a/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/enums/UserErrorCodeEnum.java b/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/enums/UserErrorCodeEnum.java
index 6a8279aba..10ce8d339 100644
--- a/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/enums/UserErrorCodeEnum.java
+++ b/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/enums/UserErrorCodeEnum.java
@@ -35,4 +35,9 @@ public enum UserErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
return message;
}
+ @Override
+ public int getGroup() {
+ return 0;
+ }
+
}
diff --git a/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/service/user/UserAddressServiceImpl.java b/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/service/user/UserAddressServiceImpl.java
index 90627bc28..dee915614 100644
--- a/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/service/user/UserAddressServiceImpl.java
+++ b/user/user-biz/src/main/java/cn/iocoder/mall/user/biz/service/user/UserAddressServiceImpl.java
@@ -32,12 +32,10 @@ public class UserAddressServiceImpl implements UserAddressService {
@Override
@Transactional
public void addAddress(UserAddressAddDTO userAddressAddDTO) {
-
// 转换do,设置默认数据
UsersUserAddressDO userAddressDO = UserAddressConvert.INSTANCE.convert(userAddressAddDTO);
userAddressDO.setCreateTime(new Date());
userAddressDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
-
// 检查是否设置为默认地址
if (UserAddressHasDefaultEnum.DEFAULT_ADDRESS_YES.getValue() == userAddressAddDTO.getHasDefault()) {
UsersUserAddressDO defaultUserAddress = userAddressMapper.selectHasDefault(userAddressAddDTO.getUserId());
@@ -49,7 +47,6 @@ public class UserAddressServiceImpl implements UserAddressService {
);
}
}
-
// 保存地址
userAddressMapper.insert(userAddressDO);
}
@@ -57,19 +54,15 @@ public class UserAddressServiceImpl implements UserAddressService {
@Override
@Transactional
public void updateAddress(UserAddressUpdateDTO userAddressAddDTO) {
-
// 检查地址
UsersUserAddressDO userAddress = userAddressMapper.selectById(userAddressAddDTO.getId());
-
if (userAddress == null) {
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.USER_ADDRESS_NOT_EXISTENT.getCode());
}
-
// 删除的地址不能更新
if (DeletedStatusEnum.DELETED_YES.getValue().equals(userAddress.getDeleted())) {
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.USER_ADDRESS_IS_DELETED.getCode());
}
-
// 检查是否设置为默认地址
// 是:将数据库 default address 设置为 no
if (UserAddressHasDefaultEnum.DEFAULT_ADDRESS_YES.getValue() == userAddressAddDTO.getHasDefault()) {
@@ -82,7 +75,6 @@ public class UserAddressServiceImpl implements UserAddressService {
);
}
}
-
// 转换 vo, 并保存数据
UsersUserAddressDO userAddressDO = UserAddressConvert.INSTANCE.convert(userAddressAddDTO);
userAddressDO.setUpdateTime(new Date());
@@ -93,16 +85,13 @@ public class UserAddressServiceImpl implements UserAddressService {
public void removeAddress(Integer userId, Integer addressId) {
// checked address is exists.
UsersUserAddressDO userAddress = userAddressMapper.selectById(addressId);
-
if (userAddress == null) {
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.USER_ADDRESS_NOT_EXISTENT.getCode());
}
-
if (DeletedStatusEnum.DELETED_YES.getValue().equals(userAddress.getDeleted())) {
// skip
return;
}
-
// 更新状态为 remove
userAddressMapper.updateById(
(UsersUserAddressDO) new UsersUserAddressDO()
diff --git a/user/user-rpc/src/main/java/cn/iocoder/mall/user/rpc/convert/user/UserAddressRPCConvert.java b/user/user-rpc/src/main/java/cn/iocoder/mall/user/rpc/convert/user/UserAddressRPCConvert.java
index 6bda9b153..16056e749 100644
--- a/user/user-rpc/src/main/java/cn/iocoder/mall/user/rpc/convert/user/UserAddressRPCConvert.java
+++ b/user/user-rpc/src/main/java/cn/iocoder/mall/user/rpc/convert/user/UserAddressRPCConvert.java
@@ -3,7 +3,6 @@ package cn.iocoder.mall.user.rpc.convert.user;
import cn.iocoder.mall.user.biz.bo.user.UserAddressBO;
import cn.iocoder.mall.user.rpc.response.user.UserAddressResponse;
import org.mapstruct.Mapper;
-import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
/**
@@ -17,7 +16,6 @@ public interface UserAddressRPCConvert {
UserAddressRPCConvert INSTANCE = Mappers.getMapper(UserAddressRPCConvert.class);
- // TODO DONE FROM 芋艿 to 小范:如果不用映射,可以不用 @Mappings 哈
- @Mappings({})
UserAddressResponse convert(UserAddressBO userAddressBO);
+
}