Authored by wujiexiang

求购变现平台服务费

package com.yohoufo.order.controller;
import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.order.constants.BidTimeLimit;
import com.yohoufo.order.model.request.BuyerBidChangePriceRequest;
import com.yohoufo.order.model.request.BuyerBidPublishRequest;
import com.yohoufo.order.model.response.BidComputeResponse;
import com.yohoufo.order.model.response.BidConfigResponse;
import com.yohoufo.order.model.response.BidPrePublishResponse;
import com.yohoufo.order.model.response.BidPublishResponse;
import com.yohoufo.order.model.response.*;
import com.yohoufo.order.service.impl.BuyerBidPublishService;
import com.yohoufo.order.service.impl.BuyerBidPriceService;
import com.yohoufo.order.service.seller.processor.PriceComputePrepareProcessor;
import com.yohoufo.order.utils.LoggerUtils;
import com.yohoufo.order.utils.MathUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -20,6 +19,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.List;
@RestController
@RequestMapping(value = "/shopping/bid")
public class BuyerBidController {
... ... @@ -42,7 +44,30 @@ public class BuyerBidController {
*/
@RequestMapping(params = "method=ufo.buyer.bid.config")
public ApiResponse config() {
return new ApiResponse.ApiResponseBuilder().code(200).data(new BidConfigResponse()).message("ok").build();
BidConfigResponse response = new BidConfigResponse();
List<PromotionFormula> promotionFormulaList = new LinkedList<>();
//商品金额
PromotionFormula goodsFormula = new PromotionFormula();
goodsFormula.setPromotion(OrderConstant.GOODS_PRICE);
goodsFormula.setPromotionAmount(MathUtils.formatCurrencyStr(0));
promotionFormulaList.add(goodsFormula);
//运费
PromotionFormula expressFormula = new PromotionFormula();
expressFormula.setPromotion(OrderConstant.DELIVERY_DESC);
expressFormula.setPromotionAmount(MathUtils.formatCurrencyStr(0));
promotionFormulaList.add(expressFormula);
//最终金额
PromotionFormula finalAmountFormula = new PromotionFormula();
finalAmountFormula.setPromotion(OrderConstant.GOODS_REAL_PRICE);
finalAmountFormula.setPromotionAmount(MathUtils.formatCurrencyStr(0));
promotionFormulaList.add(finalAmountFormula);
response.setPromotionFormulaList(promotionFormulaList);
return new ApiResponse.ApiResponseBuilder().code(200).data(response).message("ok").build();
}
/**
... ...
... ... @@ -3,6 +3,7 @@ package com.yohoufo.order.model.bo;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.order.common.EntrySellerType;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.order.model.response.BidComputeResponse;
import lombok.extern.slf4j.Slf4j;
... ... @@ -26,21 +27,11 @@ public abstract class Account {
}
/**
* 余额是否足够
*
* @param amount
* @return
*/
public boolean isBalanceEnough(BigDecimal amount) {
return true;
}
/**
* 检测账户余额是否足够,不足够抛出异常
*
* @param amount
*/
public void checkBalanceEnough(BigDecimal amount) {
public void checkBalanceEnough(BigDecimal amount, SkupType skupType) {
}
/**
... ...
... ... @@ -6,6 +6,8 @@ import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohobuy.ufo.model.order.common.EntrySellerType;
import com.yohobuy.ufo.model.order.common.SellerFuncEnum;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.dal.order.model.SellerWallet;
import com.yohoufo.dal.order.model.SellerWalletDetail;
... ... @@ -46,7 +48,6 @@ public class WalletAccount extends Account {
* @param earestMoney
* @return
*/
@Override
public boolean isBalanceEnough(BigDecimal earestMoney) {
if (!SellerHelper.isSuper(entrySellerType)) {
return sellerAuthCheckService.isEnough(uid, earestMoney);
... ... @@ -56,10 +57,13 @@ public class WalletAccount extends Account {
}
@Override
public void checkBalanceEnough(BigDecimal earestMoney) {
public void checkBalanceEnough(BigDecimal earestMoney, SkupType skupType) {
//操作金额校验
sellerAuthCheckService.checkAuth(uid, skupType, SellerFuncEnum.BATCH_PUBLISH);
//本次保证金额校验
if (!isBalanceEnough(earestMoney)) {
log.warn("[{}] checkBalanceEnough,wallet is not enough,earestMoney {}",
uid, earestMoney);
log.warn("balance is not enough, uid {} mEarestMoney {}", uid, earestMoney);
throw new ServiceException(ServiceError.WALLET_EARNESTMONEY_IS_NOT_ENOUGH);
}
}
... ...
... ... @@ -25,9 +25,13 @@ public class ServiceFeeRate {
* 暂定5%,后期可调整,上线初期为0,
* 后期活动可根据活动进行减免,每个卖家可收费不一样
* )
* 平台服务费占比 根据货款计算
*/
BigDecimal goodsPaymentRate;// = new BigDecimal(0.05D).setScale(2, BigDecimal.ROUND_HALF_UP);
/**
* 平台服务费占比 范围
*/
PriceRange goodsPaymentPriceRange;
/**
... ... @@ -37,6 +41,7 @@ public class ServiceFeeRate {
/**
* 支付渠道费,调用银联支付接口时实时扣款
* (支付宝0.55%、微信均为0.6%,统一对用户收取0.6%,前期优惠策略可暂定0)
* 银行
*/
BigDecimal payChannelRate ;//= new BigDecimal(0.006D).setScale(4, BigDecimal.ROUND_HALF_UP);
... ...
... ... @@ -15,6 +15,11 @@ public class BidConfigResponse {
//时限
private TimeLimit timeLimit = TIME_LIMIT;
/**
* 费用列表
*/
List<PromotionFormula> promotionFormulaList;
private static final TimeLimit TIME_LIMIT = new TimeLimit();
@Data
public static class TimeLimit {
... ...
... ... @@ -88,6 +88,7 @@ public class CacheKeyBuilder {
SELLER_SALE_PRICE_LIMIT("ufo:order:seller:salePrice:limit:config",""),
//买家求购
BUYER_BID_CONFIG("ufo:order:buyer:bid:config",""),
SELLER_BID_GOODS_FEE_RATE("ufo:order:seller:bid:goods:service:feeRate", ""),
DISTRIBUTED_LOCK_DEPOSIT_GOODS(DISTRIBUTED_LOCK_PREFIX, "depositCode:{}"),
... ...
... ... @@ -384,4 +384,23 @@ public class MetaConfigService {
String configVal = new DataProcesser(rkb, key, ExpiredTime.ORDER_BASE_CONFIG).getConfigVal();
return BuyerBidConfig.convert(configVal);
}
/**
* {"inStock": {"goodsPaymentRate": 0.047,"earnestMoneyRate": 0.01,"payChannelRate": 0.01}}
* @return
*/
public Map<String,ServiceFeeRate> getSellerBidGoodsFeeRate(){
CacheKeyBuilder.KeyTemp kt = CacheKeyBuilder.KeyTemp.SELLER_BID_GOODS_FEE_RATE;
RedisKeyBuilder rkb = kt.builderKeyOnlyFixed();
final String key = MetaConfigKey.SELLER_GOODS_FEE_RATE;
String configVal = new DataProcesser(rkb, key, ExpiredTime.ORDER_BASE_CONFIG).getConfigVal();
Map<String,ServiceFeeRate> sfrMap = new HashMap<String,ServiceFeeRate>(10);
try{
sfrMap = JSONObject.parseObject(configVal, new TypeReference<Map<String,ServiceFeeRate>>(){});
}catch (Exception ex){
logger.warn("in getServiceFeeRate parseObject fail, metaVal {}", configVal, ex);
}
return sfrMap;
}
}
... ...
package com.yohoufo.order.service.impl;
import com.google.common.collect.Lists;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.BidStoragePriceVo;
import com.yohobuy.ufo.model.order.bo.PrdPrice;
import com.yohobuy.ufo.model.order.bo.SoldPrdComputeBo;
import com.yohobuy.ufo.model.order.common.CancelType;
import com.yohobuy.ufo.model.order.common.OrderCodeType;
... ... @@ -20,6 +20,7 @@ import com.yohoufo.order.model.bo.Account;
import com.yohoufo.order.model.bo.AccountPayResult;
import com.yohoufo.order.model.bo.SubmitSellerOrder;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.ServiceFeeRate;
import com.yohoufo.order.model.request.PrdQueryReq;
import com.yohoufo.order.model.request.SellerBidPublishRequest;
import com.yohoufo.order.model.response.OrderSubmitResp;
... ... @@ -30,17 +31,16 @@ import com.yohoufo.order.service.proxy.ResourcesProxyService;
import com.yohoufo.order.service.proxy.UserProxyService;
import com.yohoufo.order.service.seller.OrderComputeHandler;
import com.yohoufo.order.service.seller.OrderComputeProvider;
import com.yohoufo.order.service.seller.fee.GoodsAmountService;
import com.yohoufo.order.service.seller.processor.PriceComputePrepareProcessor;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.utils.AddressHelper;
import com.yohoufo.order.utils.LoggerUtils;
import com.yohoufo.order.utils.SellerGoodsHelper;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
... ... @@ -56,9 +56,6 @@ public class SellerBidPublishService {
private BidProductProxyService bidProductProxyService;
@Autowired
private GoodsAmountService goodsAmountService;
@Autowired
private OrderComputeProvider orderComputeProvider;
@Autowired
... ... @@ -80,6 +77,9 @@ public class SellerBidPublishService {
private SellerBidOrderBindService sellerBidOrderBindService;
@Autowired
private MetaConfigService metaConfigService;
@Autowired
private CacheCleaner cacheCleaner;
... ... @@ -101,7 +101,7 @@ public class SellerBidPublishService {
//3.检测入驻用户账户保证金
Account account = accountFactory.get(uid);
account.checkBalanceEnough(computeResult.getEarnestMoney().getEarnestMoney());
account.checkBalanceEnough(computeResult.getEarnestMoney().getEarnestMoney(), SkupType.getSkupType(saleableBidSkup.getAttribute()));
//4.返回结果
Supplier<Map<String, String>> tipsConfigSupplier = () -> resourcesProxyService.getServiceTipsConfig();
return SellerOrderConvertor.computeResult2SoldPrdComputeBo(computeResult, tipsConfigSupplier);
... ... @@ -120,11 +120,11 @@ public class SellerBidPublishService {
int storageId = saleableBidSkup.getStorageId();
SkupType skupType = SkupType.getSkupType(saleableBidSkup.getAttribute());
logger.info("[{}] compute seller bid skup fee,skup:{},storageId:{},skupType:{}", uid, saleableBidSkup.getSkup(), storageId, skupType);
boolean isImperfect = SellerGoodsHelper.isImperfectGoods(skupType);
PrdQueryReq pqr = PrdQueryReq.builder().uid(uid)
.storageId(storageId).prdPrice(saleableBidSkup.getPrice()).build();
PrdPrice prdPrice = isImperfect ? priceComputePrepareProcessor.checkPriceRange(pqr, true) : priceComputePrepareProcessor.checkPulishAuthNPriceRange(pqr, true);
SellerOrderComputeResult pcc = goodsAmountService.getGoodsServiceFeeRate(uid, storageId, prdPrice, skupType);
priceComputePrepareProcessor.checkPulishAuthNPriceRange(pqr, true);
SellerOrderComputeResult pcc = getSellerBidGoodsFeeRate(uid, skupType);
OrderComputeHandler computeHandler = orderComputeProvider.findBySkupType(skupType);
SellerOrderComputeResult computeResult = computeHandler.compute(saleableBidSkup.getPrice(), pcc);
... ... @@ -147,7 +147,7 @@ public class SellerBidPublishService {
//3.检测入驻用户账户保证金
Account account = accountFactory.get(uid);
account.checkBalanceEnough(computeResult.getEarnestMoney().getEarnestMoney());
account.checkBalanceEnough(computeResult.getEarnestMoney().getEarnestMoney(), SkupType.getSkupType(saleableBidSkup.getAttribute()));
int skup = saleableBidSkup.getSkup();
//先占库存
... ... @@ -212,4 +212,23 @@ public class SellerBidPublishService {
return Pair.of(noHiddenBackAddress, hiddenBackAddress);
}
public SellerOrderComputeResult getSellerBidGoodsFeeRate(int uid, SkupType skupType) {
logger.info("in getSellerBidGoodsFeeRate uid {}, skupType {}",
uid, skupType);
ServiceFeeRate rate = getSellerBidGoodsFeeRate(skupType);
List<ServiceFeeRate> allConfig = Lists.newArrayList(rate);
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
return socr;
}
public ServiceFeeRate getSellerBidGoodsFeeRate(SkupType skupType) {
Map<String, ServiceFeeRate> sfrMap = metaConfigService.getSellerBidGoodsFeeRate();
String key = skupType.getLocalCacheKey();
ServiceFeeRate sft = sfrMap.get(key);
logger.info("getBidGoodsServiceFeeRate from local cache, skupType {} ServiceFeeRate {}", skupType, sft);
return sft;
}
}
... ...