debug: 分时段电量金额计算

This commit is contained in:
磷叶 2024-12-19 17:53:23 +08:00
parent 4d958866db
commit de170b8650

View File

@ -932,11 +932,15 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
DeviceVO device = deviceService.selectById(bill.getDeviceId());
deviceService.pullDeviceInfo(device);
Boolean result = transactionTemplate.execute(status -> {
// 更新订单套餐使用信息
// 更新订单套餐使用信息
transactionTemplate.execute(status -> {
int updateInfo = this.updateSuitInfoBeforeDevice(bill, device);
ServiceUtil.assertion(updateInfo != 1, "更新套餐使用信息失败");
return true;
});
// 充值设备
Boolean iotResult = transactionTemplate.execute(status -> {
// 更新订单设备充值状态成功
int updateRecharge = transactionBillMapper.updateDeviceRechargeStatus(
bill.getBillId(),
@ -970,9 +974,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return true;
});
// 是否成功
boolean success = result != null && result;
// 是否成功
boolean success = iotResult != null && iotResult;
if (!success) {
// 修改设备充值状态为失败
transactionBillMapper.updateDeviceRechargeStatus(
@ -1472,35 +1476,53 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 计算分时段计量金额
private BigDecimal calcTimingCountAmount(TransactionBillVO order, LocalDateTime endTime, BigDecimal totalEle) {
BigDecimal startEle = order.getSuitStartEle() == null ? BigDecimal.ZERO : order.getSuitStartEle(); // 起始电量
BigDecimal usedEle = totalEle == null ? BigDecimal.ZERO : totalEle.subtract(startEle); // 本次用电量
return calcTimingCountAmount(order.getSuitGearAmount(), order.getSuitGearTime(), order.getSuitStartTime(), endTime, usedEle);
}
// 计算分时段计量金额
private BigDecimal calcTimingCountAmount(List<BigDecimal> suitGearAmount, List<Integer> suitGearTime, LocalDateTime startTime, LocalDateTime endTime, BigDecimal usedEle) {
if (startTime == null) {
startTime = LocalDateTime.now();
}
BigDecimal total = BigDecimal.ZERO;
// 计算每小时平均用电量
LocalDateTime startTime = order.getSuitStartTime() == null ? LocalDateTime.now() : order.getSuitStartTime();
Duration betweenAvg = Duration.between(startTime, endTime);
long hours = betweenAvg.toHours();
if (hours == 0) {
hours = 1;
long minutes = betweenAvg.toMinutes();
if (minutes == 0) {
minutes = 1;
}
BigDecimal startEle = order.getSuitStartEle() == null ? BigDecimal.ZERO : order.getSuitStartEle();
BigDecimal usedEle = totalEle == null ? BigDecimal.ZERO : totalEle.subtract(startEle);
BigDecimal avgEle = usedEle.divide(BigDecimal.valueOf(hours), 2, RoundingMode.HALF_UP); // 平均每小时的用电量
BigDecimal avgEle = usedEle.divide(BigDecimal.valueOf(minutes), 6, RoundingMode.HALF_UP); // 平均每分钟的用电量 4.6
// 初始时间
List<BigDecimal> suitGearAmount = order.getSuitGearAmount();
List<Integer> suitGearTime = order.getSuitGearTime();
int hour = startTime.getHour() ;
LocalDateTime time = startTime ;
// 计算每个小时的金额
for (int i = 0; i < hours; i++) {
BigDecimal hourAmount = suitGearAmount.get(suitGearTime.get(hour)).multiply(avgEle);
total = total.add(hourAmount);
// 计算每分钟的金额
while(endTime.isAfter(time)) {
int hour = time.getHour();
BigDecimal minuteAmount = suitGearAmount.get(suitGearTime.get(hour)).multiply(avgEle);
total = total.add(minuteAmount);
hour = (hour + 1) % 24;
time = time.plusMinutes(1);
}
return total;
}
public static void main(String[] args) {
List<BigDecimal> suitGearAmount = Arrays.asList(new BigDecimal(0.22), new BigDecimal("0.39"), new BigDecimal("0.59"), new BigDecimal("0.89"));
List<Integer> suitGearTime = Arrays.stream("1,1,1,1,1,1,1,2,2,2,1,0,0,0,1,2,3,3,3,2,2,2,2,1".split(",")).map(Integer::parseInt).collect(Collectors.toList());
LocalDateTime startTime = DateUtils.toLocalDateTime("2024-12-19 12:45:31");
LocalDateTime endTime = DateUtils.toLocalDateTime("2024-12-20 14:58:35");
BigDecimal usedEle = new BigDecimal(13.8); // 总用电量 13.8
TransactionBillServiceImpl service = new TransactionBillServiceImpl();
BigDecimal total = service.calcTimingCountAmount(suitGearAmount, suitGearTime, startTime, endTime, usedEle);
System.out.println(total);
}
// 计算分时段计时金额
private BigDecimal calcTimingTimeAmount(TransactionBillVO order, LocalDateTime endTime) {
// 订单不存在 或者 开始时间为空则表示未开始使用返回0