Authored by LUOXC

refactor

... ... @@ -17,14 +17,21 @@ public interface InviteSettlementItemMapper {
@Param("tagStatus") Integer tagStatus,
@Param("inviteSettlementId") Integer inviteSettlementId);
int updateToSettledRollback(@Param("uid") Integer uid,
@Param("type") Integer type,
@Param("srcStatus") Integer srcStatus,
@Param("tagStatus") Integer tagStatus,
@Param("inviteSettlementId") Integer inviteSettlementId,
@Param("ids") List<Integer> ids);
int updateStatusByUidAndInviteSettlementId(@Param("uid") Integer uid, @Param("inviteSettlementId") Integer inviteSettlementId,
@Param("status") Integer status);
InviteSettlementItem selectByUidAndBuyerOrderCode(@Param("uid") Integer uid, @Param("buyerOrderCode") Long buyerOrderCode);
InviteSettlementItem selectOneByUidTypeAndStatus(@Param("uid") Integer uid,
@Param("type") Integer type,
@Param("status") Integer status);
@Param("type") Integer type,
@Param("status") Integer status);
int selectCountByUidTypeAndInviteSettlementId(@Param("uid") Integer uid,
@Param("type") Integer type,
... ... @@ -42,9 +49,9 @@ public interface InviteSettlementItemMapper {
@Param("sellerUid") Integer sellerUid);
/**
* 查询type1 结算方式的待结算、已结算和已付款订单数
*
* @param inviterUid
* @return
*/
... ... @@ -52,6 +59,7 @@ public interface InviteSettlementItemMapper {
/**
* 根据条件查询,待结算、已结算和已付款的统计数据
*
* @param uid
* @param type
* @param startTime
... ... @@ -66,6 +74,7 @@ public interface InviteSettlementItemMapper {
/**
* 根据条件查询,待结算、已结算和已付款的数据
*
* @param uid
* @param type
* @param startTime
... ...
... ... @@ -59,6 +59,19 @@
and status = #{srcStatus,jdbcType=INTEGER}
</update>
<update id="updateToSettledRollback">
update invite_settlement_item
set status = #{tagStatus,jdbcType=INTEGER},
invite_settlement_id = #{inviteSettlementId,jdbcType=INTEGER}
where uid = #{uid,jdbcType=INTEGER}
and type = #{type,jdbcType=INTEGER}
and status = #{srcStatus,jdbcType=INTEGER}
and id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<update id="updateStatusByUidAndInviteSettlementId">
update invite_settlement_item
set status = #{status,jdbcType=INTEGER}
... ...
... ... @@ -11,7 +11,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
/**
* @author LUOXC
... ... @@ -55,8 +58,8 @@ public class InviteSettlementController {
}
@RequestMapping(value = "/erp/invite/settlement/help/settle")
public ApiResponse settle() {
inviteSettlementService.settle();
public ApiResponse settle(@RequestParam(value = "settle_time", required = false) String settleTime) {
inviteSettlementService.settle(Objects.nonNull(settleTime) ? LocalDateTime.parse(settleTime, DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) : LocalDateTime.now());
return new ApiResponse.ApiResponseBuilder().code(200).message("ok").build();
}
... ...
... ... @@ -3,6 +3,7 @@ package com.yohoufo.order.service;
import com.yohoufo.order.model.InviteSettlementItemListVO;
import com.yohoufo.order.model.InviteSettlementListVO;
import java.time.LocalDateTime;
import java.util.List;
public interface IInviteSettlementService {
... ... @@ -20,7 +21,7 @@ public interface IInviteSettlementService {
/**
* 结算
*/
void settle();
void settle(LocalDateTime settleTime);
/**
* 将结算单和结算项标志成已付款
... ...
... ... @@ -193,9 +193,9 @@ public class InviteSettlementServiceImpl implements IInviteSettlementService {
}
@Override
public void settle() {
public void settle(LocalDateTime settleTime) {
inviterMapper.selectAll().stream()
.forEach(inviterSettleService::settle);
.forEach(inviter -> inviterSettleService.settle(inviter, settleTime));
}
@Override
... ...
... ... @@ -14,10 +14,12 @@ import com.yohoufo.order.common.InviterType;
import com.yohoufo.order.utils.IdUtils;
import com.yohoufo.order.utils.InviteSettlementUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
... ... @@ -49,10 +51,10 @@ public class InviterSettleService {
public void settle(Integer uid) {
inviterMapper.selectInviteCodeByUid(uid)
.forEach(this::settle);
.forEach(inviter -> this.settle(inviter, LocalDateTime.now()));
}
public void settle(Inviter inviter) {
public void settle(Inviter inviter, LocalDateTime settleTime) {
log.info("settle for {}", inviter);
int uid = inviter.getUid();
int now = DateUtil.getCurrentTimeSecond();
... ... @@ -81,7 +83,7 @@ public class InviterSettleService {
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.withWaitStrategy(WaitStrategies.fixedWait(50, TimeUnit.MILLISECONDS))
.build().call(() -> {
updateSettleAmount(uid, settleType, settlement);
updateSettleAmount(uid, settleTime, settleType, settlement);
return null;
});
} catch (ExecutionException | RetryException e) {
... ... @@ -90,7 +92,7 @@ public class InviterSettleService {
log.info("settle for {} end settle amount for settlement {} is {}.", uid, settlement.getId(), settlement.getSettleAmount());
}
private void updateSettleAmount(int uid, int settleType, InviteSettlement settlement) {
private void updateSettleAmount(int uid, LocalDateTime settleTime, int settleType, InviteSettlement settlement) {
int settlementId = settlement.getId();
log.info("settle for {} calculate settle amount for settlement {}.", uid, settlementId);
BigDecimal settleAmount;
... ... @@ -101,14 +103,14 @@ public class InviterSettleService {
uid, settlementId, settleAmount);
} else {
// type2方式结算金额
settleAmount = calculateSettleAmountOfType2(uid, settlementId);
settleAmount = calculateSettleAmountOfType2(uid, settleTime, settlementId);
log.info("settle for {} calculate settle amount for settlement {}, the amount of type2 is {}.",
uid, settlementId, settleAmount);
}
// 更新结算金额
settlement.setSettleCode(IdUtils.derangement(settlementId));
settlement.setSettleAmount(settleAmount);
settlement.setSettleTime(DateUtil.getCurrentTimeSecond());
settlement.setSettleTime((int) settleTime.toEpochSecond(InviteSettlementUtils.zoneOffset()));
settlement.setStatus(InviteSettlement.STATUS_WAIT_PAY);
inviteSettlementMapper.updateByUidAndId(settlement);
}
... ... @@ -139,7 +141,7 @@ public class InviterSettleService {
* @param settlementId
* @return
*/
private BigDecimal calculateSettleAmountOfType2(int uid, int settlementId) {
private BigDecimal calculateSettleAmountOfType2(int uid, LocalDateTime settleTime, int settlementId) {
int type = 2;
inviteSettlementItemMapper.updateToSettled(
uid,
... ... @@ -154,10 +156,23 @@ public class InviterSettleService {
.collect(Collectors.toMap(InviteRecord::getInviteeUid, InviteRecord::getCreateTime));
return statsList.stream()
.map(stats -> InviteSettlementUtils.calculateSettleAmountOfType2(
newLocalDateTimeOfEpochSecond(invitees.getOrDefault(stats.getSellerUid(), 0)),
inviteSettlementItemMapper.selectByUidTypeInviteSettlementIdAndSellerUid(uid, type, settlementId, stats.getSellerUid())
))
.map(stats -> {
Pair<BigDecimal, List<InviteSettlementItem>> settle = InviteSettlementUtils.calculateSettleAmountOfType2(
newLocalDateTimeOfEpochSecond(invitees.getOrDefault(stats.getSellerUid(), 0)),
settleTime,
inviteSettlementItemMapper.selectByUidTypeInviteSettlementIdAndSellerUid(uid, type, settlementId, stats.getSellerUid())
);
List<Integer> ids = settle.getRight().stream().map(InviteSettlementItem::getId).collect(Collectors.toList());
inviteSettlementItemMapper.updateToSettledRollback(
uid,
type,
InviteSettlementItem.STATUS_SETTLED,
InviteSettlementItem.STATUS_ENABLE,
0,
ids
);
return settle.getLeft();
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
... ...
package com.yohoufo.order.utils;
import com.yohoufo.dal.order.model.InviteSettlementItem;
import org.apache.commons.lang3.tuple.Pair;
import java.math.BigDecimal;
import java.math.RoundingMode;
... ... @@ -11,6 +12,7 @@ import java.time.ZoneOffset;
import java.util.List;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
/**
* @author LUOXC
... ... @@ -58,27 +60,48 @@ public class InviteSettlementUtils {
* @param items 待结算订单
* @return
*/
public static BigDecimal calculateSettleAmountOfType2(LocalDateTime inviteTime, List<InviteSettlementItem> items) {
public static Pair<BigDecimal, List<InviteSettlementItem>> calculateSettleAmountOfType2(LocalDateTime inviteTime, LocalDateTime settleTime, List<InviteSettlementItem> items) {
// 被邀请当月月初开始计算
LocalDateTime calculateInviteTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear(), inviteTime.getMonth(), 1), LocalTime.MIN);
// 一个月内
LocalDateTime calculateStartTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear(), inviteTime.getMonth(), 1), LocalTime.MIN);
LocalDateTime afterOneMonth = calculateStartTime.plusMonths(1);
LocalDateTime afterFiveMonth = calculateStartTime.plusMonths(5);
// 被邀请来年元旦
LocalDateTime calculateFinnalEndTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear() + 1, 1, 1), LocalTime.MIN);
BiPredicate<InviteSettlementItem, LocalDateTime> iaAfterOrEqual = (item, month) -> {
LocalDateTime createTime = newLocalDateTimeOfEpochSecond(item.getCreateTime());
return createTime.isAfter(month) || createTime.isEqual(month);
};
// 一个月内无需结算
if (settleTime.isBefore(afterOneMonth)) {
return Pair.of(BigDecimal.ZERO, items);
}
// 一个月内结算金额
BigDecimal inOneMonthTotalSettleAmount = items.stream()
.filter(item -> newLocalDateTimeOfEpochSecond(item.getOrderCreateTime()).isBefore(calculateInviteTime.plusMonths(1)))
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(afterOneMonth))
.map(InviteSettlementItem::getOrderAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add)
.multiply(BigDecimal.valueOf(0.02));
BiPredicate<InviteSettlementItem, Integer> iaAfterOrEqual = (item, months) -> {
LocalDateTime orderCreateTime = newLocalDateTimeOfEpochSecond(item.getOrderCreateTime());
LocalDateTime afterInviteMonth = calculateInviteTime.plusMonths(months);
return orderCreateTime.isAfter(afterInviteMonth) || orderCreateTime.isEqual(afterInviteMonth);
};
// 五个月内只结算1个月内的订单
if (settleTime.isBefore(afterFiveMonth)) {
return Pair.of(
inOneMonthTotalSettleAmount,
items.stream().filter(item -> iaAfterOrEqual.test(item, afterOneMonth)).collect(Collectors.toList())
);
}
// 五个月内
// 五个月内结算金额
BigDecimal inFiveMonthTotalSettleAmount;
BigDecimal inFiveMonthTotalOrderAmount = items.stream()
.filter(item -> iaAfterOrEqual.test(item, 1))
.filter(item -> newLocalDateTimeOfEpochSecond(item.getOrderCreateTime()).isBefore(calculateInviteTime.plusMonths(5)))
.filter(item -> iaAfterOrEqual.test(item, afterOneMonth))
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(calculateFinnalEndTime.isBefore(afterFiveMonth) ? calculateFinnalEndTime : afterFiveMonth))
.map(InviteSettlementItem::getOrderAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (inFiveMonthTotalOrderAmount.compareTo(BigDecimal.valueOf(100_0000)) < 0) {
... ... @@ -91,10 +114,19 @@ public class InviteSettlementUtils {
inFiveMonthTotalSettleAmount = inFiveMonthTotalOrderAmount.multiply(BigDecimal.valueOf(0.020));
}
// 五个月以后
// 五个月以后,1年内只结算五个月内的订单
if (settleTime.isBefore(afterFiveMonth)) {
return Pair.of(
inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount),
items.stream().filter(item -> iaAfterOrEqual.test(item, calculateFinnalEndTime.isBefore(afterFiveMonth) ? calculateFinnalEndTime : afterFiveMonth)).collect(Collectors.toList())
);
}
// 五个月以后结算金额
BigDecimal outFiveMonthTotalSettleAmount;
BigDecimal outFiveMonthTotalOrderAmount = items.stream()
.filter(item -> iaAfterOrEqual.test(item, 5))
.filter(item -> iaAfterOrEqual.test(item, afterFiveMonth))
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(calculateFinnalEndTime))
.map(InviteSettlementItem::getOrderAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (outFiveMonthTotalOrderAmount.compareTo(BigDecimal.valueOf(180_0000)) < 0) {
... ... @@ -107,7 +139,10 @@ public class InviteSettlementUtils {
outFiveMonthTotalSettleAmount = outFiveMonthTotalOrderAmount.multiply(BigDecimal.valueOf(0.018));
}
return inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount).add(outFiveMonthTotalSettleAmount);
return Pair.of(
inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount).add(outFiveMonthTotalSettleAmount),
items.stream().filter(item -> iaAfterOrEqual.test(item, calculateFinnalEndTime)).collect(Collectors.toList())
);
}
public static ZoneOffset zoneOffset() {
... ...