Authored by wujiexiang

需求:卖家阶梯扣点二期

package com.yohoufo.order.controller;
import com.google.common.base.Splitter;
import com.yohobuy.ufo.model.order.common.EntrySellerType;
import com.yohobuy.ufo.model.order.resp.EntryThreshold;
import com.yohobuy.ufo.model.order.resp.SellerPlatformServiceFeeResp;
import com.yohobuy.ufo.model.order.resp.SellerResp;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.annotation.IgnoreSession;
import com.yohoufo.common.annotation.IgnoreSignature;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.order.service.IStoredSellerDepositService;
... ... @@ -180,19 +177,4 @@ public class SellerController {
SellerPlatformServiceFeeResp resp = sellerService.platformServiceFeeDetail(uid);
return new ApiResponse.ApiResponseBuilder().code(200).data(resp).message("ok").build();
}
/**
* 统计表没有入驻类型,手动补充
*
* @param sellerUids 多个用,分隔
* @return
*/
@RequestMapping(params = "method=ufo.seller.orderQuantityStats.updateEnterType")
@IgnoreSession
@IgnoreSignature
@ResponseBody
public ApiResponse updateEnterTypeForOrderQuantityStats(@RequestParam("sellerUids") String sellerUids) {
sellerService.updateEnterTypeForOrderQuantityStats(Splitter.on(",").omitEmptyStrings().splitToList(sellerUids));
return new ApiResponse.ApiResponseBuilder().code(200).data(null).message("ok").build();
}
}
... ...
... ... @@ -8,26 +8,18 @@ import com.yohobuy.ufo.model.order.common.SuperEnterStageLevel;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohobuy.ufo.model.order.resp.EntryThreshold;
import com.yohobuy.ufo.model.order.resp.SellerPlatformServiceFeeResp;
import com.yohoufo.common.alarm.EventBusPublisher;
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;
import com.yohoufo.dal.order.model.SellerOrderStatsResult;
import com.yohoufo.dal.order.model.SuperEntrySeller;
import com.yohoufo.order.common.EnterQuitEnum;
import com.yohoufo.order.common.SuperEntrySellerStatus;
import com.yohoufo.order.event.SellerEnterTypeChangeEvent;
import com.yohoufo.order.model.bo.PlatformServiceFeeDefinition;
import com.yohoufo.order.model.bo.SellerPlatformServiceFee;
import com.yohoufo.order.service.IStoredSellerService;
import com.yohoufo.order.service.MerchantOrderPaymentService;
import com.yohoufo.order.service.cache.StoredSellerCacheService;
import com.yohoufo.order.service.impl.MetaConfigService;
import com.yohoufo.order.service.stats.StatsConfigManager;
import com.yohoufo.order.service.stats.impl.SellerOrderStatsConfiguration;
import com.yohoufo.order.service.stats.impl.SellerOrderStatsEntry;
import com.yohoufo.order.service.support.SellerPlatformServiceFeeSupport;
import com.yohoufo.order.utils.LoggerUtils;
import com.yohoufo.order.utils.MathUtils;
... ... @@ -77,9 +69,6 @@ public class SellerService {
private SellerEnterApplyMapper sellerEnterApplyMapper;
@Autowired
private StatsConfigManager<SellerOrderStatsEntry, SellerOrderStatsConfiguration> statsConfigurationManager;
@Autowired
private SellerPlatformServiceFeeSupport sellerPlatformServiceFeeSupport;
... ... @@ -178,8 +167,8 @@ public class SellerService {
public SellerPlatformServiceFeeResp platformServiceFeeDetail(int uid) {
logger.info("platformServiceFeeDetail uid {}", uid);
SellerPlatformServiceFee currentServiceFee, nextPeriodServiceFee;
if (!(currentServiceFee = currentPeriodSellerPlatformServiceFee(uid)).isRuleConfigured()
|| !(nextPeriodServiceFee = nextPeriodSellerPlatformServiceFee(uid)).isRuleConfigured()) {
if (!(currentServiceFee = sellerPlatformServiceFeeSupport.currentPeriod(uid, SkupType.IN_STOCK)).isRuleConfigured()
|| !(nextPeriodServiceFee = sellerPlatformServiceFeeSupport.nextPeriod(uid, SkupType.IN_STOCK)).isRuleConfigured()) {
logger.info("platformServiceFee rule is not configured,uid {}", uid);
return SellerPlatformServiceFeeResp.builder()
.nodes(Lists.newArrayList())
... ... @@ -190,9 +179,13 @@ public class SellerService {
//未到达的规则
PlatformServiceFeeDefinition.FeeRule unsatisfiedFeeRule = nextPeriodServiceFee.getDefinition().getUnsatisfiedFeeRule(nextPeriodOrderQuantity);
//扣点比例
List<PlatformServiceFeeDefinition.FeeRule> rules = new ArrayList<>(nextPeriodServiceFee.getDefinition().getRules());
//从小到大排序
rules.sort(Comparator.comparing(PlatformServiceFeeDefinition.FeeRule::getThreshold));
List<PlatformServiceFeeDefinition.FeeRule> rules = new ArrayList() {
{
addAll(nextPeriodServiceFee.getDefinition().getRules());
// //从小到大排序
sort(Comparator.comparing(PlatformServiceFeeDefinition.FeeRule::getThreshold));
}
};
//构建返回结果中的扣点规则
List<SellerPlatformServiceFeeResp.Node> nodes = rules.stream().map(rule -> {
... ... @@ -216,37 +209,6 @@ public class SellerService {
}
/**
* 当前
* @param uid
* @return
*/
private SellerPlatformServiceFee currentPeriodSellerPlatformServiceFee(int uid) {
//当前的扣点服务
SellerOrderStatsEntry currentStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).skupType(SkupType.IN_STOCK).time(DateUtil.getCurrentTimeSecond()).build();
SellerOrderStatsConfiguration currentStatsConfig = statsConfigurationManager.getStatsConfig(currentStatsEntry);
SellerOrderStatsResult statsResult = (SellerOrderStatsResult)statsConfigurationManager.getStatsProcessor(currentStatsConfig.getStatsProcessorName()).getResult(currentStatsEntry, currentStatsConfig);
return sellerPlatformServiceFeeSupport.buildSellerPlatformServiceFee(statsResult);
}
/**
* 下个周期的
*
* @param uid
* @return
*/
private SellerPlatformServiceFee nextPeriodSellerPlatformServiceFee(int uid) {
//下个周期
SellerOrderStatsEntry nextStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).skupType(SkupType.IN_STOCK).build();
SellerOrderStatsConfiguration nextStatsConfig = statsConfigurationManager.getStatsConfig(nextStatsEntry);
//设置查询时间为下个周期的开始时间
nextStatsEntry.setTime(nextStatsConfig.getStatsUnit().nextPeriodTimeTuple(nextStatsConfig.getStatsPeriod(), nextStatsConfig.getStatsPeriod()).getKey());
SellerOrderStatsResult statsResult = (SellerOrderStatsResult) statsConfigurationManager.getStatsProcessor(nextStatsConfig.getStatsProcessorName()).getResult(nextStatsEntry, nextStatsConfig);
return sellerPlatformServiceFeeSupport.buildSellerPlatformServiceFee(statsResult);
}
/**
* 获取入驻商家类型
* @param uid
* @return
... ... @@ -392,10 +354,4 @@ public class SellerService {
.attachWallet(merchantOrderPaymentService::getWalletLeftAmount);
return sellerWrapper;
}
public void updateEnterTypeForOrderQuantityStats(List<String> uids) {
uids.forEach(uid -> {
EventBusPublisher.publishEvent(SellerEnterTypeChangeEvent.builder().sellerUid(Integer.parseInt(uid)).eventType(EnterQuitEnum.ENTER).build());
});
}
}
... ...
... ... @@ -60,7 +60,7 @@ public class SellerOrderQuantityStatsProcessor implements StatsProcessor<SellerO
public SellerOrderStatsResult getResult(SellerOrderStatsEntry entry, SellerOrderStatsConfiguration configuration) {
logger.info("[{}] sellerOrderQuantityStatsProcessor getResult by entry:{}", entry.getSellerUid(), entry);
SellerOrderStatsResult result = sellerOrderStatsResultMapper.selectStatsResult(entry.getSellerUid(), configuration.getStatsCode(), entry.getTime());
logger.info("[{}] seller order stats result:{}", entry.getSellerUid(), result);
logger.info("[{}] sellerOrderQuantityStatsProcessor result:{}", entry.getSellerUid(), result);
return result;
}
}
\ No newline at end of file
... ...
package com.yohoufo.order.service.support;
import com.yoho.core.common.utils.DateUtil;
import com.yohobuy.ufo.model.order.common.EntrySellerType;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.dal.order.model.SellerOrderStatsResult;
import com.yohoufo.order.model.bo.PlatformServiceFeeDefinition;
import com.yohoufo.order.model.bo.SellerPlatformServiceFee;
import com.yohoufo.order.model.bo.SellerServiceFeeRuleDefinition;
import com.yohoufo.order.service.cache.SellerServiceFeeRuleCacheService;
import com.yohoufo.order.service.seller.setting.SellerService;
import com.yohoufo.order.service.stats.StatsConfigManager;
import com.yohoufo.order.service.stats.impl.SellerOrderStatsConfiguration;
import com.yohoufo.order.service.stats.impl.SellerOrderStatsEntry;
... ... @@ -17,9 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
/**
* Created by jiexiang.wu on 2019/7/23.
... ... @@ -35,6 +35,47 @@ public class SellerPlatformServiceFeeSupport {
@Autowired
private SellerServiceFeeRuleCacheService sellerServiceFeeRuleCacheService;
@Autowired
private SellerService sellerService;
/**
* 当前周期
*
* @param uid
* @return
*/
public SellerPlatformServiceFee currentPeriod(int uid, SkupType skupType) {
//当前的扣点服务
SellerOrderStatsEntry currentStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).skupType(skupType).time(com.yohoufo.common.utils.DateUtil.getCurrentTimeSecond()).build();
SellerOrderStatsConfiguration currentStatsConfig = statsConfigurationManager.getStatsConfig(currentStatsEntry);
SellerOrderStatsResult statsResult = (SellerOrderStatsResult) statsConfigurationManager.getStatsProcessor(currentStatsConfig.getStatsProcessorName()).getResult(currentStatsEntry, currentStatsConfig);
if (Objects.isNull(statsResult)) {
statsResult = createEmptyStatsResult(uid);
}
return this.buildSellerPlatformServiceFee(uid, statsResult);
}
/**
* 下个周期的
*
* @param uid
* @return
*/
public SellerPlatformServiceFee nextPeriod(int uid, SkupType skupType) {
//下个周期
SellerOrderStatsEntry nextStatsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).skupType(skupType).build();
SellerOrderStatsConfiguration nextStatsConfig = statsConfigurationManager.getStatsConfig(nextStatsEntry);
//设置查询时间为下个周期的开始时间
nextStatsEntry.setTime(nextStatsConfig.getStatsUnit().nextPeriodTimeTuple(nextStatsConfig.getStatsPeriod(), nextStatsConfig.getStatsPeriod()).getKey());
SellerOrderStatsResult statsResult = (SellerOrderStatsResult) statsConfigurationManager.getStatsProcessor(nextStatsConfig.getStatsProcessorName()).getResult(nextStatsEntry, nextStatsConfig);
if (Objects.isNull(statsResult)) {
statsResult = createEmptyStatsResult(uid);
}
return this.buildSellerPlatformServiceFee(uid, statsResult);
}
/**
* 获取平台技术服务费比例
*
... ... @@ -45,13 +86,8 @@ public class SellerPlatformServiceFeeSupport {
public BigDecimal getPlatformServiceFeeRate(int uid, SkupType skupType) {
logger.info("[{}] in platformServiceFeeRate,skupType:{}", uid, skupType);
//1.获取卖家统计结果
SellerOrderStatsEntry statsEntry = SellerOrderStatsEntry.builder().sellerUid(uid).skupType(skupType).time(DateUtil.getCurrentTimeSecond()).build();
SellerOrderStatsConfiguration statsConfig = statsConfigurationManager.getStatsConfig(statsEntry);
SellerOrderStatsResult statsResult = (SellerOrderStatsResult) statsConfigurationManager.getStatsProcessor(statsConfig.getStatsProcessorName()).getResult(statsEntry, statsConfig);
//2.通过统计结果获取费用定义
SellerPlatformServiceFee sellerPlatformServiceFee = buildSellerPlatformServiceFee(statsResult);
//查询当前周期的费用
SellerPlatformServiceFee sellerPlatformServiceFee = currentPeriod(uid, skupType);
//3.最终的费用
BigDecimal feeRate = sellerPlatformServiceFee.getFeeRate();
... ... @@ -60,12 +96,36 @@ public class SellerPlatformServiceFeeSupport {
return feeRate;
}
public SellerPlatformServiceFee buildSellerPlatformServiceFee(SellerOrderStatsResult statsResult) {
private SellerPlatformServiceFee buildSellerPlatformServiceFee(int uid, SellerOrderStatsResult statsResult) {
replaceEnterTypeIfNeed(statsResult);
//通过统计结果获取费用定义
PlatformServiceFeeDefinition platformServiceFeeDefinition = fetchPlatformServiceFeeDefinitionByStatsResult(statsResult);
return new SellerPlatformServiceFee(statsResult == null ? 0 : statsResult.getQuantity(),
platformServiceFeeDefinition == null ? PlatformServiceFeeDefinition.EMPTY_DEFINITION : platformServiceFeeDefinition);
return new SellerPlatformServiceFee(statsResult.getQuantity(), platformServiceFeeDefinition);
}
private SellerOrderStatsResult createEmptyStatsResult(int uid) {
SellerOrderStatsResult statsResult = new SellerOrderStatsResult();
statsResult.setUid(uid);
statsResult.setQuantity(0);
statsResult.setEnterType(-1);
return statsResult;
}
/**
* enterType < 0,使用用户当前的入驻类型
*
* @param statsResult
*/
private void replaceEnterTypeIfNeed(SellerOrderStatsResult statsResult) {
if (statsResult.getEnterType() < 0) {
logger.info("[{}] use current enterType to replace for orderStatsResult", statsResult.getUid());
//查询用户当前入驻类型
EntrySellerType entrySellerType = sellerService.getEntrySellerType(statsResult.getUid());
statsResult.setEnterType(entrySellerType.getCode());
}
}
/**
... ... @@ -75,9 +135,6 @@ public class SellerPlatformServiceFeeSupport {
* @return
*/
private PlatformServiceFeeDefinition fetchPlatformServiceFeeDefinitionByStatsResult(SellerOrderStatsResult sellerOrderStatsResult) {
if (Objects.isNull(sellerOrderStatsResult)) {
return null;
}
//平台服务费的规则定义
List<SellerServiceFeeRuleDefinition> ruleDefinitions = sellerServiceFeeRuleCacheService.getRuleDefinitions();
//按统计码、入驻类型获取特定的规则
... ... @@ -85,6 +142,6 @@ public class SellerPlatformServiceFeeSupport {
.filter(ruleDefinition -> StringUtils.equals(ruleDefinition.getStatsCode(), sellerOrderStatsResult.getStatsCode()))
.filter(ruleDefinition -> ruleDefinition.getEnterType() == sellerOrderStatsResult.getEnterType())
.map(ruleDefinition -> ruleDefinition.getServiceFeeDefinition()).findFirst();
return psfdOp.isPresent() ? psfdOp.get() : null;
return psfdOp.isPresent() ? psfdOp.get() : PlatformServiceFeeDefinition.EMPTY_DEFINITION;
}
}
... ...
package com.yohoufo.order.service.seller;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohobuy.ufo.model.order.resp.SellerPlatformServiceFeeResp;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.dal.order.model.BuyerOrder;
... ... @@ -10,10 +11,13 @@ import com.yohoufo.order.event.SellerEnterTypeChangeEvent;
import com.yohoufo.order.service.listener.BuyerOrderChangeEvent;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.seller.setting.SellerService;
import com.yohoufo.order.service.support.SellerPlatformServiceFeeSupport;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
public class SellerEnterTypeChangeEventTest extends BaseWebTest {
@Autowired
... ... @@ -22,6 +26,9 @@ public class SellerEnterTypeChangeEventTest extends BaseWebTest {
@Autowired
private SellerService sellerService;
@Autowired
private SellerPlatformServiceFeeSupport sellerPlatformServiceFeeSupport;
@Test
public void test_stats_event() {
BuyerOrder buyerOrder = new BuyerOrder();
... ... @@ -47,6 +54,12 @@ public class SellerEnterTypeChangeEventTest extends BaseWebTest {
SellerPlatformServiceFeeResp sellerPlatformServiceFeeResp = sellerService.platformServiceFeeDetail(500031424);
System.out.println(sellerPlatformServiceFeeResp);
Assert.assertNotNull(sellerPlatformServiceFeeResp);
Assert.assertEquals(sellerPlatformServiceFeeResp.getCurrentRate(),"5.0%");
Assert.assertEquals(sellerPlatformServiceFeeResp.getCurrentRate(), "5.0%");
}
@Test
public void getPlatformServiceFeeRate() {
BigDecimal feeRate = sellerPlatformServiceFeeSupport.getPlatformServiceFeeRate(500031424, SkupType.IN_STOCK);
Assert.assertEquals(feeRate.toPlainString(),"0.049");
}
}
... ...