Authored by wujiexiang

Merge branch 'dev-seller-order-stat-6.9.9' into test6.9.9

... ... @@ -7,7 +7,7 @@
<result column="uid" property="uid" jdbcType="INTEGER"/>
<result column="begin_time" property="beginTime" jdbcType="INTEGER"/>
<result column="end_time" property="endTime" jdbcType="INTEGER"/>
<result column="quantity" property="statsPeriod" jdbcType="INTEGER"/>
<result column="quantity" property="quantity" jdbcType="INTEGER"/>
</resultMap>
<sql id="Base_Column_List">
id, stats_code, uid, begin_time, end_time, quantity
... ...
... ... @@ -3,12 +3,9 @@ package com.yohoufo.order.model.bo;
import com.yohoufo.order.utils.BeanTool;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.*;
/**
* Created by jiexiang.wu on 2019/7/23.
... ... @@ -18,8 +15,20 @@ import java.util.List;
@ToString
public class PlatformServiceFeeDefinition {
//费用规则
private List<FeeRule> rules;
//费用规则 按照threshold从小到大排序
private List<FeeRule> rules = new ArrayList<>();
/**
* 排序
*
* @param comparator
*/
private void sortRules(Comparator comparator) {
if (Objects.isNull(rules)) {
rules = new ArrayList<>();
}
rules.sort(comparator);
}
/**
* 根据阀值获取对应的折扣
... ... @@ -28,13 +37,6 @@ public class PlatformServiceFeeDefinition {
* @return
*/
public BigDecimal getFeeRate(int threshold) {
if (CollectionUtils.isEmpty(rules)) {
return null;
}
//nodes排序 按照threshold从大到小排序
rules.sort(Comparator.comparing(FeeRule::getThreshold).reversed());
for (FeeRule rule : rules) {
if (threshold >= rule.getThreshold()) {
return rule.getRate();
... ... @@ -44,12 +46,37 @@ public class PlatformServiceFeeDefinition {
return null;
}
public Collection<FeeRule> getRules() {
return Collections.unmodifiableCollection(rules);
}
/**
* 获取下一个未满足的扣点规则
*
* @param threshold
* @return
*/
public FeeRule getUnsatisfiedFeeRule(int threshold) {
//必须确保 rules 从大到小排序的
for (int i = 0; i < rules.size(); i++) {
FeeRule rule = rules.get(i);
if (threshold >= rule.getThreshold()) {
//满足当前规则,上一个规则一定不满足
return rules.get(Math.max(0, i - 1));
}
}
return null;
}
public static PlatformServiceFeeDefinition convert(String json) {
if (StringUtils.isEmpty(json)) {
return new PlatformServiceFeeDefinition();
} else {
return BeanTool.string2Value(json, PlatformServiceFeeDefinition.class);
PlatformServiceFeeDefinition definition = BeanTool.string2Value(json, PlatformServiceFeeDefinition.class);
//从大到小排序
definition.sortRules(Comparator.comparing(FeeRule::getThreshold).reversed());
return definition;
}
}
... ...
... ... @@ -2,6 +2,7 @@ package com.yohoufo.order.model.bo;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.collections.CollectionUtils;
import java.math.BigDecimal;
... ... @@ -23,6 +24,14 @@ public class SellerPlatformServiceFee {
}
/**
* 规则是否配置了
* @return
*/
public boolean isRuleConfigured() {
return CollectionUtils.isNotEmpty(definition.getRules());
}
/**
* 费用比例
*
* @return
... ...
... ... @@ -73,12 +73,12 @@ public class SellerOrderStatsConfigCacheService {
});
}
public SellerOrderStatsConfiguration findBy(OrderAttributes orderAttributes) {
public Optional<SellerOrderStatsConfiguration> findBy(OrderAttributes orderAttributes) {
List<SellerOrderStatsConfiguration> configurations = (List) localCache.get(SELLER_ORDER_STATS_CONFIG_KEY);
if (CollectionUtils.isEmpty(configurations)) {
return null;
return Optional.ofNullable(null);
}
Optional<SellerOrderStatsConfiguration> optional = configurations.stream().filter(config -> config.getOrderAttributes().contains(orderAttributes)).findFirst();
return optional.isPresent() ? optional.get() : null;
return optional;
}
}
... ...
... ... @@ -9,6 +9,7 @@ import com.yohobuy.ufo.model.order.common.SuperEnterStageLevel;
import com.yohobuy.ufo.model.order.resp.EntryThreshold;
import com.yohobuy.ufo.model.order.resp.SellerPlatformServiceFeeResp;
import com.yohoufo.common.cache.CacheKeyEnum;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.SellerEnterApplyMapper;
import com.yohoufo.dal.order.StoredSellerMapper;
import com.yohoufo.dal.order.SuperEntrySellerMapper;
... ... @@ -27,6 +28,7 @@ import com.yohoufo.order.utils.LoggerUtils;
import com.yohoufo.order.utils.MathUtils;
import com.yohoufo.order.utils.SellerHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -167,30 +169,25 @@ public class SellerService {
* @return
*/
public SellerPlatformServiceFeeResp platformServiceFeeDetail(int uid) {
logger.info("platformServiceFee uid {}", uid);
SellerPlatformServiceFee currentServiceFee = getCurrentTimeSellerPlatformServiceFee(uid);
SellerOrderStatsEntry statsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).orderAttribute(OrderAttributes.COMMON_IN_STOCK).build();
SellerOrderStatsConfiguration statsConfig = statsConfigurationManager.getStatsConfig(statsEntry);
SellerPlatformServiceFee serviceFee = (SellerPlatformServiceFee) statsConfigurationManager.getStatsProcessor(statsConfig.getStatsProcessorName()).apply(statsEntry, statsConfig);
SellerPlatformServiceFee nextPeriodServiceFee = getNextPeriodSellerPlatformServiceFee(uid);
if (Objects.isNull(serviceFee)) {
logger.info("platformServiceFee is null for uid {}", uid);
if (!currentServiceFee.isRuleConfigured() || !nextPeriodServiceFee.isRuleConfigured()) {
logger.info("platformServiceFee rule is not configured,uid {}", uid);
return SellerPlatformServiceFeeResp.builder()
.currentMonthRate(null)
.nodes(Lists.newArrayList())
.orderQuantity(0)
.build();
}
//当前完成的数量,在下个周期使用
int nextPeriodOrderQuantity = nextPeriodServiceFee.getOrderQuantity();
//未到达的规则
PlatformServiceFeeDefinition.FeeRule unsatisfiedFeeRule = nextPeriodServiceFee.getDefinition().getUnsatisfiedFeeRule(nextPeriodOrderQuantity);
//扣点比例
List<PlatformServiceFeeDefinition.FeeRule> rules = serviceFee.getDefinition().getRules();
List<PlatformServiceFeeDefinition.FeeRule> rules = new ArrayList<>(nextPeriodServiceFee.getDefinition().getRules());
//从小到大排序
rules.sort(Comparator.comparing(PlatformServiceFeeDefinition.FeeRule::getThreshold));
List<SellerPlatformServiceFeeResp.Node> nodes = rules.stream().map(rule -> {
SellerPlatformServiceFeeResp.Node node = new SellerPlatformServiceFeeResp.Node();
node.setKey(rule.getThreshold());
... ... @@ -198,17 +195,46 @@ public class SellerService {
return node;
}).collect(Collectors.toList());
SellerPlatformServiceFeeResp resp = SellerPlatformServiceFeeResp.builder()
.currentMonthRate(MathUtils.convert2Percent(serviceFee.getFeeRate()))
.currentRate(MathUtils.convert2Percent(currentServiceFee.getFeeRate()))
.nodes(nodes)
.orderQuantity(serviceFee.getOrderQuantity())
.finishedOrderQuantity(nextPeriodOrderQuantity)
.nextRateToReach(MathUtils.convert2Percent(unsatisfiedFeeRule.getRate()))
.nextRateRequiredIncOrderQuantity(Math.max(0, unsatisfiedFeeRule.getThreshold() - nextPeriodOrderQuantity))
.build();
logger.info("platformServiceFee uid {},resp {}", uid, resp);
return resp;
}
/**
* 当前
* @param uid
* @return
*/
private SellerPlatformServiceFee getCurrentTimeSellerPlatformServiceFee(int uid) {
//当前的扣点服务
SellerOrderStatsEntry currentStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).orderAttribute(OrderAttributes.COMMON_IN_STOCK).time(DateUtil.getCurrentTimeSecond()).build();
SellerOrderStatsConfiguration currentStatsConfig = statsConfigurationManager.getStatsConfig(currentStatsEntry);
return (SellerPlatformServiceFee)statsConfigurationManager.getStatsProcessor(currentStatsConfig.getStatsProcessorName()).apply(currentStatsEntry, currentStatsConfig);
}
/**
* 下个周期的
*
* @param uid
* @return
*/
private SellerPlatformServiceFee getNextPeriodSellerPlatformServiceFee(int uid) {
//下个周期
SellerOrderStatsEntry nextStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).orderAttribute(OrderAttributes.COMMON_IN_STOCK).build();
SellerOrderStatsConfiguration nextStatsConfig = statsConfigurationManager.getStatsConfig(nextStatsEntry);
Pair<Integer, Integer> nextValidityTimeTuple = nextStatsConfig.getStatsUnit().getValidityTimeTuple(nextStatsConfig.getStatsPeriod(), nextStatsConfig.getStatsPeriod());
//设置查询时间为下个周期的开始时间
nextStatsEntry.setTime(nextValidityTimeTuple.getKey());
return (SellerPlatformServiceFee) statsConfigurationManager.getStatsProcessor(nextStatsConfig.getStatsProcessorName()).apply(nextStatsEntry, nextStatsConfig);
}
/**
... ...
... ... @@ -18,11 +18,21 @@ public interface StatsProcessor<T extends StatsEntry, U extends StatsConfigurati
String getName();
/**
* 执行动作
* 执行动作
*
* @param t
* @param u
*/
@Override
void accept(T t, U u);
/**
* 获取结果
*
* @param t
* @param u
* @return
*/
@Override
R apply(T t, U u);
}
... ...
package com.yohoufo.order.service.stats.impl;
import com.yohoufo.order.model.bo.PlatformServiceFeeDefinition;
import com.yohoufo.order.model.bo.SellerPlatformServiceFee;
import com.yohoufo.order.service.stats.StatsProcessor;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
... ... @@ -10,7 +12,7 @@ import org.springframework.stereotype.Service;
* nothing to do
*/
@Service
public class EmptyStatsProcessor implements StatsProcessor<SellerOrderStatsEntry, SellerOrderStatsConfiguration, Void> {
public class EmptyStatsProcessor implements StatsProcessor<SellerOrderStatsEntry, SellerOrderStatsConfiguration, SellerPlatformServiceFee> {
private Logger logger = LoggerUtils.getSellerOrderLogger();
... ... @@ -21,12 +23,12 @@ public class EmptyStatsProcessor implements StatsProcessor<SellerOrderStatsEntry
@Override
public void accept(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("accept entry:{},configuration:{},nothing to do", entry, configuration);
logger.info("emptyStatsProcessor accept entry:{},configuration:{},nothing to do", entry, configuration);
}
@Override
public Void apply(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("apply entry:{},configuration:{},nothing to do", entry, configuration);
return null;
public SellerPlatformServiceFee apply(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("emptyStatsProcessor apply entry:{},configuration:{},nothing to do", entry, configuration);
return new SellerPlatformServiceFee(0, new PlatformServiceFeeDefinition());
}
}
... ...
package com.yohoufo.order.service.stats.impl;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.SellerOrderStatsResultMapper;
import com.yohoufo.dal.order.model.SellerOrderStatsResult;
import com.yohoufo.order.model.bo.PlatformServiceFeeDefinition;
... ... @@ -31,7 +30,7 @@ public class SellerOrderQuantityStatsProcessor implements StatsProcessor<SellerO
@Override
public void accept(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("accept entry:{},configuration:{}", entry, configuration);
logger.info("sellerOrderQuantityStatsProcessor accept entry:{},configuration:{}", entry, configuration);
Pair<Integer, Integer> timeTuple = configuration.getStatsUnit().getValidityTimeTuple(configuration.getStatsPeriod(), configuration.getStatsPeriod());
... ... @@ -53,12 +52,12 @@ public class SellerOrderQuantityStatsProcessor implements StatsProcessor<SellerO
@Override
public SellerPlatformServiceFee apply(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("apply entry:{},configuration:{}", entry, configuration);
SellerOrderStatsResult result = sellerOrderStatsResultMapper.selectStatsResult(entry.getSellerUid(), configuration.getStatsCode(), DateUtil.getCurrentTimeSecond());
logger.info("sellerOrderQuantityStatsProcessor apply entry:{},configuration:{}", entry, configuration);
SellerOrderStatsResult result = sellerOrderStatsResultMapper.selectStatsResult(entry.getSellerUid(), configuration.getStatsCode(), entry.getTime());
int quantity = (result != null) ? result.getQuantity() : 0;
PlatformServiceFeeDefinition psfd = PlatformServiceFeeDefinition.convert(configuration.getActionParam());
SellerPlatformServiceFee serviceFee = new SellerPlatformServiceFee(quantity, psfd);
logger.info("seller platform service fee is:{},statsResult:{},entry:{}", serviceFee, result, entry);
logger.info("[{}] seller platform service statsResult:{}", entry.getSellerUid(),result);
return serviceFee;
}
}
\ No newline at end of file
... ...
... ... @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Objects;
import java.util.Optional;
/**
* Created by jiexiang.wu on 2019/7/19.
... ... @@ -36,12 +36,12 @@ public class SellerOrderStatsConfigurationManager implements StatsConfigManager<
@Override
public SellerOrderStatsConfiguration getStatsConfig(SellerOrderStatsEntry statsEntry) {
SellerOrderStatsConfiguration configuration = sellerOrderStatsConfigCacheService.findBy(statsEntry.getOrderAttribute());
if (Objects.isNull(configuration) || configuration.getExcludeUids().stream().anyMatch(uid -> uid == statsEntry.getSellerUid())) {
Optional<SellerOrderStatsConfiguration> configurationOp = sellerOrderStatsConfigCacheService.findBy(statsEntry.getOrderAttribute());
if (!configurationOp.isPresent() || configurationOp.get().getExcludeUids().stream().anyMatch(uid -> uid == statsEntry.getSellerUid())) {
// 没有找到配置项或卖家被排除
return SellerOrderStatsConfiguration.emptyConfiguration;
}
return configuration;
return configurationOp.get();
}
@Override
... ...
... ... @@ -18,4 +18,6 @@ public class SellerOrderStatsEntry implements StatsEntry {
private int buyerUid;
private long buyerOrderCode;
private OrderAttributes orderAttribute;
//查询时间
private int time;
}
... ...
package com.yohoufo.order.service.support;
import com.google.common.collect.Lists;
import com.yoho.core.common.utils.DateUtil;
import com.yohobuy.ufo.model.order.common.OrderAttributes;
import com.yohobuy.ufo.model.order.resp.SellerPlatformServiceFeeResp;
import com.yohoufo.order.model.bo.SellerPlatformServiceFee;
import com.yohoufo.order.service.stats.StatsConfigManager;
import com.yohoufo.order.service.stats.impl.SellerOrderStatsConfiguration;
... ... @@ -13,7 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Objects;
/**
* Created by jiexiang.wu on 2019/7/23.
... ... @@ -35,16 +33,13 @@ public class SellerPlatformServiceFeeSupport {
*/
public BigDecimal getPlatformServiceFeeRate(int uid, OrderAttributes orderAttributes) {
logger.info("platformServiceFeeRate,uid {}, attribute:{}", uid, orderAttributes);
SellerOrderStatsEntry statsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).orderAttribute(orderAttributes).build();
SellerOrderStatsEntry statsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).orderAttribute(orderAttributes).time(DateUtil.getCurrentTimeSecond()).build();
SellerOrderStatsConfiguration statsConfig = statsConfigurationManager.getStatsConfig(statsEntry);
SellerPlatformServiceFee serviceFee = (SellerPlatformServiceFee) statsConfigurationManager.getStatsProcessor(statsConfig.getStatsProcessorName()).apply(statsEntry, statsConfig);
if (Objects.isNull(serviceFee)) {
logger.info("platformServiceFeeRate is null for uid {}", uid);
return null;
}
return serviceFee.getFeeRate();
}
}
... ...