更新分成逻辑
This commit is contained in:
parent
0f6251455f
commit
9758933156
|
@ -163,4 +163,14 @@ public interface BonusMapper
|
|||
* 查询总金额
|
||||
*/
|
||||
BigDecimal selectSumOfAmount(@Param("query") BonusQuery query);
|
||||
|
||||
/**
|
||||
* 根据条件更新
|
||||
*/
|
||||
int updateByQuery(@Param("data") Bonus data, @Param("query") BonusQuery query);
|
||||
|
||||
/**
|
||||
* 预支付
|
||||
*/
|
||||
int prePay(@Param("list") List<? extends Bonus> bonusList);
|
||||
}
|
||||
|
|
|
@ -454,6 +454,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
and `status` = '1'
|
||||
</update>
|
||||
|
||||
<update id="updateByQuery">
|
||||
update ss_bonus sb
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<include refid="updateColumns"/>
|
||||
</trim>
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
</update>
|
||||
|
||||
<update id="prePay">
|
||||
update ss_bonus
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<foreach open="pre_pay_time = CASE id" collection="list" item="item" close="END,">
|
||||
<choose>
|
||||
<when test="item.prePayTime != null">
|
||||
WHEN #{item.id} THEN #{item.prePayTime}
|
||||
</when>
|
||||
<otherwise>
|
||||
WHEN #{item.id} THEN pre_pay_time
|
||||
</otherwise>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
where id in
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item.id}
|
||||
</foreach>
|
||||
and `status` = '2'
|
||||
</update>
|
||||
|
||||
<sql id="updateColumns">
|
||||
<if test="data.billId != null">bill_id = #{data.billId},</if>
|
||||
<if test="data.billNo != null">bill_no = #{data.billNo},</if>
|
||||
|
@ -498,7 +529,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</where>
|
||||
</select>
|
||||
|
||||
<!-- selectSumOfAmount -->
|
||||
<!-- selectSumOfAmount -->
|
||||
|
||||
<select id="selectSumOfAmount" resultType="java.math.BigDecimal">
|
||||
select sum(sb.amount) as `value`
|
||||
|
|
|
@ -4,18 +4,14 @@ import java.math.BigDecimal;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.domain.vo.CommonCountVO;
|
||||
import com.ruoyi.common.domain.vo.CommonSumVO;
|
||||
import com.ruoyi.common.domain.vo.LocalDateDecimalVO;
|
||||
import com.ruoyi.common.domain.vo.LongDecimalVO;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.bonus.domain.BonusProvideQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusVO;
|
||||
import com.ruoyi.ss.bonus.domain.enums.BonusBstType;
|
||||
import com.ruoyi.ss.bonus.domain.vo.BonusDailyAmountVO;
|
||||
import com.ruoyi.ss.bonus.domain.vo.BonusMonthAmountVO;
|
||||
import com.ruoyi.ss.bonus.domain.vo.ProvideBonusVO;
|
||||
|
||||
/**
|
||||
* 分成明细Service接口
|
||||
|
@ -88,9 +84,8 @@ public interface BonusService
|
|||
* 分配分成金额,按照比例分出金额
|
||||
*
|
||||
* @param bonusList 分成列表
|
||||
* @param money 总金额
|
||||
*/
|
||||
int partBonus(List<? extends Bonus> bonusList, BigDecimal money);
|
||||
int prePay(List<? extends Bonus> bonusList);
|
||||
|
||||
/**
|
||||
* 当未分成时退款
|
||||
|
|
|
@ -158,9 +158,14 @@ public class BonusConverterImpl implements BonusConverter {
|
|||
bonus.setBillNo(order.getOrderNo());
|
||||
bonus.setToBalance(isPlatform);
|
||||
bonus.setChannelId(channelId);
|
||||
bonus.setStatus(BonusStatus.UN_DIVIDEND.getStatus());
|
||||
bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus());
|
||||
}
|
||||
|
||||
// 拆分金额
|
||||
// 平台最低需要的分成金额
|
||||
BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
|
||||
BonusUtil.partBonusAmount(result, order.getAmount(), minService);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -219,9 +224,10 @@ public class BonusConverterImpl implements BonusConverter {
|
|||
bonus.setBillNo(bill.getBillNo());
|
||||
bonus.setToBalance(true);
|
||||
bonus.setChannelId(channel.getChannelId());
|
||||
bonus.setStatus(BonusStatus.UN_DIVIDEND.getStatus());
|
||||
bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus());
|
||||
}
|
||||
|
||||
// 拆分金额
|
||||
// 平台最低需要的分成金额
|
||||
BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
|
||||
BonusUtil.partBonusAmount(bonusList, bill.getMoney(), minService);
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.ruoyi.ss.bonus.service.impl;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -11,18 +10,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.domain.vo.CommonCountVO;
|
||||
import com.ruoyi.common.domain.vo.CommonSumVO;
|
||||
import com.ruoyi.common.domain.vo.LocalDateDecimalVO;
|
||||
import com.ruoyi.common.domain.vo.LongDecimalVO;
|
||||
import com.ruoyi.common.enums.LoginType;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.bonus.domain.BonusProvideQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusVO;
|
||||
import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
|
||||
|
@ -30,15 +23,12 @@ import com.ruoyi.ss.bonus.domain.enums.BonusBstType;
|
|||
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
|
||||
import com.ruoyi.ss.bonus.domain.vo.BonusDailyAmountVO;
|
||||
import com.ruoyi.ss.bonus.domain.vo.BonusMonthAmountVO;
|
||||
import com.ruoyi.ss.bonus.domain.vo.ProvideBonusVO;
|
||||
import com.ruoyi.ss.bonus.mapper.BonusMapper;
|
||||
import com.ruoyi.ss.bonus.service.BonusService;
|
||||
import com.ruoyi.ss.bonus.utils.BonusUtil;
|
||||
import com.ruoyi.ss.recordBalance.domain.enums.RecordBalanceBstType;
|
||||
import com.ruoyi.ss.user.domain.SmUserVO;
|
||||
import com.ruoyi.ss.user.service.UserAssembler;
|
||||
import com.ruoyi.ss.user.service.UserService;
|
||||
import com.ruoyi.system.domain.enums.config.ConfigKey;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -205,22 +195,12 @@ public class BonusServiceImpl implements BonusService
|
|||
}
|
||||
|
||||
@Override
|
||||
public int partBonus(List<? extends Bonus> bonusList, BigDecimal money) {
|
||||
if (CollectionUtils.isEmptyElement(bonusList) || money == null) {
|
||||
public int prePay(List<? extends Bonus> bonusList) {
|
||||
if (CollectionUtils.isEmptyElement(bonusList)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 设置预计分成时间等数据
|
||||
this.setWaitBonusInfo(bonusList);
|
||||
|
||||
// 更新数据库
|
||||
return this.batchUpdateAmount(bonusList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置待分成数据
|
||||
*/
|
||||
private void setWaitBonusInfo(List<? extends Bonus> bonusList) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 获取用户列表
|
||||
|
@ -233,7 +213,6 @@ public class BonusServiceImpl implements BonusService
|
|||
userAssembler.assembleRealArrivalDelay(userList);
|
||||
|
||||
for (Bonus bonus : bonusList) {
|
||||
bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus());
|
||||
// 设置预计分成时间
|
||||
if (BonusArrivalType.userList().contains(bonus.getArrivalType())) {
|
||||
SmUserVO user = userList.stream().filter(item -> item.getUserId().equals(bonus.getArrivalId())).findFirst().orElse(null);
|
||||
|
@ -245,6 +224,15 @@ public class BonusServiceImpl implements BonusService
|
|||
bonus.setPrePayTime(now);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
Integer result = transactionTemplate.execute(status -> {
|
||||
int rows = bonusMapper.prePay(bonusList);
|
||||
ServiceUtil.assertion(rows != bonusList.size(), "预分成失败,请刷新后重试");
|
||||
return rows;
|
||||
});
|
||||
|
||||
return result == null ? 0 : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -200,5 +200,9 @@ public class BonusUtil {
|
|||
// 处理误差后的分配金额
|
||||
dividedAmount = CollectionUtils.sumDecimal(bonusList, Bonus::getAmount);
|
||||
ServiceUtil.assertion(dividedAmount.compareTo(money) != 0, "分成金额分配出错");
|
||||
|
||||
for (Bonus bonus : bonusList) {
|
||||
bonus.setWaitAmount(bonus.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ruoyi.ss.transactionBill.service.TransactionAssembler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -148,6 +149,10 @@ public class DeviceServiceImpl implements DeviceService
|
|||
@Autowired
|
||||
private ICommandLogService commandLogService;
|
||||
|
||||
@Autowired
|
||||
private TransactionAssembler transactionAssembler;
|
||||
|
||||
|
||||
/**
|
||||
* 查询设备
|
||||
*
|
||||
|
@ -1254,6 +1259,7 @@ public class DeviceServiceImpl implements DeviceService
|
|||
if (CollectionUtils.isEmptyElement(billList)) {
|
||||
return 0;
|
||||
}
|
||||
transactionAssembler.assembleBonusList(billList);
|
||||
|
||||
return transactionBillService.batchCloseBillByDevice(billList, device, totalEle);
|
||||
}
|
||||
|
|
|
@ -394,6 +394,6 @@ public interface TransactionBillService {
|
|||
/**
|
||||
* 处理已结束订单
|
||||
*/
|
||||
boolean handleFinished(TransactionBillVO bill);
|
||||
boolean handleFinishedBonus(TransactionBillVO bill);
|
||||
|
||||
}
|
||||
|
|
|
@ -1032,7 +1032,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
ServiceUtil.assertion(!TransactionBillStatus.SUCCESS.getStatus().equals(order.getStatus()), "当前订单状态不允许结束");
|
||||
ServiceUtil.assertion(device == null, "设备不存在");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now(); // 结束使用的时间
|
||||
LocalDateTime endTime = LocalDateTime.now(); // 结束使用的时间
|
||||
|
||||
// 结束使用的电量:若蓝牙传过来的值为空或者小于当前电量,则使用当前电量,否则使用蓝牙传输的电量(谁大用谁)
|
||||
BigDecimal totalEle = this.calcTotalEle(device, bo.getTotalEle());
|
||||
|
@ -1041,9 +1041,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
ServiceUtil.assertion(order.getIsFinished() != null && order.getIsFinished(), "当前订单已结束,无法操作");
|
||||
|
||||
Integer result = transactionTemplate.execute(status -> {
|
||||
// 修改结束使用的时间
|
||||
// 修改结束使用的电量
|
||||
TransactionBill data = new TransactionBill();
|
||||
data.setSuitEndTime(now);
|
||||
data.setSuitEndTime(endTime);
|
||||
data.setSuitEndEle(totalEle);
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
query.setBillId(order.getBillId());
|
||||
|
@ -1054,7 +1054,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
|
||||
// 若是分时段电量,则记录一次电量金额
|
||||
if (SuitFeeType.TIMING_COUNT.getType().equals(order.getSuitFeeType())) {
|
||||
BillEleRecord record = billEleRecordConverter.toPo(order, device, now, now);
|
||||
BillEleRecord record = billEleRecordConverter.toPo(order, device, endTime, endTime);
|
||||
int insertRecord = billEleRecordService.insertBillEleRecord(record);
|
||||
ServiceUtil.assertion(insertRecord != 1, "记录分时段订单%s用电量失败", order.getBillNo());
|
||||
}
|
||||
|
@ -1064,21 +1064,36 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
|
||||
boolean success = result != null && result == 1; // 是否成功
|
||||
|
||||
// 若成功,且为智能模式,则计算需要退款的金额, 若金额 > 0.01 则申请退款
|
||||
if (success && SuitFeeMode.SMART.getMode().equals(order.getSuitFeeMode())) {
|
||||
BigDecimal refundAmount = this.calcRefundAmount(order, now, totalEle);
|
||||
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
|
||||
// 成功后操作
|
||||
if (success) {
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
// 智能退款
|
||||
BigDecimal refundAmount = this.calcRefundAmount(order, endTime, totalEle);
|
||||
if (SuitFeeMode.SMART.getMode().equals(order.getSuitFeeMode())) {
|
||||
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
|
||||
try {
|
||||
BillRefundDTO refundDto = new BillRefundDTO();
|
||||
refundDto.setBillId(order.getBillId());
|
||||
refundDto.setRefundAmount(refundAmount);
|
||||
refundDto.setRefundReason(String.format("充值订单%s智能退款%s元", order.getBillNo(), refundAmount));
|
||||
refundDto.setCheckFinish(false);
|
||||
int refund = this.refund(refundDto);
|
||||
ServiceUtil.assertion(refund != 1, "申请退款失败");
|
||||
} catch (Exception e) {
|
||||
log.error("订单{}智能退款失败:{}", order.getBillNo(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理分成
|
||||
this.handleFinishedBonus(order);
|
||||
|
||||
// 10秒后,执行一次分成
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
// 申请退款
|
||||
BillRefundDTO refundDto = new BillRefundDTO();
|
||||
refundDto.setBillId(order.getBillId());
|
||||
refundDto.setRefundAmount(refundAmount);
|
||||
refundDto.setRefundReason(String.format("充值订单%s智能退款%s元", order.getBillNo(), refundAmount));
|
||||
refundDto.setCheckFinish(false);
|
||||
int refund = this.refund(refundDto);
|
||||
ServiceUtil.assertion(refund != 1, "申请退款失败");
|
||||
bonusService.payBonusBeforeTime(LocalDateTime.now());
|
||||
}, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
}, 10, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
return result == null ? 0 : result;
|
||||
|
@ -1892,7 +1907,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFinished(TransactionBillVO bill) {
|
||||
public boolean handleFinishedBonus(TransactionBillVO bill) {
|
||||
if (bill == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1901,11 +1916,11 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
}
|
||||
|
||||
Boolean result = transactionTemplate.execute(status -> {
|
||||
// TODO 更新订单流程状态
|
||||
// TODO 若订单没有结束时间,则更新订单的结束时间
|
||||
// 更新订单流程状态
|
||||
// 若订单没有结束时间,则更新订单的结束时间
|
||||
TransactionBill data = new TransactionBill();
|
||||
data.setFinished(true);
|
||||
if (data.getSuitEndTime() == null) {
|
||||
if (bill.getSuitEndTime() == null) {
|
||||
data.setSuitEndTime(LocalDateTime.now());
|
||||
}
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
|
@ -1915,15 +1930,16 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
query.setStatusList(TransactionBillStatus.payedOrder());
|
||||
query.setBillId(bill.getBillId());
|
||||
int rows = this.updateByQuery(data, query);
|
||||
ServiceUtil.assertion(rows != 1, "订单%s的流程状态已发生变化,请稍后重试", bill.getBillNo());
|
||||
|
||||
if (rows == 1 && bill.getBonusList() != null) {
|
||||
// 过滤未出账的分成
|
||||
if (bill.getBonusList() != null) {
|
||||
// 过滤没有预计支付时间的待分成
|
||||
List<BonusVO> waitDivideBonusList = bill.getBonusList().stream()
|
||||
.filter(item -> BonusStatus.UN_DIVIDEND.getStatus().equals(item.getStatus()))
|
||||
.filter(item -> BonusStatus.WAIT_DIVIDE.getStatus().equals(item.getStatus()) && item.getPrePayTime() == null)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmptyElement(waitDivideBonusList)) {
|
||||
// 出账
|
||||
bonusService.partBonus(bill.getBonusList(), bill.getMoney());
|
||||
// 预支付
|
||||
bonusService.prePay(bill.getBonusList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,8 +229,8 @@ public class VipOrderServiceImpl implements VipOrderService, AfterPay, AfterRefu
|
|||
int insertBonus = bonusService.batchInsert(bonusList);
|
||||
ServiceUtil.assertion(insertBonus != bonusList.size(), "创建分成失败");
|
||||
|
||||
// 分配金额
|
||||
int part = bonusService.partBonus(bonusList, order.getAmount());
|
||||
// 预分成
|
||||
int part = bonusService.prePay(bonusList);
|
||||
ServiceUtil.assertion(part != bonusList.size(), "分配分成失败");
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.time.LocalDateTime;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -130,12 +131,13 @@ public class BillMonitorTask {
|
|||
/**
|
||||
* TODO 监控订单
|
||||
*/
|
||||
public void monitor() {
|
||||
public void monitor(String startTime) {
|
||||
// 查询已结束,但未进行流程的订单
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
query.setType(TransactionBillType.RECHARGE.getType());
|
||||
query.setIsFinished(true);
|
||||
query.setFinished(false);
|
||||
query.setCreateTimeStart(DateUtils.toLocalDateTime(startTime));
|
||||
query.setStatusList(TransactionBillStatus.payedOrder());
|
||||
List<TransactionBillVO> list = transactionBillService.selectSmTransactionBillList(query);
|
||||
|
||||
|
@ -149,7 +151,7 @@ public class BillMonitorTask {
|
|||
|
||||
for (TransactionBillVO bill : list) {
|
||||
try {
|
||||
transactionBillService.handleFinished(bill);
|
||||
transactionBillService.handleFinishedBonus(bill);
|
||||
} catch (Exception e) {
|
||||
log.warn("处理已结束订单{}出错:{}", bill.getBillNo(), e.getMessage());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user