Authored by 胡古飞

Merge branch 'gray' into wn_lastReducePriceTime

# Conflicts:
#	index/src/main/resources/esmapping/productindex.json
#	service/src/main/java/com/yoho/search/consumer/service/base/ProductIndexService.java
... ... @@ -14,18 +14,12 @@ public interface ProductMapper {
int updateByPrimaryKeySelective(Product record);
int updateByPrimaryKey(Product record);
List<Product> selectPageLists(@Param(value = "offset") Integer offset, @Param(value = "pageSize") Integer pageSize);
Integer selectProductIdBySkn(Integer productSkn);
Integer selectSknByProductId(Integer productId);
List<Product> selectSknsByProductIds(List<Integer> productIds);
List<Product> selectAll();
int selectCount();
Product selectBySkn(Integer skn);
... ...
<?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.ProductMapper">
<resultMap id="BaseResultMap" type="com.yoho.search.dal.model.Product">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="shop_id" property="shopId" jdbcType="INTEGER"/>
... ... @@ -56,7 +57,9 @@
<result column="is_seckill" property="isSeckill" jdbcType="CHAR"/>
<result column="market_phrase" property="marketPhrase" jdbcType="VARCHAR"/>
<result column="bundle_type" property="bundleType" jdbcType="INTEGER"/>
<result column="coupon_limit_status" property="couponLimitStatus" jdbcType="INTEGER"/>
</resultMap>
<sql id="Base_Column_List">
id, erp_product_id,shop_id, product_name, cn_alphabet,
phrase, sales_phrase, brand_id, max_sort_id, middle_sort_id,
... ... @@ -67,8 +70,9 @@
first_shelve_time,shelve_time,expect_arrival_time, create_time, arrival_time,
edit_time, auditing_time, is_down, status, is_edit,
vip_discount_type, storage,is_outlets,folder_id,sell_channels,
elements, age_level,app_type,is_instalment,is_seckill,is_limitbuy,is_deposit_advance,market_phrase,bundle_type
elements, age_level,app_type,is_instalment,is_seckill,is_limitbuy,is_deposit_advance,market_phrase,bundle_type,coupon_limit_status
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap"
parameterType="java.lang.Integer" timeout="20000">
select
... ... @@ -76,6 +80,7 @@
from product
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectBySkn" resultMap="BaseResultMap"
parameterType="java.lang.Integer" timeout="20000">
select
... ... @@ -84,11 +89,13 @@
where erp_product_id = #{skn,jdbcType=INTEGER}
limit 1
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"
timeout="20000">
delete from product
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.yoho.search.dal.model.Product"
timeout="20000">
insert ignore into product (id, erp_product_id,shop_id,
... ... @@ -112,7 +119,7 @@
status, is_edit, vip_discount_type,
storage,
is_outlets, folder_id,
sell_channels, elements,age_level,app_type,is_instalment,is_seckill,is_deposit_advance,is_limitbuy,market_phrase,bundle_type)
sell_channels, elements,age_level,app_type,is_instalment,is_seckill,is_deposit_advance,is_limitbuy,market_phrase,bundle_type,coupon_limit_status)
values
(#{id,jdbcType=INTEGER},
#{erpProductId,jdbcType=INTEGER},
... ... @@ -154,9 +161,11 @@
#{isDepositAdvance,jdbcType=CHAR},
#{isLimitbuy,jdbcType=CHAR},
#{marketPhrase,jdbcType=VARCHAR},
#{bundleType,jdbcType=INTEGER}
#{bundleType,jdbcType=INTEGER},
#{couponLimitStatus,jdbcType=INTEGER}
)
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.yoho.search.dal.model.Product"
timeout="20000">
update product
... ... @@ -321,34 +330,37 @@
<if test="bundleType != null">
bundle_type = #{bundleType,jdbcType=INTEGER},
</if>
<if test="couponLimitStatus != null">
coupon_limit_status = #{couponLimitStatus,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectCount" resultType="java.lang.Integer" timeout="20000">
SELECT count(*) FROM product
</select>
<select id="selectProductIdBySkn" resultType="java.lang.Integer"
parameterType="java.lang.Integer" timeout="20000">
SELECT id FROM product where
erp_product_id =
#{productSkn,jdbcType=INTEGER}
</select>
<select id="selectSknByProductId" resultType="java.lang.Integer"
parameterType="java.lang.Integer" timeout="20000">
SELECT erp_product_id FROM product where
id =
#{id,jdbcType=INTEGER}
</select>
<select id="selectPageLists" resultMap="BaseResultMap" timeout="20000">
select
<include refid="Base_Column_List"/>
from product limit #{offset},#{pageSize}
</select>
<select id="selectAll" resultMap="BaseResultMap" timeout="20000">
select
<include refid="Base_Column_List"/>
from product
</select>
<select id="selectBySkns" resultMap="BaseResultMap">
Select
<include refid="Base_Column_List"/>
... ... @@ -358,6 +370,7 @@
#{item}
</foreach>
</select>
<select id="selectListByIds" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
... ... @@ -367,4 +380,5 @@
#{item}
</foreach>
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -29,7 +29,7 @@
<![CDATA[ start_time <= #{currentTime,jdbcType=INTEGER} ]]>
<![CDATA[ and end_time >= #{currentTime,jdbcType=INTEGER} ]]>
and status = 1
and is_del = 'N'
and is_del != 'Y'
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
... ...
... ... @@ -25,7 +25,6 @@
open="(" separator="," close=")">
#{item}
</foreach>
and is_del = 'N'
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
... ...
package com.yoho.search.consumer.index.increment;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
... ... @@ -24,6 +11,18 @@ import com.yoho.search.consumer.service.base.ActivityProductService;
import com.yoho.search.consumer.service.base.ProductService;
import com.yoho.search.core.es.utils.IgnoreSomeException;
import com.yoho.search.dal.model.ActivityProduct;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Created by YOHO on 15-9-2.
... ...
... ... @@ -1056,8 +1056,13 @@
"productProfitValue": {
"type":"long"
},
<<<<<<< HEAD
"lastReducePriceTime": {
"type": "long"
=======
"couponLimitStatus": {
"type":"long"
>>>>>>> gray
}
}
}
... ...
... ... @@ -211,6 +211,7 @@ public class ProductIndexService {
map.put(ProductIndexEsField.profitValue, productIndexBO.getProfitValue());
map.put(ProductIndexEsField.promotionTitle, productIndexBO.getPromotionTitles());
map.put(ProductIndexEsField.lastReducePriceTime, productIndexBO.getLastReducePriceTime());
map.put(ProductIndexEsField.couponLimitStatus, productIndexBO.getCouponLimitStatus());
return map;
}
... ...
... ... @@ -62,6 +62,8 @@ public class ProductIBO implements Serializable {
private String isInstalment;
private String isSeckill;
private String marketPhrase;
private Integer couponLimitStatus;
// inner join brand
private String brandNameCn;
... ... @@ -689,4 +691,11 @@ public class ProductIBO implements Serializable {
this.isPhraseExist = isPhraseExist;
}
public Integer getCouponLimitStatus() {
return couponLimitStatus;
}
public void setCouponLimitStatus(Integer couponLimitStatus) {
this.couponLimitStatus = couponLimitStatus;
}
}
\ No newline at end of file
... ...
... ... @@ -4,10 +4,12 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.dal.model.PromotionInfo;
import com.yoho.search.dal.model.PromotionParams;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
... ... @@ -17,7 +19,7 @@ import java.util.stream.Collectors;
*/
public class PromotionCond {
private final Logger INDEX_REBUILD_LOG = LoggerFactory.getLogger("INDEX_REBULDER");
private static final Logger INDEX_REBUILD_LOG = LoggerFactory.getLogger("INDEX_REBULDER");
enum Aggregator {
ALL, ANY;
... ... @@ -118,19 +120,20 @@ public class PromotionCond {
Object condtionsObj = condDetailJSONObj.get("conditions");
if (condtionsObj instanceof JSONArray) {
JSONArray condItemsJSONArray = (JSONArray) condtionsObj;
Assert.notEmpty(condItemsJSONArray, "condItemsJSONArray is empty.");
this.condItemList = condItemsJSONArray.stream().map(obj -> (JSONObject) obj).map(CondItem::new).collect(Collectors.toList());
this.condItemList = condItemsJSONArray.isEmpty() ? new ArrayList<>() :
condItemsJSONArray.stream().map(obj -> (JSONObject) obj).map(CondItem::new).collect(Collectors.toList());
} else {
JSONObject condItemsJSONObj = (JSONObject) condtionsObj;
Assert.notEmpty(condItemsJSONObj, "condItemsJSONObj is empty.");
this.condItemList = condItemsJSONObj.keySet().stream().map(key -> condItemsJSONObj.getJSONObject(key)).map(CondItem::new).collect(Collectors.toList());
this.condItemList = condItemsJSONObj.isEmpty() ? new ArrayList<>() :
condItemsJSONObj.keySet().stream().map(key -> condItemsJSONObj.getJSONObject(key)).map(CondItem::new).collect(Collectors.toList());
}
Assert.notEmpty(this.condItemList, "condItemList cannot be empty");
}
public boolean matchProduct(final ProductIndexBO productIndexBO) {
if (this.aggregator == Aggregator.ALL) {
if (CollectionUtils.isEmpty(condItemList)) {
// 当没有具体条件,比如【全场满99元加5元换购YOHO!当期热销新刊】这种时所有productindex都匹配
return true;
} else if (this.aggregator == Aggregator.ALL) {
return this.condItemList.stream().allMatch(condItem -> condItem.matchProduct(productIndexBO));
} else {
return this.condItemList.stream().anyMatch(condItem -> condItem.matchProduct(productIndexBO));
... ... @@ -166,7 +169,7 @@ public class PromotionCond {
private final List<CondDetail> condDetailList;
public PromotionCond(PromotionInfo promotionInfo, PromotionParams promotionParams) {
private PromotionCond(PromotionInfo promotionInfo, PromotionParams promotionParams) {
this.promotionId = promotionInfo.getId();
this.promotionTitle = promotionInfo.getTitle();
... ... @@ -212,6 +215,19 @@ public class PromotionCond {
Assert.notEmpty(this.condDetailList, "condDetailList cannot be empty");
}
public static PromotionCond build(PromotionInfo promotionInfo, PromotionParams promotionParams) {
if (promotionInfo == null) {
return null;
}
try {
return new PromotionCond(promotionInfo, promotionParams);
} catch (Exception e) {
INDEX_REBUILD_LOG.warn("[func=PromotionCond.build][promotionId={}][errorMsg={}]", promotionInfo.getId(), e.getMessage());
return null;
}
}
public boolean matchProduct(final ProductIndexBO productIndexBO) {
boolean matchResult;
if (this.aggregator == Aggregator.ALL) {
... ... @@ -247,7 +263,7 @@ public class PromotionCond {
promotionParams.setPromotionId(1);
promotionParams.setConditionParam(conditionParam);
PromotionCond promotionCond = new PromotionCond(promotionInfo, promotionParams);
PromotionCond promotionCond = PromotionCond.build(promotionInfo, promotionParams);
ProductIndexBO productIndexBO = new ProductIndexBO();
productIndexBO.setProductSkn(51049121);
... ...
... ... @@ -45,7 +45,7 @@ public class PromotionConditionLogicService {
// 1. 查询促销列表
List<PromotionInfo> promotionInfoList = promotionInfoService.selectValidPromotionList();
if (CollectionUtils.isEmpty(promotionInfoList)) {
INDEX_REBUILD_LOG.debug("[func=PromotionConditionLogicService.end][msg=no valid promotion]");
INDEX_REBUILD_LOG.info("[func=PromotionConditionLogicService.end][msg=no valid promotion]");
return;
}
... ... @@ -56,7 +56,7 @@ public class PromotionConditionLogicService {
.collect(Collectors.toList());
List<PromotionParams> promotionParamsList = promotionParamsService.selectByPromotionIdList(promotionIdList);
if (CollectionUtils.isEmpty(promotionParamsList)) {
INDEX_REBUILD_LOG.debug("[func=PromotionConditionLogicService.end][msg=no valid promotion params]");
INDEX_REBUILD_LOG.info("[func=PromotionConditionLogicService.end][msg=no valid promotion params]");
return;
}
... ... @@ -65,7 +65,7 @@ public class PromotionConditionLogicService {
this.promotionCondList = promotionParamsList.parallelStream()
.filter(Objects::nonNull)
.filter(promotionParams -> StringUtils.isNotEmpty(promotionParams.getConditionParam()))
.map(promotionParams -> new PromotionCond(promotionInfoMap.get(promotionParams.getPromotionId()), promotionParams))
.map(promotionParams -> PromotionCond.build(promotionInfoMap.get(promotionParams.getPromotionId()), promotionParams))
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Integer> validPromotionIdList = this.promotionCondList.stream().map(PromotionCond::getPromotionId).collect(Collectors.toList());
... ...
package com.yoho.search.consumer.service.logic;
import com.yoho.core.config.ConfigReader;
import com.yoho.search.dal.ScoreRuleMapper;
import com.yoho.search.dal.model.ScoreRule;
import javax.annotation.Resource;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -10,9 +9,10 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import com.yoho.core.config.ConfigReader;
import com.yoho.search.base.constants.ScoreRuleConstants;
import com.yoho.search.dal.ScoreRuleMapper;
import com.yoho.search.dal.model.ScoreRule;
/**
* Created by ginozhang on 2017/4/12.
... ... @@ -20,79 +20,74 @@ import java.util.List;
@Component
public class ScoreRuleLogicService implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(ScoreRuleLogicService.class);
private static final List<String> SUPPORT_RULE_TYPES = Arrays.asList("BRAND_INCREASE_RULE","NEW_ARRIVAL_PAGE_DECAY_RULE","OTHER_PAGE_DECAY_RULE");
private static final String CONFIG_ROOT_PATH = "/yh/config";
private static final String FUNCTION_SCORE_RULE_KEY_TEMPLATE = "search.function.score.%s";
private static final String DEFAULT_RULE_VALUES = "-1";
@Autowired
private ScoreRuleMapper scoreRuleMapper;
@Autowired
private ConfigReader configReader;
@Resource(name = "curatorFramework")
private CuratorFramework client;
@Override
public void afterPropertiesSet() throws Exception {
for (String ruleType : SUPPORT_RULE_TYPES) {
ScoreRule scoreRule = scoreRuleMapper.selectByRuleType(ruleType);
if (scoreRule != null) {
tryUpdateFunctionScoreRule(scoreRule);
} else {
tryRemoveFunctionScoreRule(ruleType);
}
}
}
public void tryUpdateFunctionScoreRule(ScoreRule scoreRule) {
if (!SUPPORT_RULE_TYPES.contains(scoreRule.getRuleType())) {
logger.warn("[func=ScoreRuleLogicService.tryUpdateFunctionScoreRule][ruleType={}][message=invalid rule type.]", scoreRule.getRuleType());
return;
}
String key = String.format(FUNCTION_SCORE_RULE_KEY_TEMPLATE, scoreRule.getRuleType().toLowerCase());
String srcValue = configReader.getString(key, DEFAULT_RULE_VALUES);
if (!scoreRule.getRuleValues().equals(srcValue)) {
logger.info("[func=ScoreRuleLogicService.tryUpdateFunctionScoreRule][ruleType={}][srcValue={}][newValue={}]", scoreRule.getRuleType(), srcValue, scoreRule.getRuleValues());
publishToZk(key, scoreRule.getRuleValues());
}
}
public void tryRemoveFunctionScoreRule(String ruleType) {
if (!SUPPORT_RULE_TYPES.contains(ruleType)) {
logger.warn("[func=ScoreRuleLogicService.tryRemoveFunctionScoreRule][ruleType={}][message=invalid rule type.]", ruleType);
return;
}
String key = String.format(FUNCTION_SCORE_RULE_KEY_TEMPLATE, ruleType.toLowerCase());
String srcValue = configReader.getString(key, DEFAULT_RULE_VALUES);
if (!DEFAULT_RULE_VALUES.equals(srcValue)) {
logger.info("[func=ScoreRuleLogicService.tryRemoveFunctionScoreRule][ruleType={}][srcValue={}]", ruleType, srcValue);
publishToZk(key, DEFAULT_RULE_VALUES);
}
}
private synchronized void publishToZk(String key, String value) {
try {
if (client.checkExists().forPath(CONFIG_ROOT_PATH) == null) {
client.create().creatingParentContainersIfNeeded().forPath(CONFIG_ROOT_PATH);
}
String path = CONFIG_ROOT_PATH + "/" + key;
if (this.client.checkExists().forPath(path) == null) {
this.client.create().forPath(path, value.getBytes("UTF-8"));
} else {
this.client.setData().forPath(path, value.getBytes("UTF-8"));
}
} catch (Exception e) {
logger.error("publish function score rule " + key + " to zk failed!", e);
}
}
private static final Logger logger = LoggerFactory.getLogger(ScoreRuleLogicService.class);
private static final String CONFIG_ROOT_PATH = "/yh/config";
private static final String DEFAULT_RULE_VALUES = "-1";
@Autowired
private ScoreRuleMapper scoreRuleMapper;
@Autowired
private ConfigReader configReader;
@Resource(name = "curatorFramework")
private CuratorFramework client;
@Override
public void afterPropertiesSet() throws Exception {
for (String ruleType : ScoreRuleConstants.getSupportScoreRule()) {
ScoreRule scoreRule = scoreRuleMapper.selectByRuleType(ruleType);
if (scoreRule != null) {
tryUpdateFunctionScoreRule(scoreRule);
} else {
tryRemoveFunctionScoreRule(ruleType);
}
}
}
public void tryUpdateFunctionScoreRule(ScoreRule scoreRule) {
if (!ScoreRuleConstants.isScoreRuleSupport(scoreRule.getRuleType())) {
logger.warn("[func=ScoreRuleLogicService.tryUpdateFunctionScoreRule][ruleType={}][message=invalid rule type.]", scoreRule.getRuleType());
return;
}
String key = ScoreRuleConstants.getZkDynamicConfigKey(scoreRule.getRuleType());
String srcValue = configReader.getString(key, DEFAULT_RULE_VALUES);
if (!scoreRule.getRuleValues().equals(srcValue)) {
logger.info("[func=ScoreRuleLogicService.tryUpdateFunctionScoreRule][ruleType={}][srcValue={}][newValue={}]", scoreRule.getRuleType(), srcValue,
scoreRule.getRuleValues());
publishToZk(key, scoreRule.getRuleValues());
}
}
public void tryRemoveFunctionScoreRule(String ruleType) {
if (!ScoreRuleConstants.isScoreRuleSupport(ruleType)) {
logger.warn("[func=ScoreRuleLogicService.tryRemoveFunctionScoreRule][ruleType={}][message=invalid rule type.]", ruleType);
return;
}
String key = ScoreRuleConstants.getZkDynamicConfigKey(ruleType);
String srcValue = configReader.getString(key, DEFAULT_RULE_VALUES);
if (!DEFAULT_RULE_VALUES.equals(srcValue)) {
logger.info("[func=ScoreRuleLogicService.tryRemoveFunctionScoreRule][ruleType={}][srcValue={}]", ruleType, srcValue);
publishToZk(key, DEFAULT_RULE_VALUES);
}
}
private synchronized void publishToZk(String key, String value) {
try {
if (client.checkExists().forPath(CONFIG_ROOT_PATH) == null) {
client.create().creatingParentContainersIfNeeded().forPath(CONFIG_ROOT_PATH);
}
String path = CONFIG_ROOT_PATH + "/" + key;
if (this.client.checkExists().forPath(path) == null) {
this.client.create().forPath(path, value.getBytes("UTF-8"));
} else {
this.client.setData().forPath(path, value.getBytes("UTF-8"));
}
} catch (Exception e) {
logger.error("publish function score rule " + key + " to zk failed!", e);
}
}
}
\ No newline at end of file
... ...
... ... @@ -164,6 +164,7 @@ public class ProductILogicService {
productIBO.setSellChannels(p.getSellChannels());
productIBO.setAgeLevel(p.getAgeLevel());
productIBO.setAppType(p.getAppType());
productIBO.setCouponLimitStatus(p.getCouponLimitStatus());
//品牌
this.buildBrand(brandMap,p,productIBO);
//品类
... ...