Authored by chenchao

use push sdk 2 send msg

... ... @@ -79,4 +79,17 @@ public interface SellerOrderGoodsViewMapper {
SellerOrderGoods selectAvgPriceOfPrd(@Param("storageId")int storageId, @Param("limit")int limit);
SellerOrderGoods selectLeastPriceOfSku(@Param("storageId")int storageId,
@Param("statusList") List<Integer> statusList,
@Param("skupTypes")Collection<Integer> skupTypes);
int selectCntOfSku(@Param("storageId")int storageId,
@Param("statusList") List<Integer> statusList,
@Param("skupTypes")Collection<Integer> skupTypes);
List selectUserOfSku(@Param("storageId")int storageId,
@Param("statusList") List<Integer> statusList,
@Param("skupTypes")Collection<Integer> skupTypes);
}
... ...
... ... @@ -237,4 +237,36 @@
limit #{limit}
</select>
<select id="selectLeastPriceOfSku" resultMap="BaseResultMap">
SELECT min(goods_price) goods_price FROM seller_order_goods
WHERE <include refid="where_sku_attr_status" />
</select>
<select id="selectCntOfSku" resultType="int">
SELECT count(*) FROM seller_order_goods
WHERE <include refid="where_sku_attr_status" />
</select>
<select id="selectUserOfSku" resultType="list">
SELECT uid FROM seller_order_goods
WHERE <include refid="where_sku_attr_status" /> group by uid
</select>
<sql id="where_sku_attr_status" >
storage_id = #{storageId,jdbcType=INTEGER}
and attributes in
<foreach collection="skupTypes" item="skupType" open="(" close=")" separator=",">
#{skupType,jdbcType=INTEGER}
</foreach>
and status in
<foreach item="status" index="index" collection="statusList" open="(" separator="," close=")">
#{status, jdbcType=TINYINT}
</foreach>
and bid_type = 0
</sql>
</mapper>
\ No newline at end of file
... ...
... ... @@ -29,6 +29,12 @@
<groupId>com.yohoufo.fore</groupId>
<artifactId>yohoufo-fore-inboxclient</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.dsf</groupId>
<artifactId>yoho-msgcenter-sdk</artifactId>
<version>1.0.3-SNAPSHOT</version>
</dependency>
</dependencies>
... ...
package com.yohoufo.msg.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PrdMsg {
private Integer productId;
private String prdName;
private String sizeName;
private String productCode;
private String price;
}
... ...
package com.yohoufo.msg.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.msgcenter.sdk.dto.MessageCenterEvent;
import com.yoho.msgcenter.sdk.handler.MsgCenterHandlerImpl;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.dal.product.model.Product;
import com.yohoufo.msg.cache.CacheKeyBuilder;
import com.yohoufo.msg.concurrent.ThreadPoolFactory;
import com.yohoufo.msg.config.CaseIdConfig;
import com.yohoufo.msg.model.NoticeCaseNode;
import com.yohoufo.msg.model.NoticeRuleNode;
import com.yohoufo.msg.model.PrdMsg;
import com.yohoufo.msg.service.limit.RedisLimitStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -15,7 +21,6 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
/**
... ... @@ -32,9 +37,17 @@ public class MsgService {
@Autowired
private RedisLimitStrategy redisLimitStrategy;
@Autowired
private MsgCenterHandlerImpl msgCenterHandler;
public void noticeSellerWhenBuyerBidSuccess(List<Integer> uidList, SellerOrderGoods sellerOrderGoods){
/**
* TODO 优化点:需要考虑如何批量化
* @param uidList
* @param sellerOrderGoods
* @param product
*/
public void noticeSellerWhenBuyerBidSuccess(List<Integer> uidList, SellerOrderGoods sellerOrderGoods, Product product){
Integer storageId = sellerOrderGoods.getStorageId();
NoticeCaseNode ncNode = noticeCaseService.getNoticeCaseNode(CaseIdConfig.BUYER_BID_SUCCESS_NOTICE_SELLER);
Map<Integer, NoticeRuleNode> noticeRuleNodeMap = ncNode.getNoticeRuleNodeMap();
... ... @@ -43,7 +56,7 @@ public class MsgService {
for(Integer uid : uidList) {
RedisKeyBuilder rkb = CacheKeyBuilder.bidOrderNoticeSellerKey(uid, caseId);
//use thread pool to control
executorService.submit(()->redisLimitStrategy.checkLimit(uid, storageId, rkb, noticeRuleNodeMap, () -> sendPush2Seller(uid,sellerOrderGoods)));
executorService.submit(()->redisLimitStrategy.checkLimit(uid, storageId, rkb, noticeRuleNodeMap, () -> sendPush2Seller(uid,sellerOrderGoods, product)));
}
long taskCount = executorService.getTaskCount();
... ... @@ -58,8 +71,11 @@ public class MsgService {
* @param sellerOrderGoods
* @return
*/
private int sendPush2Seller(Integer uid, SellerOrderGoods sellerOrderGoods){
private int sendPush2Seller(Integer uid, SellerOrderGoods sellerOrderGoods, Product product){
MessageCenterEvent centerEvent = buildCommonPrdMsg(uid, sellerOrderGoods, product);
centerEvent.setSendScene("UFO_BIDORDER_PAID_SUCCESS");
centerEvent.setSecurityKey("df09fe86-7499-4ef9-a99b-d9c8a0fb5f01");
msgCenterHandler.send(centerEvent);
return -1;
}
... ... @@ -69,8 +85,29 @@ public class MsgService {
* @param sellerOrderGoods
* @return
*/
private int sendPush2Buyer(Integer uid, SellerOrderGoods sellerOrderGoods){
private int sendPush2Buyer(Integer uid, SellerOrderGoods sellerOrderGoods, Product product){
MessageCenterEvent centerEvent = buildCommonPrdMsg(uid, sellerOrderGoods, product);
centerEvent.setSendScene("UFO_BIDORDER_SELLER_ONSHELVE");
centerEvent.setSecurityKey("7df7714f-f3b6-4dcf-92c2-d9b2c7ca896b");
msgCenterHandler.send(centerEvent);
return -1;
}
private static MessageCenterEvent buildCommonPrdMsg(Integer uid, SellerOrderGoods sellerOrderGoods, Product product){
MessageCenterEvent centerEvent = new MessageCenterEvent();
centerEvent.setUserType("UID"); //根据userList的类型可选:UID,MOBILE,TOKEM,OPENID
centerEvent.setUserList(Lists.newArrayList(String.valueOf(uid)));
//TODO optimized,use map directly
PrdMsg prdMsg = PrdMsg.builder()
.productId(sellerOrderGoods.getProductId())
.prdName(sellerOrderGoods.getProductName())
.sizeName(sellerOrderGoods.getSizeName())
.productCode(product.getProductCode()).price(sellerOrderGoods.getGoodsPrice().toPlainString()).build();
centerEvent.setParams(JSONObject.parseObject(JSONObject.toJSONString(prdMsg)));
centerEvent.setBusinessLine("ufo");
return centerEvent;
}
}
... ...
... ... @@ -3,8 +3,11 @@ package com.yohoufo.order.service.impl.statechange;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.enums.InboxBusinessTypeEnum;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.constants.ChangePriceStatus;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.dal.order.model.BuyerChangePriceRecord;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.SellerOrderGoods;
... ... @@ -19,12 +22,12 @@ import com.yohoufo.order.mq.TopicConstants;
import com.yohoufo.order.service.AbstractBuyerOrderStateChanger;
import com.yohoufo.order.service.IBuyerOrderService;
import com.yohoufo.order.service.impl.BuyerChangePriceRecordService;
import com.yohoufo.order.service.seller.SkupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
/**
* 支付定金完成
... ... @@ -43,6 +46,9 @@ public class BuyerOrderPayDepositSuccessChanger extends AbstractBuyerOrderStateC
@Autowired
private MsgService msgService;
@Autowired
private SkupService skupService;
@Override
protected Collection<Statement> afterStatements(RequestedStatusChangeBuyerOrder statusChangeBuyerOrder) {
BuyerOrder buyerOrder = statusChangeBuyerOrder.getBuyerOrder();
... ... @@ -142,10 +148,32 @@ public class BuyerOrderPayDepositSuccessChanger extends AbstractBuyerOrderStateC
//1. check
// 1.1 不能低于最低现货价90%
//1.2 没有最低现货价
Set<Integer> skupTypes = new HashSet<>();
skupTypes.add(SkupType.IN_STOCK.getCode());
List<Integer> statusList = new ArrayList<>();
statusList.add(SkupStatus.CAN_SELL.getCode());
Integer sku;
BigDecimal leastPrice = skupService.getLeastPriceOfSku(sku=sellerOrderGoods.getStorageId(), statusList, skupTypes);
if (Objects.isNull(leastPrice)){
logger.warn("push msg 2 seller find no sale goods,sku {}", sku);
return;
}
BigDecimal minThreshold = BigDecimalHelper.halfUp(leastPrice.multiply(new BigDecimal(0.9)));
if (sellerOrderGoods.getGoodsPrice().compareTo(minThreshold)<0){
logger.warn("push msg 2 seller, buyer bid price too low, bid-price {} lease price {} threshold {}",
sellerOrderGoods.getGoodsPrice(), leastPrice, minThreshold);
return;
}
// 2. push
// 2.1 find out all seller who own this kind of sku
List<Integer> uidList = null;
List<Integer> uidList = skupService.findUidBySku(sku, statusList, skupTypes);
Product product = productMapper.selectByPrimaryKey(sellerOrderGoods.getProductId());
//2.2 check every seller push frequency one by one ;----可能有性能问题 最耗时的一步
msgService.noticeSellerWhenBuyerBidSuccess(uidList, sellerOrderGoods);
msgService.noticeSellerWhenBuyerBidSuccess(uidList, sellerOrderGoods, product);
}
}
... ...
... ... @@ -9,6 +9,7 @@ import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohobuy.ufo.model.response.StorageDataResp;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.SellerOrderGoodsViewMapper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.convert.GoodsInfoConvertor;
import com.yohoufo.order.model.dto.OrderBuilder;
... ... @@ -26,6 +27,7 @@ import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Created by chenchao on 2018/9/17.
... ... @@ -38,6 +40,9 @@ public class SkupService {
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
private SellerOrderGoodsViewMapper sellerOrderGoodsViewMapper;
@Autowired
private ProductProxyService productProxyService;
@Transactional(propagation = Propagation.REQUIRED)
... ... @@ -153,4 +158,20 @@ public class SkupService {
int num = sellerOrderGoodsMapper.updateStatusBySkpu(condition);
return num;
}
public BigDecimal getLeastPriceOfSku(Integer storageId,List<Integer> statusList, Set<Integer> skupTypes){
int cnt = sellerOrderGoodsViewMapper.selectCntOfSku(storageId, statusList, skupTypes);
if (cnt == 0){
logger.warn("getLeastPriceOfSku no record, sku {}", storageId);
return null;
}
SellerOrderGoods sellerOrderGoods = sellerOrderGoodsViewMapper.selectLeastPriceOfSku(storageId, statusList, skupTypes);
return sellerOrderGoods.getGoodsPrice();
}
public List<Integer> findUidBySku(int storageId, List<Integer> statusList, Set<Integer> skupTypes){
List<Integer> uidList = sellerOrderGoodsViewMapper.selectUserOfSku(storageId,statusList,skupTypes);
return uidList;
}
}
... ...
... ... @@ -8,24 +8,16 @@ 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.cache.CacheKeyEnum;
import com.yohoufo.dal.order.SellerEnterApplyMapper;
import com.yohoufo.dal.order.StoredSellerMapper;
import com.yohoufo.dal.order.SuperEntrySellerMapper;
import com.yohoufo.dal.order.model.SuperEntrySeller;
import com.yohoufo.order.common.SuperEntrySellerStatus;
import com.yohoufo.order.model.bo.PlatformServiceFeeDefinition;
import com.yohoufo.order.model.bo.SellerPlatformServiceFee;
import com.yohoufo.order.service.IStoredSellerDepositService;
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.support.SellerPlatformServiceFeeSupport;
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.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -46,15 +38,9 @@ public class SellerService {
private static final Logger logger = LoggerUtils.getSellerOrderLogger();
@Autowired
private StoredSellerCacheService storedSellerCacheService;
@Autowired
private IStoredSellerService storedSellerService;
@Autowired
private SuperEntrySellerMapper superEntrySellerMapper;
@Autowired
private StoredSellerMapper storedSellerMapper;
@Autowired
... ... @@ -64,12 +50,6 @@ public class SellerService {
private SellerFuncService sellerFuncService;
@Autowired
private SellerEnterApplyService sellerEnterApplyService;
@Autowired
private SellerEnterApplyMapper sellerEnterApplyMapper;
@Autowired
private SellerPlatformServiceFeeSupport sellerPlatformServiceFeeSupport;
@Autowired
... ... @@ -101,33 +81,11 @@ public class SellerService {
}
public List<Integer> getSuperEntrySellerUids(){
CacheKeyEnum cke = CacheKeyEnum.SUPER_ENTRY_SELLER_LIST;
List<Integer> uidList = storedSellerCacheService.getSuperEntrySellerList(cke.getKey());
if (CollectionUtils.isNotEmpty(uidList)){
//hit in cache
logger.info("in getSuperEntrySellerUids hit cache uidList {}", uidList);
return uidList;
}
List<SuperEntrySeller> sesList = superEntrySellerMapper.selectAll(SuperEntrySellerStatus.SUPER.getCode());
if (CollectionUtils.isNotEmpty(sesList)){
uidList = sesList.parallelStream().map(SuperEntrySeller::getUid).collect(Collectors.toList());
storedSellerCacheService.setSuperEntrySellerList(cke.getKey(), uidList);
logger.info("in getSuperEntrySellerUids fetch from DB uidList {}", uidList);
}
return uidList;
}
public SellerWrapper getBaseSellerWrapper(Integer uid){
SellerWrapper sellerWrapper = new SellerWrapper(uid,logger)
.storedSellerDataSource(storedSellerMapper::selectByUid)
// .addSpecialSuperFunc(this::isSpecialSuper)
.buildSellerWrapper();
return sellerWrapper;
}
... ... @@ -151,15 +109,6 @@ public class SellerService {
return false;
}
// public boolean isSpecialSuper(int uid){
// List<Integer> uidList = getSuperEntrySellerUids();
// logger.info("isSuperEntrySeller check uid {} uidList {}", uid, uidList);
// if (CollectionUtils.isNotEmpty(uidList)){
// //hit or not
// return uidList.contains(uid);
// }
// return false;
// }
/**
* 平台技术服务费
... ... @@ -221,7 +170,6 @@ public class SellerService {
logger.info("of uid {}", uid);
SellerBo sellerBo = new SellerWrapper(uid,logger)
.storedSellerDataSource(storedSellerMapper::selectByUid)
// .addSpecialSuperFunc(this::isSpecialSuper)
.buildSellerWrapper().sellerBo();
EntrySellerType est = sellerBo.getEntrySellerType();
logger.info("of uid {} EntrySellerType {}", uid, est);
... ... @@ -230,24 +178,7 @@ public class SellerService {
/**
* 支付成功后回调
* (一)用于处理卖家申请,
* 1. 成为普通入驻 (晋升 普通卖家->普通入驻)
* 2. 成为超级入驻
* 2.1: 普通卖家 -> 超级入驻 ;
* 2.2 :普通入驻 -> 超级入驻;
* (二)普通卖家充值,丢弃;
* (三)超级卖家
* 1. 如果取消能力 -> 恢复;
* 2. 没有取消,丢弃;
*
* @param uid
* @param orderCode
*/
// public void processApply(Integer uid, Long orderCode, BigDecimal total){
// sellerEnterApplyService.audit(uid, orderCode, total);
// }
@Autowired
private MetaConfigService metaConfigService;
... ... @@ -256,40 +187,7 @@ public class SellerService {
return metaConfigService.getEntryThreshold();
}
// public Boolean applySuperEnter(Integer uid){
// SellerWrapper sellerWrapper =
// new SellerWrapper(uid,logger)
// .storedSellerDataSource(storedSellerMapper::selectByUid)
// .buildSellerWrapper();
// SellerBo sellerBo = sellerWrapper.sellerBo();
// EntrySellerType currentEST = sellerBo.of();
// EntrySellerType targetEST = EntrySellerType.SUPER_ENTRY;
// if (Objects.equals(targetEST, currentEST)
// || Objects.equals(EntrySellerType.SPECIAL_SUPER, currentEST)){
// logger.info("applySuperEnter user was {} , uid {}", currentEST , uid);
// return true;
// }
// //普通个人
// if (Objects.equals(targetEST, EntrySellerType.NOT_ENTRY)){
// logger.info("applySuperEnter user was {} , uid {}", currentEST , uid);
// return false;
// }
// //left enter type is 入驻非超级
// BigDecimal leftInWallet = merchantOrderPaymentService.getWalletLeftAmount(uid);
// sellerWrapper.setLeftInWallet(leftInWallet);
// //前提:1. 当前卖家是 普通个人 or 入驻非超级 2. 钱包余额大于等于超级的阈值
// Map<EntrySellerType,EntryThreshold> entryThreshold = getEntryThreshold();
// EntryThreshold set = entryThreshold.get(EntrySellerType.SUPER_ENTRY);
// boolean isFatWallet = leftInWallet.compareTo(set.getPrepaymentAmount()) >= 0;
// logger.info("applySuperEnter uid {} leftInWallet {} super EntryThreshold {} isFatWallet {}",
// uid, leftInWallet, set, isFatWallet);
// //申请记录(新增 or 修改) 入驻卖家(enter_type level_func 功能菜单)
// if (isFatWallet){
// //insert apply
// sellerEnterApplyService.upgradeLevelIfFatWallet(sellerWrapper, null, targetEST);
// }
// return isFatWallet;
// }
/**
... ... @@ -311,9 +209,6 @@ public class SellerService {
logger.warn("processAfterWalletChange user was {} , uid {}", currentEST , uid);
return ;
}
//left enter type is 入驻超级
// BigDecimal leftInWallet = merchantOrderPaymentService.getWalletLeftAmount(uid);
// sellerEnterApplyService.changeLevel4Super(sellerWrapper, leftInWallet);
// level发生变化
entrySellerWalletChangers.deduct(uid);
... ... @@ -330,7 +225,6 @@ public class SellerService {
public Boolean checkIsNormalSuper(Integer uid){
SellerWrapper sellerWrapper =
new SellerWrapper(uid,logger)
// .addSpecialSuperFunc(this::isSpecialSuper)
.storedSellerDataSource(storedSellerMapper::selectByUid)
.buildSellerWrapper();
SellerBo sellerBo = sellerWrapper.sellerBo();
... ... @@ -342,12 +236,6 @@ public class SellerService {
}
SellerLevelFuncBo sellerLevelFuncBo = authLevelChgeSupport.getShouldLevel(uid, targetEST);
// //left enter type is 入驻超级
// BigDecimal leftInWallet = merchantOrderPaymentService.getWalletLeftAmount(uid);
// Map<EntrySellerType,EntryThreshold> estMap = metaConfigService.getEntryThreshold();
// EntryThreshold set = estMap.get(currentEST);
// //目标身份对应的等级
// SellerLevelFuncBo bslfb = SellerHelper.getSellerLevelFunc(currentEST, set, leftInWallet);
Integer level = sellerLevelFuncBo.getLevel();
if (sellerLevelFuncBo.getLevel() != SuperEnterStageLevel.FULL.getCode()){
logger.warn("in checkIsNormalSuper not valid, uid {} level {}", uid, level);
... ... @@ -360,8 +248,10 @@ public class SellerService {
SellerWrapper sellerWrapper =
new SellerWrapper(uid,logger)
.storedSellerDataSource(storedSellerMapper::selectByUid)
.buildSellerWrapper().attachAssetPolicy()
.buildSellerWrapper()
.attachAssetPolicy()
.attachWallet(merchantOrderPaymentService::getWalletLeftAmount);
return sellerWrapper;
}
}
... ...