diff --git a/mobile-web/src/config/env.js b/mobile-web/src/config/env.js
index aab5a5714..cd3425bf5 100644
--- a/mobile-web/src/config/env.js
+++ b/mobile-web/src/config/env.js
@@ -19,8 +19,8 @@ if (process.env.NODE_ENV == 'development') {
// baseUrl = 'http://127.0.0.1';
// baseUrl = 'http://180.167.213.26:18099';
-dataSources = 'remote';
-// dataSources = 'local';
+// dataSources = 'remote';
+dataSources = 'local';
export {
baseUrl,
diff --git a/mobile-web/src/page/page/index.vue b/mobile-web/src/page/page/index.vue
index d301292dc..46d84d550 100644
--- a/mobile-web/src/page/page/index.vue
+++ b/mobile-web/src/page/page/index.vue
@@ -1,6 +1,10 @@
diff --git a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/mock/ProductSpuServiceMock.java b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/mock/ProductSpuServiceMock.java
index fc72c309c..57948956e 100644
--- a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/mock/ProductSpuServiceMock.java
+++ b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/mock/ProductSpuServiceMock.java
@@ -2,12 +2,16 @@ package cn.iocoder.mall.order.biz.mock;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.product.api.ProductSpuService;
+import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
+import java.util.Collection;
+import java.util.List;
+
/**
* @author Sin
* @time 2019-03-24 15:24
@@ -37,4 +41,9 @@ public class ProductSpuServiceMock implements ProductSpuService {
public CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) {
return null;
}
+
+ @Override
+ public CommonResult> getProductSpuList(Collection ids) {
+ return null;
+ }
}
diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java
index 845a7b1c4..c23675ba3 100644
--- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java
+++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java
@@ -1,12 +1,16 @@
package cn.iocoder.mall.product.api;
import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
+import java.util.Collection;
+import java.util.List;
+
public interface ProductSpuService {
CommonResult getProductSpu(Integer id);
@@ -19,4 +23,6 @@ public interface ProductSpuService {
CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
+ CommonResult> getProductSpuList(Collection ids);
+
}
\ No newline at end of file
diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java
index 67973c1b8..4428dd9ce 100644
--- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java
+++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java
@@ -4,6 +4,7 @@ import cn.iocoder.mall.product.dataobject.ProductSpuDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
+import java.util.Collection;
import java.util.List;
@Repository
@@ -11,6 +12,8 @@ public interface ProductSpuMapper {
ProductSpuDO selectById(Integer id);
+ List selectByIds(Collection ids);
+
void insert(ProductSpuDO productSpuDO);
void update(ProductSpuDO productSpuDO);
diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java
index cf394f9d1..f95b7bcb3 100644
--- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java
+++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java
@@ -7,6 +7,7 @@ import cn.iocoder.common.framework.util.StringUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.product.api.ProductSpuService;
import cn.iocoder.mall.product.api.bo.ProductAttrAndValuePairBO;
+import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
@@ -212,6 +213,19 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return CommonResult.success(productSpuPage);
}
+ @Override
+ public CommonResult> getProductSpuList(Collection ids) {
+ List spus = productSpuMapper.selectByIds(ids);
+ return CommonResult.success(ProductSpuConvert.INSTANCE.convert(spus));
+ }
+
+ /**
+ * 校验 sku 是否合法
+ *
+ * @param productSkuAddDTOs sku 添加或修改信息
+ * @param productAttrDetailBOs 商品规格明细数组
+ * @return 是否校验通过
+ */
private CommonResult validProductSku(List productSkuAddDTOs, List productAttrDetailBOs) {
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
Map productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
@@ -241,6 +255,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return CommonResult.success(true);
}
+ /**
+ * 获得 sku 数组中,指定规格的 sku
+ *
+ * @param attrs 指定规格
+ * @param skus sku 数组
+ * @return 符合条件的 sku
+ */
private ProductSkuDO findProductSku(Collection attrs, List skus) {
if (CollectionUtil.isEmpty(skus)) {
return null;
@@ -256,6 +277,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return null;
}
+ /**
+ * 根据 sku 数组,计算相关的字段到 spu 中。
+ *
+ * @param spu spu
+ * @param skus sku 数组
+ */
private void initSpuFromSkus(ProductSpuDO spu, List skus) {
assert skus.size() > 0; // 写个断言,避免下面警告
spu.setPrice(skus.stream().min(Comparator.comparing(ProductSkuAddOrUpdateDTO::getPrice)).get().getPrice()); // 求最小价格
diff --git a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml
index 918049ff1..7b0d3724d 100644
--- a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml
+++ b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml
@@ -16,6 +16,17 @@
AND deleted = 0
+
+
INSERT INTO product_spu (
name, sell_point, description, cid, pic_urls,
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java
new file mode 100644
index 000000000..7e2dbd873
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java
@@ -0,0 +1,53 @@
+package cn.iocoder.mall.promotion.application.controller.users;
+
+import cn.iocoder.common.framework.constant.CommonStatusEnum;
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.product.api.ProductSpuService;
+import cn.iocoder.mall.product.api.bo.ProductSpuBO;
+import cn.iocoder.mall.promotion.api.ProductRecommendService;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
+import cn.iocoder.mall.promotion.application.convert.ProductRecommendConvert;
+import cn.iocoder.mall.promotion.application.vo.users.UsersProductRecommendVO;
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("users/banner")
+@Api("商品推荐模块")
+public class UsersProductRecommendController {
+
+ @Reference(validation = "true")
+ private ProductRecommendService productRecommendService;
+ @Reference(validation = "true")
+ private ProductSpuService productSpuService;
+
+ @GetMapping("/list")
+ @ApiOperation("获得所有 Banner 列表")
+ public CommonResult> list() {
+ // 查询商品推荐列表
+ List productRecommends = productRecommendService.getProductRecommendList(
+ null, CommonStatusEnum.ENABLE.getValue()).getData();
+ // 获得商品集合
+ List spus = productSpuService.getProductSpuList(
+ productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet())).getData();
+ Map spuMap = spus.stream().collect(Collectors.toMap(ProductSpuBO::getId, account -> account));
+ // 组合结果,返回
+ Multimap result = new HashMultimap<>();
+ productRecommends.sort(Comparator.comparing(ProductRecommendBO::getSort)); // 排序,按照 sort 升序
+ productRecommends.forEach(productRecommendBO -> result.put(productRecommendBO.getType(),
+ ProductRecommendConvert.INSTANCE.convert(spuMap.get(productRecommendBO.getProductSpuId())))); // 将 ProductSpuBO 添加到 results 中
+ return CommonResult.success(result);
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
index 2c04fec01..7ba9acbdd 100644
--- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
@@ -1,10 +1,12 @@
package cn.iocoder.mall.promotion.application.convert;
import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
import cn.iocoder.mall.promotion.api.bo.ProductRecommendPageBO;
import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendPageVO;
import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendVO;
+import cn.iocoder.mall.promotion.application.vo.users.UsersProductRecommendVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@@ -23,7 +25,10 @@ public interface ProductRecommendConvert {
@Mappings({})
CommonResult convert(CommonResult result);
-// @Mappings({})
-// List convertList(List banners);
+ @Mappings({})
+ UsersProductRecommendVO convert(ProductSpuBO productSpu);
+
+ // @Mappings({})
+ // List convertList(List banners);
}
\ No newline at end of file
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersProductRecommendVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersProductRecommendVO.java
new file mode 100644
index 000000000..d4fadd729
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersProductRecommendVO.java
@@ -0,0 +1,75 @@
+package cn.iocoder.mall.promotion.application.vo.users;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+@ApiModel(value = "商品推荐 VO", description = "不包括 SKU 信息 VO")
+public class UsersProductRecommendVO {
+
+ @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
+ private Integer id;
+
+ // ========== 基本信息 =========
+ @ApiModelProperty(value = "SPU 名字", required = true, example = "厮大牛逼")
+ private String name;
+ @ApiModelProperty(value = "卖点", required = true, example = "各种 MQ 骚操作")
+ private String sellPoint;
+ @ApiModelProperty(value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn")
+ private List picUrls;
+
+ // ========== Sku 相关字段 =========
+ /**
+ * 价格
+ *
+ * 目前的计算方式是,以 Sku 最小价格为准
+ */
+ private Integer price;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public UsersProductRecommendVO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public UsersProductRecommendVO setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getSellPoint() {
+ return sellPoint;
+ }
+
+ public UsersProductRecommendVO setSellPoint(String sellPoint) {
+ this.sellPoint = sellPoint;
+ return this;
+ }
+
+ public List getPicUrls() {
+ return picUrls;
+ }
+
+ public UsersProductRecommendVO setPicUrls(List picUrls) {
+ this.picUrls = picUrls;
+ return this;
+ }
+
+ public Integer getPrice() {
+ return price;
+ }
+
+ public UsersProductRecommendVO setPrice(Integer price) {
+ this.price = price;
+ return this;
+ }
+
+}
\ No newline at end of file