|
|
@@ -70,13 +70,6 @@ public class SettlementServiceImpl extends MyBaseServiceImpl<SettlementRecordMap
|
|
|
|
|
|
log.info("开始执行结算,周期:{}", period);
|
|
|
|
|
|
- // 幂等检查:如果本期已有结算记录则跳过
|
|
|
- long settledCount = lambdaQuery().eq(SettlementRecord::getSettlementPeriod, period).count();
|
|
|
- if (settledCount > 0) {
|
|
|
- log.warn("本期 {} 已有 {} 条结算记录,跳过重复结算", period, settledCount);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
// 汇总本期各站点分账数据
|
|
|
var allRecords = splitRecordService.lambdaQuery()
|
|
|
.ge(SplitRecord::getCreateTime, periodStart)
|
|
|
@@ -99,6 +92,16 @@ public class SettlementServiceImpl extends MyBaseServiceImpl<SettlementRecordMap
|
|
|
}
|
|
|
|
|
|
private void doStationSettlement(String stationId, String period, List<SplitRecord> allRecords) {
|
|
|
+ // 站点+周期幂等:已有结算记录(不论状态)则跳过
|
|
|
+ long existing = lambdaQuery()
|
|
|
+ .eq(SettlementRecord::getStationId, stationId)
|
|
|
+ .eq(SettlementRecord::getSettlementPeriod, period)
|
|
|
+ .count();
|
|
|
+ if (existing > 0) {
|
|
|
+ log.info("站点 {} 周期 {} 已有结算记录,跳过", stationId, period);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
int totalRecharge = sumByType(allRecords, stationId, SplitRecord.TYPE_RECHARGE, true);
|
|
|
int totalRefund = sumByType(allRecords, stationId, SplitRecord.TYPE_REFUND, false);
|
|
|
int totalCrossExpend = sumByType(allRecords, stationId, SplitRecord.TYPE_CROSS_EXPEND, false);
|
|
|
@@ -108,25 +111,16 @@ public class SettlementServiceImpl extends MyBaseServiceImpl<SettlementRecordMap
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 读取上期期末余额作为本期期初
|
|
|
int openingBalance = getOpeningBalance(stationId, period);
|
|
|
|
|
|
- // 本期货物流转净额
|
|
|
int netInflow = totalRecharge - totalRefund - totalCrossExpend + totalCrossIncome;
|
|
|
-
|
|
|
- // 微信提现手续费 0.6% — 钱从微信商户转出时先扣除,仅对货物流转净额计算
|
|
|
int withdrawalFee = netInflow > 0
|
|
|
? new BigDecimal(netInflow).multiply(WITHDRAWAL_FEE_RATE).setScale(0, RoundingMode.DOWN).intValue()
|
|
|
: 0;
|
|
|
-
|
|
|
- // 扣掉微信手续费后加上期结转,才是实际可分配金额
|
|
|
int afterWechat = openingBalance + netInflow - withdrawalFee;
|
|
|
-
|
|
|
- // 平台服务费 10% — 基于微信扣完手续费后可分配的金额
|
|
|
int platformFee = afterWechat > 0
|
|
|
? new BigDecimal(afterWechat).multiply(PLATFORM_FEE_RATE).setScale(0, RoundingMode.DOWN).intValue()
|
|
|
: 0;
|
|
|
-
|
|
|
int settlementAmount = afterWechat - platformFee;
|
|
|
|
|
|
SettlementRecord record = new SettlementRecord()
|
|
|
@@ -145,33 +139,17 @@ public class SettlementServiceImpl extends MyBaseServiceImpl<SettlementRecordMap
|
|
|
record.setSettlementAmount(settlementAmount)
|
|
|
.setClosingPendingBalance(0)
|
|
|
.setStatus(SettlementRecord.STATUS_待结算);
|
|
|
-
|
|
|
- // 增加站点可提现金额
|
|
|
- stationAccountService.lambdaUpdate()
|
|
|
- .setSql("available_balance = available_balance + {0}", settlementAmount)
|
|
|
- .eq(StationAccount::getStationId, stationId)
|
|
|
- .update();
|
|
|
-
|
|
|
- save(record);
|
|
|
-
|
|
|
- // 平台服务费收入记录
|
|
|
- if (platformFee > 0) {
|
|
|
- platformRevenueRecordService.saveRecord(record, stationId);
|
|
|
- platformAccountService.addRevenue(platformFee);
|
|
|
- }
|
|
|
-
|
|
|
- log.info("站点 {} 结算成功,金额:{} 分,平台费:{} 分,提现手续费:{} 分",
|
|
|
- stationId, settlementAmount, platformFee, withdrawalFee);
|
|
|
} else {
|
|
|
record.setSettlementAmount(0)
|
|
|
.setClosingPendingBalance(settlementAmount)
|
|
|
.setStatus(SettlementRecord.STATUS_异常结算)
|
|
|
.setRemark("结算金额为负,结转至下期");
|
|
|
+ }
|
|
|
|
|
|
- save(record);
|
|
|
+ save(record);
|
|
|
|
|
|
- log.warn("站点 {} 异常结算,结转金额:{} 分", stationId, settlementAmount);
|
|
|
- }
|
|
|
+ log.info("站点 {} 周期 {} 结算记录已生成,状态:{},金额:{} 分,平台费:{} 分,提现手续费:{} 分",
|
|
|
+ stationId, period, record.getStatus(), record.getSettlementAmount(), platformFee, withdrawalFee);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -216,4 +194,40 @@ public class SettlementServiceImpl extends MyBaseServiceImpl<SettlementRecordMap
|
|
|
}).toList();
|
|
|
return new PageBean<>(voList);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void confirmSettlement(Long recordId) {
|
|
|
+ var record = getById(recordId);
|
|
|
+ if (record == null) {
|
|
|
+ throw new IllegalArgumentException("结算记录不存在");
|
|
|
+ }
|
|
|
+ if (record.getStatus() == SettlementRecord.STATUS_已结算) {
|
|
|
+ throw new IllegalArgumentException("该记录已确认,不可重复操作");
|
|
|
+ }
|
|
|
+ if (record.getStatus() != SettlementRecord.STATUS_待结算) {
|
|
|
+ throw new IllegalArgumentException("仅待结算记录可确认");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转入站点可提现余额
|
|
|
+ stationAccountService.lambdaUpdate()
|
|
|
+ .setSql("available_balance = available_balance + {0}", record.getSettlementAmount())
|
|
|
+ .eq(StationAccount::getStationId, record.getStationId())
|
|
|
+ .update();
|
|
|
+
|
|
|
+ // 平台服务费收入记录
|
|
|
+ if (record.getPlatformFee() != null && record.getPlatformFee() > 0) {
|
|
|
+ platformRevenueRecordService.saveRecord(record, record.getStationId());
|
|
|
+ platformAccountService.addRevenue(record.getPlatformFee());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新状态为已结算
|
|
|
+ lambdaUpdate()
|
|
|
+ .set(SettlementRecord::getStatus, SettlementRecord.STATUS_已结算)
|
|
|
+ .eq(SettlementRecord::getId, recordId)
|
|
|
+ .update();
|
|
|
+
|
|
|
+ log.info("结算确认完成,记录ID:{},站点:{},周期:{},金额:{} 分",
|
|
|
+ recordId, record.getStationId(), record.getSettlementPeriod(), record.getSettlementAmount());
|
|
|
+ }
|
|
|
}
|