|
@@ -14,6 +14,7 @@ import org.jebot.models.jebot.BotGroup;
|
|
|
import org.jebot.models.jebot.BotUser;
|
|
|
import org.jebot.models.xxpay.MchAccount;
|
|
|
import org.jebot.models.xxpay.PayOrder;
|
|
|
+import org.jebot.models.xxpay.PayPassage;
|
|
|
import org.jebot.service.dto.UpdateBalance;
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
@@ -27,9 +28,11 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
-import static org.jebot.constant.Constant.DATA_TYPE_MERCHANT;
|
|
|
+import static org.jebot.constant.Constant.*;
|
|
|
+import static org.jebot.constant.Constant.AMOUNT_MOVE_POINT;
|
|
|
import static org.jebot.util.DateUtil.getTodayMidnight;
|
|
|
import static org.jebot.util.DateUtil.getYesnight;
|
|
|
+
|
|
|
@Slf4j
|
|
|
@RestController
|
|
|
public class BotRest {
|
|
@@ -49,6 +52,103 @@ public class BotRest {
|
|
|
return "TelegramBot 已成功重载";
|
|
|
}
|
|
|
|
|
|
+ //宝塔定时调用接口触发
|
|
|
+ @GetMapping("/dailyChannelSettlement")
|
|
|
+ public String dailyChannelSettlement() {
|
|
|
+ log.info("定时任务开始:每日通道结算");
|
|
|
+
|
|
|
+ Date endDate = getYesnight();
|
|
|
+ Date todayMidnight = getTodayMidnight(endDate);
|
|
|
+
|
|
|
+ // 获取所有有告警阈值的群组
|
|
|
+ List<BotGroup> botGroups = handlerManager.getGroupRepository()
|
|
|
+ .findAllByAgentWarningThresholdOrPaymentWarningThresholdGreaterThanZero();
|
|
|
+
|
|
|
+ // 只保留通道类型群组
|
|
|
+ List<BotGroup> mchGroups = botGroups.stream()
|
|
|
+ .filter(botGroup -> DATA_TYPE_CHANNEL.equals(botGroup.getDataType()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (mchGroups.isEmpty()) {
|
|
|
+ log.info("没有通道群组");
|
|
|
+ return "没有通道群组";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询通道信息
|
|
|
+ List<Long> mchIds = mchGroups.stream().map(BotGroup::getDataId).collect(Collectors.toList());
|
|
|
+ List<PayPassage> mchAccounts = handlerManager.getPassageRepository().findByPassageIds(mchIds);
|
|
|
+ if (mchAccounts.isEmpty()) {
|
|
|
+ return "没有通道信息";
|
|
|
+ }
|
|
|
+ Map<Long, PayPassage> mchAccountMap = mchAccounts.stream()
|
|
|
+ .collect(Collectors.toMap(PayPassage::getId, payPassage -> payPassage));
|
|
|
+
|
|
|
+ for (BotGroup mchGroup : mchGroups) {
|
|
|
+ BotMessage message = new BotMessage();
|
|
|
+ message.setBotGroup(mchGroup);
|
|
|
+ message.setTelegramBot(telegramBot);
|
|
|
+ BotUser botUser = new BotUser();
|
|
|
+ botUser.setUserName("接口");
|
|
|
+ botUser.setUserId(1L);
|
|
|
+ message.setBotUser(botUser);
|
|
|
+
|
|
|
+ StringBuilder messageText = new StringBuilder();
|
|
|
+
|
|
|
+ PayPassage mchAccount = mchAccountMap.get(mchGroup.getDataId());
|
|
|
+ if (mchAccount == null) {
|
|
|
+ messageText.append(mchGroup.getDataName())
|
|
|
+ .append("[").append(mchGroup.getDataId()).append("]")
|
|
|
+ .append(": 通道不存在\n");
|
|
|
+ messageText.append("处理结束\n");
|
|
|
+ sendMessageAndLog(message, messageText.toString());
|
|
|
+ continue; // 处理下一个群组
|
|
|
+ }
|
|
|
+
|
|
|
+ if (mchAccount.getStatus() != 1) {
|
|
|
+ messageText.append(mchAccount.getPassageName()).append(": 通道状态异常\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询订单
|
|
|
+ List<PayOrder> payOrderList = handlerManager.getPayOrderRepository()
|
|
|
+ .findSuccessPayOrderByPassageIdAndCreateTime(mchGroup.getDataId(), todayMidnight, endDate);
|
|
|
+
|
|
|
+ if (payOrderList.isEmpty()) {
|
|
|
+ messageText.append(mchAccount.getPassageName()).append(": 无订单数据\n");
|
|
|
+ sendMessageAndLog(message, messageText.toString());
|
|
|
+ continue; // 处理下一个群组
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行结算
|
|
|
+ SettlementPassage(message, mchGroup, payOrderList, todayMidnight, endDate);
|
|
|
+
|
|
|
+ // 记录消息内容
|
|
|
+ messageText.append("结算完成: ").append(mchAccount.getPassageName()).append("\n");
|
|
|
+
|
|
|
+ // 防止发送消息过快
|
|
|
+ try {
|
|
|
+ Thread.sleep(500);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ log.error("线程中断: {}", e.getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ sendMessageAndLog(message, messageText.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ return "每日通道结算调用结算成功";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送消息并记录日志的工具方法
|
|
|
+ */
|
|
|
+ private void sendMessageAndLog(BotMessage message, String content) {
|
|
|
+ SendMessage sendMessage = new SendMessage(message.getBotGroup().getDataId(), content);
|
|
|
+ SendResponse execute = message.getTelegramBot().execute(sendMessage);
|
|
|
+ if (!execute.isOk()) {
|
|
|
+ log.error("发送消息失败, 错误信息: {}", execute.description());
|
|
|
+ } else {
|
|
|
+ log.info("发送消息成功, 群组ID: {}, 内容: {}", message.getBotGroup().getDataId(), content);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
|
|
|
//宝塔定时调用接口触发
|
|
@@ -131,7 +231,7 @@ public class BotRest {
|
|
|
log.info("每日结算发送消息成功, 结算记录: {}", messageText);
|
|
|
}
|
|
|
}
|
|
|
- return "调用结算成功";
|
|
|
+ return "每日商户结算调用结算成功";
|
|
|
}
|
|
|
|
|
|
|
|
@@ -236,7 +336,113 @@ public class BotRest {
|
|
|
deductionAmount.doubleValue(),
|
|
|
e.getMessage());
|
|
|
e.printStackTrace();
|
|
|
- sendMessage = new SendMessage( message.getBotGroup().getDataId(),
|
|
|
+ sendMessage = new SendMessage(message.getBotGroup().getDataId(),
|
|
|
+ "下发处理失败,请手动处理");
|
|
|
+ } finally {
|
|
|
+ if (sendMessage != null) {
|
|
|
+ message.getTelegramBot().execute(sendMessage);
|
|
|
+ log.info("一键结算发送消息成功, 结算记录: {}", sendMessage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private boolean SettlementPassage(BotMessage message, BotGroup mchGroup, List<PayOrder> payOrderList, Date todayMidnight, Date endDate) {
|
|
|
+
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+
|
|
|
+ // 计算总金额(未扣手续费)
|
|
|
+ BigDecimal totalAmount = payOrderList.stream()
|
|
|
+ .map(PayOrder::getAmount)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+ // 成功总笔数
|
|
|
+ long totalOrders = payOrderList.size();
|
|
|
+
|
|
|
+ // 扣除手续费后的总跑量
|
|
|
+ BigDecimal totalAmountByMchRate = payOrderList.stream()
|
|
|
+ .map(order -> BigDecimal.ONE
|
|
|
+ .subtract(order.getPayPassageRate().movePointLeft(AMOUNT_MOVE_POINT))
|
|
|
+ .multiply(order.getAmount()))
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+ stringBuilder.append(DateUtil.formatDate(endDate)).append("【" + mchGroup.getDataName() + "】账单,请核对:\n");
|
|
|
+ stringBuilder.append("总跑量: ").append(totalAmount.movePointLeft(AMOUNT_MOVE_POINT).doubleValue()).append("\n");
|
|
|
+ stringBuilder.append("成功笔数: ").append(totalOrders).append("\n");
|
|
|
+ stringBuilder.append("扣除手续费总跑量: ").append(totalAmountByMchRate.movePointLeft(AMOUNT_MOVE_POINT).doubleValue()).append("\n");
|
|
|
+
|
|
|
+ // 扣除金额(手续费)
|
|
|
+ // 下发金额 = 总跑量 - 手续费
|
|
|
+ BigDecimal deductionAmount = totalAmountByMchRate.movePointLeft(AMOUNT_MOVE_POINT);
|
|
|
+
|
|
|
+ // ================= 发送账单 =================
|
|
|
+ SendMessage sendMessage = new SendMessage(mchGroup.getGroupId(), stringBuilder.toString());
|
|
|
+ SendResponse execute = message.getTelegramBot().execute(sendMessage);
|
|
|
+ if (!execute.isOk()) {
|
|
|
+ log.error("一键结算发送消息失败, 错误信息: {}", execute.description());
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ // ================= 更新商户账本 =================
|
|
|
+ BotAccountBook accountBook = handlerManager.getAccountBookRepository()
|
|
|
+ .findByBelongIdAndType(mchGroup.getDataId(), DATA_TYPE_CHANNEL);
|
|
|
+
|
|
|
+ if (accountBook == null) {
|
|
|
+ accountBook = new BotAccountBook();
|
|
|
+ accountBook.setBelongId(mchGroup.getDataId());
|
|
|
+ accountBook.setType(DATA_TYPE_CHANNEL);
|
|
|
+ accountBook.setPaymentBalance(0);
|
|
|
+ accountBook.setAgentBalance(0);
|
|
|
+ handlerManager.getAccountBookRepository().save(accountBook);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("一键结算发送消息成功, 群组ID: {}, 结算记录: {}", mchGroup.getGroupId(), stringBuilder.toString());
|
|
|
+ //查询总下发
|
|
|
+ BotAccountBook accountBookAll = handlerManager.getAccountBookRepository()
|
|
|
+ .findByBelongIdAndType(mchGroup.getGroupId(), DATA_TYPE_CHANNEL);
|
|
|
+ List<BotGroup> botGroups = this.handlerManager.getGroupRepository().findAllByGroupIdAndDataType(mchGroup.getGroupId(), DATA_TYPE_CHANNEL);
|
|
|
+ double oldPaymentBalance = 0;
|
|
|
+ for (BotGroup botGroup : botGroups) {
|
|
|
+ BotAccountBook accountBookchannl = handlerManager.getAccountBookRepository()
|
|
|
+ .findByBelongIdAndType(botGroup.getDataId(), DATA_TYPE_CHANNEL);
|
|
|
+ oldPaymentBalance += accountBookchannl.getPaymentBalance();
|
|
|
+ }
|
|
|
+ oldPaymentBalance += accountBookAll.getPaymentBalance();
|
|
|
+ double newPaymentBalance = BigDecimal.valueOf(oldPaymentBalance)
|
|
|
+ .subtract(deductionAmount).doubleValue();
|
|
|
+
|
|
|
+ BotMessage botMessage = new BotMessage();
|
|
|
+ botMessage.setBotGroup(mchGroup);
|
|
|
+ botMessage.setBotUser(message.getBotUser());
|
|
|
+
|
|
|
+ try {
|
|
|
+ UpdateBalance updateMerchantPaymentBalance = new UpdateBalance();
|
|
|
+ updateMerchantPaymentBalance.setId(accountBook.getId());
|
|
|
+ updateMerchantPaymentBalance.setOldBalance(accountBook.getPaymentBalance());
|
|
|
+ updateMerchantPaymentBalance.setNewBalance(BigDecimal.valueOf(accountBook.getPaymentBalance())
|
|
|
+ .subtract(deductionAmount).doubleValue());
|
|
|
+ updateMerchantPaymentBalance.setAmount(deductionAmount.doubleValue());
|
|
|
+ updateMerchantPaymentBalance.setMessage(botMessage);
|
|
|
+
|
|
|
+ handlerManager.getAccountBookService()
|
|
|
+ .updatePaymentBalanceByIdAndPaymentBalance(updateMerchantPaymentBalance);
|
|
|
+
|
|
|
+ sendMessage = new SendMessage(mchGroup.getGroupId(),
|
|
|
+ String.format("下发提醒\n下发金额: %.2f\n下发前: %.2f\n下发后: %.2f",
|
|
|
+ deductionAmount.doubleValue(), oldPaymentBalance, newPaymentBalance));
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新商户群组账本失败,群组ID:{},群组名称:{},用户ID:{},用户名称:{},金额:{},错误信息:{}",
|
|
|
+ message.getBotGroup().getDataId(),
|
|
|
+ message.getBotGroup().getDataName(),
|
|
|
+ message.getBotUser().getUserId(),
|
|
|
+ message.getBotUser().getUserName(),
|
|
|
+ deductionAmount.doubleValue(),
|
|
|
+ e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ sendMessage = new SendMessage(message.getBotGroup().getDataId(),
|
|
|
"下发处理失败,请手动处理");
|
|
|
} finally {
|
|
|
if (sendMessage != null) {
|