Authored by chenchao

get msg delay time by calculate

... ... @@ -109,7 +109,9 @@ public class NotDeliverNoticeDelayMsgConsumer implements YhConsumer {
Integer leftMinutes = null;
boolean hasNext = maxTimes>currentTimes;
if (hasNext && msg.getMinutesOfLeft() == null){
IntervalBo timeIntervalBo = DeliveryMinutesService.calculateInterval(currentTimes, deliveryMinutesService.getTotalMinutes(), deliveryMinutesService.getDelayTime());
final int totalMinutes = deliveryMinutesService.getTotalMinutes(msg.getOrderCode(), msg.getSellerOrderGoods());
final int[] delayIntervalArrys = deliveryMinutesService.getDelayTime(totalMinutes);
IntervalBo timeIntervalBo = DeliveryMinutesService.calculateInterval(currentTimes, totalMinutes, delayIntervalArrys);
LOGGER.info("in topic {}, msg {} intervalBo {}", topic, msg, timeIntervalBo);
if (Objects.nonNull(timeIntervalBo)){
leftMinutes = timeIntervalBo.getMinutesOfLeft();
... ...
... ... @@ -40,19 +40,22 @@ public class DeliverNoticeAsyncHandler implements IEventHandler<DeliverNoticeEve
@Subscribe
public void handle(DeliverNoticeEvent event) {
int ts = DateUtil.getCurrentTimeSecond();
//延迟时间(分钟级别)
int minutes = 0;
if (event.getOrderAttributes() == OrderAttributes.OVERSEAS_IN_STOCK.getCode()){
minutes = deliveryMinutesService.getDeliverOverSeasNoticeMinutes();
}else{
//提醒发货的次数编号
//兼容了queue中老数据,默认是第二次;
//后续event.getTimes是个固定属性,必然有数据
int times = event.getTimes() == null ? OrderConstant.SellerDeliverNotice.SECOND_TIME : event.getTimes().intValue();
switch (times){
case OrderConstant.SellerDeliverNotice.SECOND_TIME:
case OrderConstant.SellerDeliverNotice.SECOND_TIME://第二次
minutes = deliveryMinutesService.getDeliverMinutesSecond(ts);
break;
case OrderConstant.SellerDeliverNotice.LAST_TIME:
case OrderConstant.SellerDeliverNotice.LAST_TIME://第三次
minutes = Objects.isNull(event.getMinutesOfDelay()) ? deliveryMinutesService.getDeliverMinutesOfLastTime() :
event.getMinutesOfDelay();
break;
... ... @@ -70,7 +73,9 @@ public class DeliverNoticeAsyncHandler implements IEventHandler<DeliverNoticeEve
private void appendExtToEvent(int currentTimes, DeliverNoticeEvent event){
IntervalBo intervalBo = null;
intervalBo = DeliveryMinutesService.calculateInterval(currentTimes, deliveryMinutesService.getTotalMinutes(), deliveryMinutesService.getDelayTime());
final int totalMinutes = deliveryMinutesService.getTotalMinutes(event.getOrderCode(), event.getSellerOrderGoods());
final int[] delayIntervalArrys = deliveryMinutesService.getDelayTime(totalMinutes);
intervalBo = DeliveryMinutesService.calculateInterval(currentTimes, totalMinutes, delayIntervalArrys);
if (intervalBo!=null){
event.setMinutesOfDelay(intervalBo.getMinutesofDelay());
event.setMinutesOfLeft(intervalBo.getMinutesOfLeft());
... ...
... ... @@ -4,9 +4,11 @@ import com.yoho.core.cache.LocalCache;
import com.yoho.core.config.ConfigReader;
import com.yohobuy.ufo.model.order.bo.IntervalBo;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.dal.order.model.OrderOverTime;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.model.dto.LimitTime;
import com.yohoufo.order.service.impl.MetaConfigService;
import com.yohoufo.order.service.impl.OrderOverTimeService;
import lombok.Getter;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
... ... @@ -18,6 +20,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
... ... @@ -62,16 +65,78 @@ public class DeliveryMinutesService {
* 第二次通知 等待24小时,发送通知(剩余12小时);
* 第三次通知 再等待10小时,发送通知(剩余2小时)
*/
@Getter
private int[] delayTime ;
@Getter
private int totalMinutes = 36*60;
@Autowired
private MetaConfigService metaConfigService;
/**
* 业务规则 通知的触发点 倒计时到12小时 2小时
*
* TODO 后续使用配置方式
*/
private static final int[] LEFT_MINUTES = new int[]{12*60,2*60};
@Autowired
private OrderOverTimeService orderOverTimeService;
public int[] getDelayTime(int totalMinutes){
return calDelayMinutesByTotal(totalMinutes, LEFT_MINUTES);
}
/**
* 订单维度 下单时刻的配置
* @param orderCode
* @return
*/
public int getDeliverMinutesLimitTimeByOrder(Long orderCode){
OrderOverTime oot = orderOverTimeService.selectByOrderCode(orderCode);
return Optional.ofNullable(oot).map(OrderOverTime::getDeliveryMinutes).orElse(-1);
}
/**
* 不能确定orderOverTime是否被持久化(异步)时使用
*
* @param orderCode
* @param sellerOrderGoods
* @return
*/
public int getTotalMinutes(Long orderCode,SellerOrderGoods sellerOrderGoods){
//订单维度 下单时刻的配置
int totalMinutes = getDeliverMinutesLimitTimeByOrder(orderCode);
if (totalMinutes<=0){//商品类型匹配,当前生效的全局配置(数据库)
totalMinutes = getDeliverMinutesLimitTimeBySkupType(sellerOrderGoods);
}
//配置文件(程序中)
if (totalMinutes<=0){
totalMinutes = this.totalMinutes;
}
return totalMinutes;
}
/**
*
* @param totalMinutes 总的分钟数
* @return
*/
public static int[] calDelayMinutesByTotal(int totalMinutes, int[] countDownInterval){
//有个隐含的规则 第一次也有某些动作是立即执行;总时间 - 倒计时时长(约为总时长 ns误差 忽略)
int[] delayArrys = new int[countDownInterval.length+1];
int index = 0;
delayArrys[index] = 0;
for (;index<countDownInterval.length;){
int interval = countDownInterval[index];
delayArrys[++index] = (totalMinutes - interval);
totalMinutes = interval;
}
return delayArrys;
}
@PostConstruct
private void init() {
... ... @@ -105,17 +170,31 @@ public class DeliveryMinutesService {
return MINUTES_DELIVERNOTICE_SECOND;
}
public int getDeliverMinutesThird(int ts, SellerOrderGoods sellerOrderGoods){
private int getDeliverMinutesLimitTimeBySkupType(SellerOrderGoods sellerOrderGoods){
Map<String, LimitTime> limitTimeMap = metaConfigService.getSellerDeliverLimitTimeConfig();
SkupType skupType = SkupType.getSkupType(sellerOrderGoods.getAttributes());
LimitTime limitTime = null;
if (MapUtils.isNotEmpty(limitTimeMap)
&& Objects.nonNull(limitTime = limitTimeMap.get(skupType.getLocalCacheKey()))) {
int limitTimeInt = getMinutes(limitTime);
logger.info("getDeliverMinutesThird from special skupType {} {},limitTimeInt {}",
logger.info("getDeliverMinutesLimitTimeBySkupType from special skupType {} {},limitTimeInt {}",
limitTime,sellerOrderGoods, limitTimeInt);
return limitTimeInt;
}
return -1;
}
/**
* it's dead line of seller deliver goods of buyer order
* @param ts
* @param sellerOrderGoods
* @return
*/
public int getDeliverMinutesThird(int ts, SellerOrderGoods sellerOrderGoods){
int limitTimeInt = getDeliverMinutesLimitTimeBySkupType(sellerOrderGoods);
if (limitTimeInt>0){
return limitTimeInt;
}
//当前时刻在某个指定的时刻之前时,使用旧的规则
if(ts<getOnlineTime()){
return minutes_deliverNotice_third_old;
... ... @@ -200,9 +279,10 @@ public class DeliveryMinutesService {
public static void main(String[] args) {
int start = 60;
int[] intervals1 = calDelayMinutesByTotal(start, new int[]{50,30}); //new int[]{0,10,20};
for(int times=1;times<=3;times++) {
int start = 60;
int[] intervals1 = new int[]{0,10,20};
IntervalBo intervalBo = calculateInterval(times, start, intervals1);
System.out.println(intervalBo);
}
... ...