Authored by unknown

Merge branch 'master' into wn_photoSearch

package com.yoho.search.dal;
import com.yoho.search.dal.model.Goods;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
import com.yoho.search.dal.model.Goods;
public interface GoodsMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -21,15 +21,11 @@ public interface GoodsMapper {
List<Goods> selectPageLists(@Param(value="offset")Integer offset, @Param(value="pageSize")Integer pageSize);
List<Goods> selectByIdsAndStatus(List<Integer> ids);
List<Map<String, Object>> selectGoodListByProductId(Integer productId);
List<Goods> selectValidListByProductIds(List<Integer> productIds);
List<Goods> selectListByProductIds(List<Integer> productIds);
List<Integer> selectIdByProductIds(List<Integer> ids);
List<Goods> selectListByGoodsIds(List<Integer> ids);
List<Goods> selectListByGoodsIds(List<Integer> goodsIds);
int selectCount();
}
\ No newline at end of file
... ...
package com.yoho.search.dal;
import com.yoho.search.dal.model.ProductColors;
import java.util.List;
/**
* Created by wangnan on 2016/11/10.
*/
public interface ProductColorsMapper {
List<ProductColors> selectProductColors(List<Integer> ids);
}
package com.yoho.search.dal;
import com.yoho.search.dal.model.ProductSizes;
import java.util.List;
/**
* Created by wangnan on 2016/11/10.
*/
public interface ProductSizesMapper {
List<ProductSizes> selectProductSizes(List<Integer> ids);
}
package com.yoho.search.dal.model;
/**
* Created by wangnan on 2016/6/29.
*/
public class ProductColors {
private Integer productId;
private String colorIds;
private String colorNames;
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getColorIds() {
return colorIds;
}
public void setColorIds(String colorIds) {
this.colorIds = colorIds;
}
public String getColorNames() {
return colorNames;
}
public void setColorNames(String colorNames) {
this.colorNames = colorNames;
}
}
package com.yoho.search.dal.model;
/**
* Created by wangnan on 2016/6/30.
*/
public class ProductSizes {
protected Integer productId;
protected Integer storageNum;
protected String sizeIds;
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getSizeIds() {
return sizeIds;
}
public void setSizeIds(String sizeIds) {
this.sizeIds = sizeIds;
}
public Integer getStorageNum() {
return storageNum;
}
public void setStorageNum(Integer storageNum) {
this.storageNum = storageNum;
}
}
... ... @@ -242,19 +242,6 @@
<include refid="Base_Column_List"/>
from goods limit #{offset},#{pageSize}
</select>
<select id="selectGoodListByProductId" resultMap="goodsResultMap"
parameterType="java.lang.Integer" timeout="20000">
<![CDATA[
SELECT a.id,a.product_id,a.color_id,a.color_name,a.color_image,a.is_default,a.product_skc,b.color_code,a.status,c.cover_1,c.cover_2
FROM goods a LEFT JOIN product_color b ON a.`color_id`=b.`id` LEFT JOIN
(SELECT a.goods_id,GROUP_CONCAT(CASE a.gender_cover WHEN 1 THEN a.image_url END) AS cover_1,GROUP_CONCAT(CASE a.gender_cover WHEN 2 THEN a.image_url END) AS cover_2
FROM goods_images a WHERE (a.gender_cover <> 0) GROUP BY a.`goods_id`) c ON a.id = c.goods_id WHERE a.product_id=#{productId,jdbcType=INTEGER}
]]>
</select>
<resultMap id="ids" type="Integer">
<result column="id" property="Id" jdbcType="INTEGER"/>
</resultMap>
<select id="selectListByProductIds" resultMap="BaseResultMap"
parameterType="java.lang.Integer" timeout="20000">
select
... ... @@ -266,8 +253,7 @@
#{item}
</foreach>
</select>
<select id="selectByIdsAndStatus" resultMap="BaseResultMap"
parameterType="java.lang.Integer" timeout="20000">
<select id="selectValidListByProductIds" resultMap="BaseResultMap" parameterType="java.lang.Integer" timeout="20000">
select
<include refid="Base_Column_List"/>
from goods
... ... @@ -278,19 +264,6 @@
#{item}
</foreach>
</select>
<resultMap id="selectIdByProductIdsMap" type="Integer">
<result column="id" property="Id" jdbcType="INTEGER"/>
</resultMap>
<select id="selectIdByProductIds" resultMap="selectIdByProductIdsMap" timeout="20000">
select id
from goods
WHERE product_id in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
<select id="selectListByGoodsIds" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
... ...
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yoho.search.dal.ProductColorsMapper">
<resultMap id="ProductColors" type="com.yoho.search.dal.model.ProductColors">
<result column="product_id" property="productId" jdbcType="INTEGER"/>
<result column="color_ids" property="colorIds" jdbcType="VARCHAR"/>
<result column="color_names" property="colorNames" jdbcType="VARCHAR"/>
</resultMap>
<select id="selectProductColors" resultMap="ProductColors" timeout="20000">
<![CDATA[
SELECT
`a`.`product_id` AS `product_id`,
group_concat(`a`.`color_id` SEPARATOR ',') AS `color_ids`,
group_concat(
`a`.`color_name` SEPARATOR ','
) AS `color_names`
FROM
`goods` `a` where product_id in]]>
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
GROUP BY
`a`.`product_id`
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yoho.search.dal.ProductSizesMapper">
<resultMap id="ProductSizes" type="com.yoho.search.dal.model.ProductSizes">
<result column="product_id" property="productId" jdbcType="INTEGER"/>
<result column="size_ids" property="sizeIds" jdbcType="VARCHAR"/>
<result column="storage_num" property="storageNum" jdbcType="INTEGER"/>
</resultMap>
<select id="selectProductSizes" resultMap="ProductSizes"
parameterType="java.lang.Integer" timeout="20000">
<![CDATA[
SELECT
`t`.`product_id` AS `product_id`,
group_concat(
DISTINCT `t`.`goods_dimension_id` SEPARATOR ','
) AS `size_ids`,
sum(`t`.`storage_num`) AS `storage_num`
FROM
`storage` `t`
WHERE
`t`.`erp_sku_id` in]]>
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
GROUP BY
`t`.`product_id`
</select>
</mapper>
\ No newline at end of file
... ... @@ -10,68 +10,63 @@ import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSONArray;
import com.yoho.search.consumer.service.base.GoodsService;
import com.yoho.search.consumer.service.bo.ProductGoodsBO;
import com.yoho.search.consumer.service.bo.ProductSizesBO;
import com.yoho.search.consumer.service.logic.productIndex.ProductGoodsLogicService;
import com.yoho.search.consumer.service.logic.productIndex.ProductSizesLogicService;
/**
* Created by ginozhang on 2017/2/8.
* 将库存相关的增量更新代码抽象到父类,被Storage和Goods的MqListener共用。
* Created by ginozhang on 2017/2/8. 将库存相关的增量更新代码抽象到父类,被Storage和Goods的MqListener共用。
*/
public abstract class AbstractStorageRelatedMqListener extends AbstractIndexMqListener {
@Autowired
private GoodsService goodsService;
@Autowired
private ProductGoodsLogicService productGoodsLogicService;
@Autowired
private ProductSizesLogicService productSizesLogicService;
@Autowired
private ProductGoodsLogicService productGoodsLogicService;
@Autowired
private ProductSizesLogicService productSizesLogicService;
protected void fillStorageNumAndSizeInfo(Integer productId, Map<String, Object> indexData) {
List<ProductSizesBO> productSizesBOList = productSizesLogicService.getProductSizeBOList(Arrays.asList(productId));
if (productSizesBOList == null || productSizesBOList.isEmpty()) {
indexData.put("storageNum", 0);
indexData.put("isSoonSoldOut", "Y");
indexData.put("isSoldOut", "Y");
indexData.put("soldOut", 0);
indexData.put("sizeIds", "");
indexData.put("sizeNames", "");
indexData.put("breakSizePercent", 100);
indexData.put("heatValue", 0);
return;
}
ProductSizesBO productSizesBO = productSizesBOList.get(0);
indexData.put("storageNum", productSizesBO.getStorageNum());
indexData.put("isSoonSoldOut", productSizesBO.getIsSoonSoldOut());
indexData.put("isSoldOut", productSizesBO.getIsSoldOut());
indexData.put("soldOut", productSizesBO.getSoldOut());
indexData.put("sizeIds", productSizesBO.getSizeIds());
indexData.put("sizeNames", productSizesBO.getSizeNames());
indexData.put("breakSizePercent", productSizesBO.getBreakSizePercent());
indexData.put("heatValue", productSizesBO.getHeatValue());
}
protected void fillStorageNumAndSizeInfo(Integer productId, Map<String, Object> indexData) {
List<ProductSizesBO> productSizesBOList = productSizesLogicService.getProductSizeBOList(Arrays.asList(productId));
if (productSizesBOList == null || productSizesBOList.isEmpty()) {
indexData.put("storageNum", 0);
indexData.put("isSoonSoldOut", "Y");
indexData.put("isSoldOut", "Y");
indexData.put("soldOut", 0);
indexData.put("sizeIds", "");
indexData.put("sizeNames", "");
indexData.put("breakSizePercent", 100);
indexData.put("heatValue", 0);
return;
}
ProductSizesBO productSizesBO = productSizesBOList.get(0);
indexData.put("storageNum", productSizesBO.getStorageNum());
indexData.put("isSoonSoldOut", productSizesBO.getIsSoonSoldOut());
indexData.put("isSoldOut", productSizesBO.getIsSoldOut());
indexData.put("soldOut", productSizesBO.getSoldOut());
indexData.put("sizeIds", productSizesBO.getSizeIds());
indexData.put("sizeNames", productSizesBO.getSizeNames());
indexData.put("breakSizePercent", productSizesBO.getBreakSizePercent());
indexData.put("heatValue", productSizesBO.getHeatValue());
}
protected void fillColor(Map<String, Object> indexData, Integer productId) {
Set<String> colorIdSet = new HashSet<String>();
Set<String> colorNameSet = new HashSet<String>();
// 1.获取goodsList
List<ProductGoodsBO> productGoodsBOList = goodsService.getProductGoodsByProductId(productId);
// 2.组装goods数据
if (productGoodsBOList != null && productGoodsBOList.size() == 1) {
ProductGoodsBO productGoodsBO = productGoodsBOList.get(0);
String goodsListJsonArrayStr = productGoodsBO.getGoodsList();
JSONArray goodsListJsonArray = JSONArray.parseArray(goodsListJsonArrayStr);
// 获取有库存且状态正常的color
productGoodsLogicService.getColorSet(goodsListJsonArray, colorIdSet, colorNameSet);
indexData.put("goodsList", goodsListJsonArray);
indexData.put("colorIds", StringUtils.join(colorIdSet, ","));
indexData.put("colorNames", StringUtils.join(colorNameSet, ","));
} else {
indexData.put("goodsList", new JSONArray());
indexData.put("colorIds", "");
indexData.put("colorNames", "");
}
}
protected void fillColor(Map<String, Object> indexData, Integer productId) {
Set<String> colorIdSet = new HashSet<String>();
Set<String> colorNameSet = new HashSet<String>();
// 1.获取goodsList
List<ProductGoodsBO> productGoodsBOList = productGoodsLogicService.getProductGoodsBOList(Arrays.asList(productId));
// 2.组装goods数据
if (productGoodsBOList != null && productGoodsBOList.size() == 1) {
ProductGoodsBO productGoodsBO = productGoodsBOList.get(0);
JSONArray goodsListJsonArray = productGoodsBO.getGoodsList();
// 获取有库存且状态正常的color
productGoodsLogicService.getColorSet(goodsListJsonArray, colorIdSet, colorNameSet);
indexData.put("goodsList", goodsListJsonArray);
indexData.put("colorIds", StringUtils.join(colorIdSet, ","));
indexData.put("colorNames", StringUtils.join(colorNameSet, ","));
} else {
indexData.put("goodsList", new JSONArray());
indexData.put("colorIds", "");
indexData.put("colorNames", "");
}
}
}
\ No newline at end of file
... ...
... ... @@ -20,9 +20,9 @@ import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.consumer.common.CostStatistics;
import com.yoho.search.consumer.index.increment.AbstractIndexMqListener;
import com.yoho.search.consumer.service.base.GoodsImagesService;
import com.yoho.search.consumer.service.base.GoodsService;
import com.yoho.search.consumer.service.bo.ProductGoodsBO;
import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
import com.yoho.search.consumer.service.logic.productIndex.ProductGoodsLogicService;
import com.yoho.search.consumer.service.logic.productIndex.viewBuilder.VideosBuilder;
import com.yoho.search.dal.model.GoodsImages;
... ... @@ -34,7 +34,7 @@ public class GoodsImagesMqListener extends AbstractIndexMqListener {
@Autowired
private GoodsImagesService goodsImagesService;
@Autowired
private GoodsService goodsService;
private ProductGoodsLogicService productGoodsLogicService;
@Autowired
private VideosBuilder videosBuilder;
@Autowired
... ... @@ -74,10 +74,12 @@ public class GoodsImagesMqListener extends AbstractIndexMqListener {
if (productId == null) {
return;
}
logger.info("[func=updateData][step(1/3)covertFromMap][goodsId={}][goodsImageId={}][cost={}ms]", goodsImages.getGoodsId(), goodsImages.getId(), costStatistics.getCost());
logger.info("[func=updateData][step(1/3)covertFromMap][goodsId={}][goodsImageId={}][cost={}ms]", goodsImages.getGoodsId(), goodsImages.getId(),
costStatistics.getCost());
// 第二步:保存至数据库
goodsImagesService.saveOrUpdate(goodsImages);
logger.info("[func=updateData][step(2/3)saveToBb][goodsId={}][goodsImageId={}][cost={}ms]", goodsImages.getGoodsId(), goodsImages.getId(), costStatistics.getCost());
logger.info("[func=updateData][step(2/3)saveToBb][goodsId={}][goodsImageId={}][cost={}ms]", goodsImages.getGoodsId(), goodsImages.getId(),
costStatistics.getCost());
// 第三步:更新索引
this.updateProductIndex(productId);
logger.info("[func=updateData][step(3/3)updateProductIndex][goodsId={}][goodsImageId={}][cost={}ms]", goodsImages.getGoodsId(), goodsImages.getId(),
... ... @@ -93,10 +95,10 @@ public class GoodsImagesMqListener extends AbstractIndexMqListener {
}
logger.info("[func=selectDefaultImageUrlByProductId][productId={}][cost={}ms]", productId, costStatistics.getCost());
// 2、获取goodsList
List<ProductGoodsBO> productGoodBOs = goodsService.getProductGoodsByProductId(productId);
List<ProductGoodsBO> productGoodBOs = productGoodsLogicService.getProductGoodsBOList(Arrays.asList(productId));
JSONArray goodsJsonArray = new JSONArray();
if (productGoodBOs != null && productGoodBOs.size() == 1) {
goodsJsonArray = JSONArray.parseArray(productGoodBOs.get(0).getGoodsList());
goodsJsonArray = productGoodBOs.get(0).getGoodsList();
}
logger.info("[func=getProductGoodsByProductId][productId={}][cost={}ms]", productId, costStatistics.getCost());
// 3、更新图片的时候检查下是否存在视频
... ...
package com.yoho.search.consumer.service.base;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.consumer.service.bo.ProductGoodsBO;
import com.yoho.search.consumer.service.logic.productIndex.ProductGoodsLogicService;
import com.yoho.search.dal.GoodsMapper;
import com.yoho.search.dal.model.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Component
public class GoodsService {
... ... @@ -53,11 +54,6 @@ public class GoodsService {
}
public List<Goods> getListByProductId(List<Integer> productIds){return goodsMapper.selectListByProductIds(productIds); }
@Deprecated
public List<Map<String, Object>> getGoodsListByProductId(Integer productId) {
return goodsMapper.selectGoodListByProductId(productId);
}
@Deprecated
public JSONObject getGoodsList(Map<String, Object> map) {
... ...
package com.yoho.search.consumer.service.bo;
import com.alibaba.fastjson.JSONObject;
import java.io.Serializable;
import com.alibaba.fastjson.JSONObject;
/**
* Created by wangnan on 2016/6/30.
*/
public class ProductGoodBO implements Serializable {
private static final long serialVersionUID = -6037322619886144422L;
private Integer product_id;
private JSONObject goodList;
private String isDefault;
public Integer getProduct_id() {
return product_id;
}
private JSONObject goodJSONObject;
public void setProduct_id(Integer product_id) {
this.product_id = product_id;
}
public Integer getProduct_id() {
return product_id;
}
public JSONObject getGoodList() {
return goodList;
}
public void setProduct_id(Integer product_id) {
this.product_id = product_id;
}
public void setGoodList(JSONObject goodList) {
this.goodList = goodList;
}
public JSONObject getGoodJSONObject() {
return goodJSONObject;
}
public String getIsDefault() {
return isDefault;
}
public void setGoodJSONObject(JSONObject goodJSONObject) {
this.goodJSONObject = goodJSONObject;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault;
}
}
... ...
... ... @@ -2,6 +2,8 @@ package com.yoho.search.consumer.service.bo;
import java.io.Serializable;
import com.alibaba.fastjson.JSONArray;
/**
* Created by wangnan on 2016/6/30.
*/
... ... @@ -9,7 +11,7 @@ public class ProductGoodsBO implements Serializable {
private static final long serialVersionUID = 8955321779208171799L;
private Integer productId;
private String goodsList;
private JSONArray goodsList;
public Integer getProductId() {
return productId;
... ... @@ -19,11 +21,12 @@ public class ProductGoodsBO implements Serializable {
this.productId = productId;
}
public String getGoodsList() {
public JSONArray getGoodsList() {
return goodsList;
}
public void setGoodsList(String goodsList) {
public void setGoodsList(JSONArray goodsList) {
this.goodsList = goodsList;
}
}
... ...
package com.yoho.search.consumer.service.bo;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ProductSizesBO {
import com.yoho.search.dal.model.ProductSizes;
private Integer productId;
private Integer storageNum;
private String skuIds;// 当前有效的sku列表
private String sizeIds;// 当前有效的尺码ids
private double breakSizePercent;//断码率
private String sizeNames;// 当前有效的颜色名称
private BigDecimal heatValue;
public class ProductSizesBO extends ProductSizes {
public Integer getProductId() {
return productId;
}
private String sizeNames;
private double breakSizePercent;
private BigDecimal heatValue;;
public void setProductId(Integer productId) {
this.productId = productId;
}
public ProductSizesBO(ProductSizes productSizes) {
this.productId = productSizes.getProductId();
this.storageNum = productSizes.getStorageNum();
this.sizeIds = productSizes.getSizeIds();
public Integer getStorageNum() {
return storageNum;
}
public Set<Integer> getSizeIdSet() {
Set<Integer> results = new HashSet<Integer>();
if (StringUtils.isBlank(this.sizeIds)) {
return results;
}
String[] sizeIdArray = this.sizeIds.split(",");
for (String sizeId : sizeIdArray) {
try {
results.add(Integer.valueOf(sizeId));
} catch (Exception e) {
}
}
return results;
public void setStorageNum(Integer storageNum) {
this.storageNum = storageNum;
}
public void setSizeNames(String sizeNames) {
this.sizeNames = sizeNames;
public String getSkuIds() {
return skuIds;
}
public void setSkuIds(String skuIds) {
this.skuIds = skuIds;
}
public String getSizeIds() {
return sizeIds;
}
public void setSizeIds(String sizeIds) {
this.sizeIds = sizeIds;
}
public String getSizeNames() {
return sizeNames;
}
public void setSizeNames(String sizeNames) {
this.sizeNames = sizeNames;
}
public double getBreakSizePercent() {
return breakSizePercent;
}
... ... @@ -51,6 +60,14 @@ public class ProductSizesBO extends ProductSizes {
this.breakSizePercent = breakSizePercent;
}
public BigDecimal getHeatValue() {
return heatValue;
}
public void setHeatValue(BigDecimal heatValue) {
this.heatValue = heatValue;
}
public Integer getSoldOut() {
return storageNum == null || storageNum == 0 ? 0 : 1;
}
... ... @@ -63,12 +80,4 @@ public class ProductSizesBO extends ProductSizes {
return storageNum == null || storageNum <= 2 ? "Y" : "N";
}
public BigDecimal getHeatValue() {
return heatValue;
}
public void setHeatValue(BigDecimal heatValue) {
this.heatValue = heatValue;
}
}
... ...
package com.yoho.search.consumer.service.logic.productIndex;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
... ... @@ -14,17 +31,6 @@ import com.yoho.search.dal.GoodsMapper;
import com.yoho.search.dal.model.Goods;
import com.yoho.search.dal.model.GoodsCoverImage;
import com.yoho.search.dal.model.Storage;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* Created by wangnan on 2016/6/30.
... ... @@ -72,22 +78,25 @@ public class ProductGoodsLogicService {
} catch (ExecutionException e) {
cacheLogger.error(e.getMessage());
}
if(productIds==null || productIds.isEmpty()){
return new ArrayList<ProductGoodsBO>();
}
List<Goods> goodsList = goodsMapper.selectListByProductIds(productIds);
List<Integer> goodsIds = goodsMapper.selectIdByProductIds(productIds);
List<Integer> goodsIds = goodsList.stream().map(Goods::getId).collect(Collectors.toList());
List<GoodsCoverImage> goodsCoverImageList = new ArrayList<GoodsCoverImage>();
List<Storage> storageList = new ArrayList<>();
if (goodsIds != null && !goodsIds.isEmpty()) {
goodsCoverImageList = goodsCoverImageMapper.selectGoodsCoverImage(goodsIds);
storageList = storageService.getStoragesByGoodsIds(goodsIds);
}
// 构建storageListMap
Map<Integer, Integer> storageListMap = new HashMap<>();
// 构建goodStorageMap
Map<Integer, Integer> goodStorageMap = new HashMap<>();
if (!CollectionUtils.isEmpty(storageList)) {
for (Storage storage : storageList) {
if (storageListMap.containsKey(storage.getGoodsId())) {
storageListMap.put(storage.getGoodsId(), storage.getStorageNum() + storageListMap.get(storage.getGoodsId()));
if (goodStorageMap.containsKey(storage.getGoodsId())) {
goodStorageMap.put(storage.getGoodsId(), storage.getStorageNum() + goodStorageMap.get(storage.getGoodsId()));
} else {
storageListMap.put(storage.getGoodsId(), storage.getStorageNum());
goodStorageMap.put(storage.getGoodsId(), storage.getStorageNum());
}
}
}
... ... @@ -113,21 +122,21 @@ public class ProductGoodsLogicService {
for (Goods goods : goodsList) {
ProductGoodBO productGoodBO = new ProductGoodBO();
productGoodBO.setProduct_id(goods.getProductId());
productGoodBO.setIsDefault(goods.getIsDefault() == null ? "" : goods.getIsDefault());
this.buildGoods(goods, productGoodBO, productColorsMap, goodsCoverImagesMap, storageListMap);
JSONObject goodsJSONObject = this.fillGoodJSONObject(goods, productColorsMap, goodsCoverImagesMap, goodStorageMap);
productGoodBO.setGoodJSONObject(goodsJSONObject);
productGoodBOs.add(productGoodBO);
}
Map<Integer, JSONArray> productGoodsMap = new HashMap<>();
for (ProductGoodBO productGoodBO : productGoodBOs) {
if (productGoodsMap.containsKey(productGoodBO.getProduct_id())) {
if (productGoodBO.getGoodList() != null) {
if (productGoodBO.getGoodJSONObject() != null) {
JSONArray jsonArray = productGoodsMap.get(productGoodBO.getProduct_id());
jsonArray.add(productGoodBO.getGoodList());
jsonArray.add(productGoodBO.getGoodJSONObject());
productGoodsMap.put(productGoodBO.getProduct_id(), jsonArray);
}
} else {
JSONArray jsonArray = new JSONArray();
jsonArray.add(productGoodBO.getGoodList());
jsonArray.add(productGoodBO.getGoodJSONObject());
productGoodsMap.put(productGoodBO.getProduct_id(), jsonArray);
}
}
... ... @@ -135,12 +144,12 @@ public class ProductGoodsLogicService {
for (Map.Entry<Integer, JSONArray> entry : productGoodsMap.entrySet()) {
ProductGoodsBO pg = new ProductGoodsBO();
pg.setProductId(entry.getKey());
pg.setGoodsList(entry.getValue().toJSONString());
pg.setGoodsList(entry.getValue());
productGoodsBOs.add(pg);
}
return productGoodsBOs;
}
/**
* 获取有库存且状态正常的color
*/
... ... @@ -164,23 +173,22 @@ public class ProductGoodsLogicService {
}
/**
* 拼装goodsList字段
* 转成good对象
*/
private void buildGoods(Goods goods, ProductGoodBO productGoodBO, Map<Integer, String> productColorsMap, Map<Integer, GoodsCoverImage> goodsCoverImagesMap,
Map<Integer, Integer> storageMap) {
JSONObject jsonObj = new JSONObject();
private JSONObject fillGoodJSONObject(Goods goods, Map<Integer, String> productColorsMap, Map<Integer, GoodsCoverImage> goodsCoverImagesMap, Map<Integer, Integer> goodStorageMap) {
JSONObject goodJSONObject = new JSONObject();
// 来自Goods
jsonObj.put("goods_id", String.valueOf(goods.getId()));
jsonObj.put("color_name", StringUtils.isBlank(goods.getColorName()) ? "" : goods.getColorName());
jsonObj.put("images_url", StringUtils.isBlank(goods.getColorImage()) ? "" : goods.getColorImage());
jsonObj.put("is_default", StringUtils.isBlank(goods.getIsDefault()) ? "" : goods.getIsDefault());
jsonObj.put("color_id", goods.getColorId() == null ? "" : goods.getColorId().toString());
jsonObj.put("status", goods.getStatus() == null ? "" : goods.getStatus().toString());
jsonObj.put("product_skc", goods.getProductSkc() == null ? "" : goods.getProductSkc());
jsonObj.put("color_value", "");
goodJSONObject.put("goods_id", String.valueOf(goods.getId()));
goodJSONObject.put("color_name", StringUtils.isBlank(goods.getColorName()) ? "" : goods.getColorName());
goodJSONObject.put("images_url", StringUtils.isBlank(goods.getColorImage()) ? "" : goods.getColorImage());
goodJSONObject.put("is_default", StringUtils.isBlank(goods.getIsDefault()) ? "" : goods.getIsDefault());
goodJSONObject.put("color_id", goods.getColorId() == null ? "" : goods.getColorId().toString());
goodJSONObject.put("status", goods.getStatus() == null ? "" : goods.getStatus().toString());
goodJSONObject.put("product_skc", goods.getProductSkc() == null ? "" : goods.getProductSkc());
goodJSONObject.put("color_value", "");
// 来自productColorsMap
String colorCode = productColorsMap.get(goods.getColorId());
jsonObj.put("color_code", StringUtils.isBlank(colorCode) ? "" : colorCode);
goodJSONObject.put("color_code", StringUtils.isBlank(colorCode) ? "" : colorCode);
// 来自goodsCoverImagesMap
GoodsCoverImage goodsCoverImage = goodsCoverImagesMap.get(goods.getId());
String cover_1 = "";
... ... @@ -189,11 +197,11 @@ public class ProductGoodsLogicService {
cover_1 = goodsCoverImage.getCover_1();
cover_2 = goodsCoverImage.getCover_2();
}
jsonObj.put("cover_1", StringUtils.isBlank(cover_1) ? "" : cover_1);
jsonObj.put("cover_2", StringUtils.isBlank(cover_2) ? "" : cover_2);
goodJSONObject.put("cover_1", StringUtils.isBlank(cover_1) ? "" : cover_1);
goodJSONObject.put("cover_2", StringUtils.isBlank(cover_2) ? "" : cover_2);
// 来自storageMap
Integer storage_num = storageMap.get(goods.getId());
jsonObj.put("storage_num", storage_num == null ? 0 : storage_num);
productGoodBO.setGoodList(jsonObj);
Integer storage_num = goodStorageMap.get(goods.getId());
goodJSONObject.put("storage_num", storage_num == null ? 0 : storage_num);
return goodJSONObject;
}
}
... ...
package com.yoho.search.consumer.service.logic.productIndex;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yoho.search.consumer.service.bo.ProductSizesBO;
import com.yoho.search.dal.GoodsMapper;
import com.yoho.search.dal.ProductSizesMapper;
import com.yoho.search.dal.SizeMapper;
import com.yoho.search.dal.StorageMapper;
import com.yoho.search.dal.model.Goods;
import com.yoho.search.dal.model.ProductSizes;
import com.yoho.search.dal.model.Size;
import com.yoho.search.dal.model.Storage;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by wangnan on 2016/6/30.
... ... @@ -32,8 +38,6 @@ public class ProductSizesLogicService {
@Autowired
private SizeMapper sizeMapper;
@Autowired
private ProductSizesMapper productSizesMapper;
@Autowired
private ProductHeatValueLogicService productHeatValueLogicService;
/**
... ... @@ -41,85 +45,71 @@ public class ProductSizesLogicService {
*/
public List<ProductSizesBO> getProductSizeBOList(List<Integer> productIds) {
// 获取ProductId对应的上架的goodsId列表
List<Goods> goodsList = goodsMapper.selectByIdsAndStatus(productIds);
if (CollectionUtils.isEmpty(goodsList)) {
List<Goods> validGoodsList = goodsMapper.selectValidListByProductIds(productIds);
if (CollectionUtils.isEmpty(validGoodsList)) {
return new ArrayList<>();
}
// 获取goodsId对应得Storage列表
List<Integer> goodsIdList = goodsList.stream().map(Goods::getId).collect(Collectors.toList());
List<Storage> oldStorageList = storageMapper.selectByGoodsIds(goodsIdList);
if (CollectionUtils.isEmpty(oldStorageList)) {
List<Integer> validGoodsIdList = validGoodsList.stream().map(Goods::getId).collect(Collectors.toList());
List<Storage> storageList = storageMapper.selectByGoodsIds(validGoodsIdList);
if (CollectionUtils.isEmpty(storageList)) {
return new ArrayList<>();
}
// 过滤状态是上架的且有库存的Goods和Storage
Map<Integer, Set<Integer>> productValidStatusSizes = new HashMap<Integer, Set<Integer>>();
Map<Integer, Set<Integer>> productHasStorageSizes = new HashMap<Integer, Set<Integer>>();
List<Storage> effectiveStorageList = new ArrayList<Storage>();
for (Storage storage : oldStorageList) {
// 按productId分组
Map<Integer, List<Storage>> productStorageMap = new HashMap<Integer, List<Storage>>();
for (Storage storage : storageList) {
Integer productId = storage.getProductId();
// 处理未下架的sku
if (!VALID_STATUS.equals(storage.getStatus())) {
continue;
}
this.addValueToSet(productId, storage.getGoodsDimensionId(), productValidStatusSizes);
// 处理有库存的sku
if (storage.getStorageNum() == null || storage.getStorageNum().intValue() <= 0) {
continue;
}
this.addValueToSet(productId, storage.getGoodsDimensionId(), productHasStorageSizes);
effectiveStorageList.add(storage);
}
if (CollectionUtils.isEmpty(effectiveStorageList)) {
return new ArrayList<>();
}
// 根据上架的GoodsId筛选Storage数据
Set<Integer> validGoodsIdSet = goodsIdList.stream().collect(Collectors.toSet());
List<Integer> validErpSkuIdList = new ArrayList<>();
for (Storage s : effectiveStorageList) {
if (validGoodsIdSet.contains(s.getGoodsId())) {
validErpSkuIdList.add(s.getErpSkuId());
List<Storage> productStorageList = productStorageMap.get(productId);
if (productStorageList == null) {
productStorageList = new ArrayList<Storage>();
productStorageMap.put(productId, productStorageList);
}
}
// 判断sku列表是否为空
if (validErpSkuIdList == null || validErpSkuIdList.isEmpty()) {
return new ArrayList<>();
}
// 从数据库中获取真实库存
List<ProductSizes> productSizesFromDb = productSizesMapper.selectProductSizes(validErpSkuIdList);
if (CollectionUtils.isEmpty(productSizesFromDb)) {
return new ArrayList<>();
}
// 构造返回结果对象
List<ProductSizesBO> results = new ArrayList<ProductSizesBO>();
for (ProductSizes productSizes : productSizesFromDb) {
results.add(new ProductSizesBO(productSizes));
productStorageList.add(storage);
}
// 获取尺码信息
// 批量获取尺码信息
Set<Integer> sizeIdSet = new HashSet<>();
for (ProductSizesBO productSizesBO : results) {
sizeIdSet.addAll(productSizesBO.getSizeIdSet());
for (Storage s : storageList) {
sizeIdSet.add(s.getGoodsDimensionId());
}
List<Size> sizeList = sizeMapper.selectByIds(sizeIdSet.stream().collect(Collectors.toList()));
Map<Integer, String> sizeNameMap = sizeList.stream().collect(Collectors.toMap(Size::getId, Size::getSizeName));
// 获取人气值信息
// 批量获取人气值信息
Map<Integer, BigDecimal> heatValueMap = productHeatValueLogicService.queryProductIdHeatValue(productIds);
// 填充其他信息
for (ProductSizesBO productSizesBO : results) {
// 构造ProductSizesBO
List<ProductSizesBO> results = new ArrayList<ProductSizesBO>();
for (Map.Entry<Integer, List<Storage>> entry : productStorageMap.entrySet()) {
Integer productId = entry.getKey();
List<Storage> productStorageList = entry.getValue();
ProductSizesBO productSizesBO = new ProductSizesBO();
productSizesBO.setProductId(productId);
productSizesBO.setBreakSizePercent(this.getBreakSizePercent(productStorageList));// 计算断码率
// 过滤出有效的和有库存的库存
List<Storage> validteStorages = productStorageList.stream()
.filter(storage -> VALID_STATUS.equals(storage.getStatus()) && storage.getStorageNum() != null && storage.getStorageNum() > 0)
.collect(Collectors.toList());
// 获取信息
List<Integer> sizeIds = new ArrayList<Integer>();
List<Integer> skuIds = new ArrayList<Integer>();
int storageNum = 0;
for (Storage storage : validteStorages) {
sizeIds.add(storage.getGoodsDimensionId());
skuIds.add(storage.getErpSkuId());
storageNum = storageNum + storage.getStorageNum();
}
productSizesBO.setSkuIds(StringUtils.join(skuIds, ","));
productSizesBO.setSizeIds(StringUtils.join(sizeIds, ","));
productSizesBO.setStorageNum(storageNum);
// 填充尺码名称
productSizesBO.setSizeNames(this.getSizeNames(productSizesBO.getSizeIdSet(), sizeNameMap));
// 填充断码率
Integer validStatusSizeCount = productValidStatusSizes.getOrDefault(productSizesBO.getProductId(), new HashSet<Integer>()).size();
Integer hasStorageSizeCount = productHasStorageSizes.getOrDefault(productSizesBO.getProductId(), new HashSet<Integer>()).size();
productSizesBO.setBreakSizePercent(this.getBreakSizePercent(validStatusSizeCount, hasStorageSizeCount));
productSizesBO.setSizeNames(StringUtils.join((this.getSizeNames(sizeIds, sizeNameMap)), ","));
// 填充人气值[断码率>50,则人气值减半]
BigDecimal heatValue = heatValueMap.get(productSizesBO.getProductId());
if (heatValue == null) {
... ... @@ -129,29 +119,42 @@ public class ProductSizesLogicService {
heatValue = heatValue.multiply(new BigDecimal("0.5"));
}
productSizesBO.setHeatValue(heatValue);
results.add(productSizesBO);
}
return results;
}
private <K, V> void addValueToSet(K key, V value, Map<K, Set<V>> map) {
Set<V> values = map.get(key);
if (values == null) {
values = new HashSet<V>();
map.put(key, values);
private double getBreakSizePercent(List<Storage> storageList) {
Set<Integer> productValidStatusSizes = new HashSet<Integer>();// 上架了的尺码【计算断码率】
Set<Integer> productHasStorageSizes = new HashSet<Integer>();// 有库存的尺码【计算断码率】
for (Storage storage : storageList) {
// 处理未下架的sku
if (!VALID_STATUS.equals(storage.getStatus())) {
continue;
}
// 记录有效的尺码id
productValidStatusSizes.add(storage.getGoodsDimensionId());
// 处理有库存的sku
if (storage.getStorageNum() == null || storage.getStorageNum().intValue() <= 0) {
continue;
}
// 记录有库存的尺码id
productHasStorageSizes.add(storage.getGoodsDimensionId());
}
values.add(value);
return this.getBreakSizePercent(productValidStatusSizes.size(), productHasStorageSizes.size());
}
private String getSizeNames(Set<Integer> sizeIds, Map<Integer, String> sizeNameMap) {
StringBuilder results = new StringBuilder();
private List<String> getSizeNames(Collection<Integer> sizeIds, Map<Integer, String> sizeNameMap) {
List<String> results = new ArrayList<String>();
for (Integer sizeId : sizeIds) {
String sizeName = sizeNameMap.get(sizeId);
if (sizeName == null) {
continue;
}
results.append(',').append(sizeName);
results.add(sizeName);
}
return results.toString().replaceFirst(",", "");
return results;
}
/**
... ...
package com.yoho.search.consumer.service.logic.productIndex.viewBuilder;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.consumer.service.bo.ProductGoodsBO;
import com.yoho.search.consumer.service.bo.ProductIndexBO;
import com.yoho.search.consumer.service.logic.productIndex.ProductGoodsLogicService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.consumer.service.bo.ProductGoodsBO;
import com.yoho.search.consumer.service.bo.ProductIndexBO;
import com.yoho.search.consumer.service.logic.productIndex.ProductGoodsLogicService;
/**
* Created by wangnan on 2017/1/6.
*/
@Component
public class ProductGoodsBuilder implements ViewBuilder {
@Autowired
private ProductGoodsLogicService productGoodsLogicService;
@Autowired
private ProductGoodsLogicService productGoodsLogicService;
/**
* 构建ProductIndex的ColorIds,ColorNames属性
*/
@Override
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
List<ProductGoodsBO> productGoodsBOs = productGoodsLogicService.getProductGoodsBOList(ids);
Map<Integer, ProductGoodsBO> productGoodsMap = productGoodsBOs.stream().collect(Collectors.toMap(ProductGoodsBO::getProductId, (p) -> p));
Set<String> colorIdSet = null;
Set<String> colorNameSet = null;
for (ProductIndexBO productIndexBO : productIndexBOs) {
ProductGoodsBO productGoodsBO = productGoodsMap.get(productIndexBO.getProductId());
if (productGoodsBO != null) {
this.checkSknStatus(productIndexBO, productGoodsBO);
productIndexBO.setGoodsList(productGoodsBO.getGoodsList());
String goodsListJsonArrayStr = productGoodsBO.getGoodsList();
if (goodsListJsonArrayStr == null || goodsListJsonArrayStr.length() < 3) {
productIndexBO.setColorIds("");
productIndexBO.setColorNames("");
continue;
}
colorIdSet = new HashSet<String>();
colorNameSet = new HashSet<String>();
JSONArray goodsListJsonArray = JSONArray.parseArray(goodsListJsonArrayStr);
//获取有库存且状态正常的color
productGoodsLogicService.getColorSet(goodsListJsonArray, colorIdSet, colorNameSet);
productIndexBO.setColorIds(StringUtils.join(colorIdSet, ","));
productIndexBO.setColorNames(StringUtils.join(colorNameSet, ","));
/**
* 构建ProductIndex的ColorIds,ColorNames属性
*/
@Override
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
List<ProductGoodsBO> productGoodsBOs = productGoodsLogicService.getProductGoodsBOList(ids);
Map<Integer, ProductGoodsBO> productGoodsMap = productGoodsBOs.stream().collect(Collectors.toMap(ProductGoodsBO::getProductId, (p) -> p));
for (ProductIndexBO productIndexBO : productIndexBOs) {
ProductGoodsBO productGoodsBO = productGoodsMap.get(productIndexBO.getProductId());
if (productGoodsBO != null) {
this.checkSknStatus(productIndexBO, productGoodsBO);
JSONArray goodsList = productGoodsBO.getGoodsList();
if (goodsList == null) {
goodsList = new JSONArray();
}
productIndexBO.setGoodsList(goodsList.toJSONString());
if (goodsList.isEmpty()) {
productIndexBO.setColorIds("");
productIndexBO.setColorNames("");
continue;
}
Set<String> colorIdSet = new HashSet<String>();
Set<String> colorNameSet = new HashSet<String>();
// 获取有库存且状态正常的color
productGoodsLogicService.getColorSet(goodsList, colorIdSet, colorNameSet);
productIndexBO.setColorIds(StringUtils.join(colorIdSet, ","));
productIndexBO.setColorNames(StringUtils.join(colorNameSet, ","));
}
}
}
}
}
}
/**
* 如果skn下面所有skc的状态都是0,那skn的状态设为0
* 和增量不同之处:不存在status从0->1,只存在1->0
*/
private void checkSknStatus(ProductIndexBO productIndexBO, ProductGoodsBO productGoodsBO) {
JSONArray jsonArray = JSONArray.parseArray(productGoodsBO.getGoodsList());
if (jsonArray != null) {
boolean sknInvalid = true;
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject) jsonArray.get(i);
if (jsonObject!=null&&jsonObject.get("status") != null) {
String status = jsonObject.get("status").toString();
if (status.equals("1")) {
sknInvalid = false;
}
}
}
if (sknInvalid) {
productIndexBO.setStatus(0);
}
}
}
/**
* 如果skn下面所有skc的状态都是0,那skn的状态设为0 和增量不同之处:不存在status从0->1,只存在1->0
*/
private void checkSknStatus(ProductIndexBO productIndexBO, ProductGoodsBO productGoodsBO) {
JSONArray jsonArray = productGoodsBO.getGoodsList();
if (jsonArray != null) {
boolean sknInvalid = true;
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject) jsonArray.get(i);
if (jsonObject != null && jsonObject.get("status") != null) {
String status = jsonObject.get("status").toString();
if (status.equals("1")) {
sknInvalid = false;
}
}
}
if (sknInvalid) {
productIndexBO.setStatus(0);
}
}
}
}
... ...
... ... @@ -11,7 +11,6 @@ import org.springframework.stereotype.Component;
import com.yoho.search.consumer.service.bo.ProductIndexBO;
import com.yoho.search.consumer.service.bo.ProductSizesBO;
import com.yoho.search.consumer.service.logic.productIndex.ProductSizesLogicService;
import com.yoho.search.dal.model.ProductSizes;
/**
* Created by wangnan on 2017/1/6.
... ... @@ -21,11 +20,11 @@ public class ProductSizesBuilder implements ViewBuilder {
@Autowired
private ProductSizesLogicService productSizesLogicService;
@Override
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
List<ProductSizesBO> productSizess = productSizesLogicService.getProductSizeBOList(ids);
Map<Integer, ProductSizesBO> productSizesMap = productSizess.stream().collect(Collectors.toMap(ProductSizes::getProductId, (p) -> p));
Map<Integer, ProductSizesBO> productSizesMap = productSizess.stream().collect(Collectors.toMap(ProductSizesBO::getProductId, (p) -> p));
for (ProductIndexBO productIndexBO : productIndexBOs) {
// 设置默认值
productIndexBO.setStorageNum(BigDecimal.valueOf(0));
... ...