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