فهرست منبع

绑定、解绑码商
一键结算通道

LiYi 1 هفته پیش
والد
کامیت
98454daa60

+ 3 - 0
src/main/java/org/jebot/constant/Constant.java

@@ -36,6 +36,7 @@ public class Constant {
     /* ----------------------------一键结算--------------------------------- */
 
     public static final String SETTLE_MCH = "所有账单";
+    public static final String SETTLE_PASSAGE = "所有通道账单";
 
     /* ----------------------------添加管理指令标识--------------------------------- */
     public static final String ADD_ADMIN = "增加管理";
@@ -66,6 +67,8 @@ public class Constant {
     //通过群组 ID 解绑商户号
     public static final String UNBIND_MCH_FLAG = "解绑商户";
     public static final String BIND_MCH_FLAG = "绑定商户";
+    public static final String BIND_CODEPRO_FLAG = "绑定码商";
+    public static final String UNBIND_CODEPRO_FLAG = "解绑码商";
     public static final String BIND_MCH_USTDURL = "绑定商户地址";
     //通过群组 ID 关闭商户
     public static final String DISABLE_MCH = "关闭商户";

+ 8 - 2
src/main/java/org/jebot/handler/impl/HelpHandler.java

@@ -41,7 +41,10 @@ public class HelpHandler extends AbstractHandler {
                             "%s: \"代收记账\"(%s500或%s-500)\n" +
                             "%s: \"代付记账\"(%s500或%s-500)\n"+
                             "%s: 代收记账24小时历史\n"+
-                            "%s: 代付记账24小时历史\n",
+                            "%s: 代付记账24小时历史\n"+
+                            "%s: 绑定码商\n"+
+                            "%s: 解绑码商\n"+
+                            "%s: 所有通道账单\n",
                     QUERY_USDT_TO_ALIPAY_CNY,
                     QUERY_USDT_TO_WECAHT_CNY,
                     QUERY_USDT_TO_BANK_CNY,
@@ -83,7 +86,10 @@ public class HelpHandler extends AbstractHandler {
                     AGENT_ACCOUNT_FLAG,
                     AGENT_ACCOUNT_FLAG,
                     PAYMENT_ACCOUNT_HISTORY_FLAG,
-                    AGENT_ACCOUNT_HISTORY_FLAG);
+                    AGENT_ACCOUNT_HISTORY_FLAG,
+                    BIND_CODEPRO_FLAG,   // 新增绑定码商
+                    UNBIND_CODEPRO_FLAG,
+                    SETTLE_PASSAGE);     // 新增所有通道账单
             SendMessage sendMessage = new SendMessage(botMessage.getMessage().chat().id(), helpMessage);
             botMessage.getTelegramBot().execute(sendMessage);
             return true;

+ 115 - 2
src/main/java/org/jebot/handler/impl/channel/ChannelBindGroupOrUnbindGroupHandler.java

@@ -11,10 +11,10 @@ import org.jebot.handler.dto.BotMessage;
 import org.jebot.models.jebot.BotGroup;
 import org.jebot.models.xxpay.PayPassage;
 
+import java.util.List;
 import java.util.regex.Pattern;
 
-import static org.jebot.constant.Constant.BIND_CHANNEL_FLAG;
-import static org.jebot.constant.Constant.UNBIND_CHANNEL_FLAG;
+import static org.jebot.constant.Constant.*;
 
 @Slf4j
 public class ChannelBindGroupOrUnbindGroupHandler extends AbstractHandler {
@@ -22,10 +22,13 @@ public class ChannelBindGroupOrUnbindGroupHandler extends AbstractHandler {
     //根据通道编号绑定到群组
     private static final Pattern BIND_CHANNEL = Pattern.compile("^" + BIND_CHANNEL_FLAG + "[a-zA-Z0-9]+(,[a-zA-Z0-9]+)*$");
 
+    private static final Pattern BIND_CODEPRO = Pattern.compile("^" + BIND_CODEPRO_FLAG + "[a-zA-Z0-9]+(,[a-zA-Z0-9]+)*$");
+
 
 
     //根据通道编号解绑群组
     private static final Pattern UNBIND_CHANNEL = Pattern.compile("^" + UNBIND_CHANNEL_FLAG + "[a-zA-Z0-9]+(,[a-zA-Z0-9]+)*$");
+    private static final Pattern UNBIND_CODEPRO = Pattern.compile("^" + UNBIND_CODEPRO_FLAG + "[a-zA-Z0-9]+(,[a-zA-Z0-9]+)*$");
 
     @Override
     public boolean msgHandler(BotMessage botMessage) {
@@ -69,6 +72,51 @@ public class ChannelBindGroupOrUnbindGroupHandler extends AbstractHandler {
             }
             return true;
         }
+
+
+        //码商部分 通过码商id查询通道id 批量绑定解绑
+        if (BIND_CODEPRO.matcher(botMessage.getMessageText()).find()) {
+            bindChannelByCodeproId(botMessage);
+            return true;
+        }
+
+        if (UNBIND_CODEPRO.matcher(botMessage.getMessageText()).find()) {
+            // 1. 解析码商ID
+            Long codeproId;
+            try {
+                codeproId = Long.valueOf(botMessage.getMessageText().replace(UNBIND_CODEPRO_FLAG, "").trim());
+            } catch (NumberFormatException e) {
+                SendMessage sendMessage = new SendMessage(botMessage.getMessage().chat().id(), "码商ID格式错误");
+                sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+                botMessage.getTelegramBot().execute(sendMessage);
+                return true;
+            }
+
+            // 2. 查询该码商名下的通道列表
+            List<PayPassage> passages = handlerManager.getPassageRepository().findByCodepro(codeproId);
+            if (passages.isEmpty()) {
+                SendMessage sendMessage = new SendMessage(botMessage.getMessage().chat().id(), "该码商没有绑定通道");
+                sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+                botMessage.getTelegramBot().execute(sendMessage);
+                return true;
+            }
+
+            // 3. 循环解绑每个通道
+            for (PayPassage payPassage : passages) {
+                handlerManager.getGroupRepository()
+                        .deleteByDataIDAndDataType(payPassage.getId(), Constant.DATA_TYPE_CHANNEL);
+            }
+
+            // 4. 发送结果
+            SendMessage sendMessage = new SendMessage(botMessage.getMessage().chat().id(), "解绑成功");
+            sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+            SendResponse execute = botMessage.getTelegramBot().execute(sendMessage);
+            if (!execute.isOk()) {
+                log.error("解绑通道结果发送失败: {}", execute);
+            }
+            return true;
+        }
+
         return false;
     }
 
@@ -117,6 +165,71 @@ public class ChannelBindGroupOrUnbindGroupHandler extends AbstractHandler {
         }
     }
 
+    private void bindChannelByCodeproId(BotMessage botMessage) {
+        StringBuilder sb = new StringBuilder();
+        Chat chat = botMessage.getMessage().chat();
+
+        // 1. 获取码商ID
+        Long codeproId;
+        try {
+            codeproId = Long.valueOf(botMessage.getMessageText().replace(BIND_CODEPRO_FLAG, "").trim());
+        } catch (NumberFormatException e) {
+            SendMessage sendMessage = new SendMessage(chat.id(), "码商ID格式错误");
+            sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+            botMessage.getTelegramBot().execute(sendMessage);
+            return;
+        }
+
+        // 2. 根据码商ID查询通道列表
+        List<PayPassage> passages = handlerManager.getPassageRepository().findByCodepro(codeproId);
+        if (passages.isEmpty()) {
+            SendMessage sendMessage = new SendMessage(chat.id(), "该码商没有对应的通道");
+            sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+            botMessage.getTelegramBot().execute(sendMessage);
+            return;
+        }
+
+        // 3. 循环绑定每个通道
+        for (PayPassage payPassage : passages) {
+            Long channelId = payPassage.getId();
+
+            BotGroup botGroup = handlerManager.getGroupRepository()
+                    .findBotGroupByDataIdAndDataType(channelId, Constant.DATA_TYPE_CHANNEL);
+
+            if (botGroup == null) {
+                // 通道不存在,保存通道绑定信息
+                botGroup = new BotGroup();
+                botGroup.setDataId(channelId);
+                botGroup.setDataName(payPassage.getPassageName());
+                botGroup.setGroupId(chat.id());
+                botGroup.setGroupName(chat.title());
+                botGroup.setDataType(Constant.DATA_TYPE_CHANNEL);
+                handlerManager.getGroupRepository().save(botGroup);
+                sb.append(String.format("%s:%s\r\n", channelId, "绑定成功"));
+                continue;
+            }
+
+            if (chat.id().equals(botGroup.getGroupId())) {
+                sb.append(String.format("%s:%s\r\n", channelId, "已绑定到当前群组"));
+                continue;
+            }
+
+            // 变更绑定到当前群组
+            botGroup.setGroupId(chat.id());
+            handlerManager.getGroupRepository().save(botGroup);
+            sb.append(String.format("%s:%s\r\n", channelId, String.format("从绑定 %s 群组变更为绑定 %s 群组", payPassage.getPassageName(), chat.title())));
+        }
+
+        // 4. 发送绑定结果
+        SendMessage sendMessage = new SendMessage(chat.id(), sb.toString());
+        sendMessage.replyParameters(new ReplyParameters(botMessage.getMessage().messageId()));
+        SendResponse execute = botMessage.getTelegramBot().execute(sendMessage);
+        if (!execute.isOk()) {
+            log.error("绑定通道结果发送失败: {}", execute);
+        }
+    }
+
+
     private static String[] getChannelIds(String text, String replaceStr) {
         String channelIdsStr = text.replace(replaceStr, "");
         if (channelIdsStr.contains(",")) {

+ 72 - 0
src/main/java/org/jebot/handler/impl/merchant/MerchantOneClickSettlementHandler.java

@@ -11,6 +11,7 @@ import org.jebot.models.jebot.BotAccountBook;
 import org.jebot.models.jebot.BotGroup;
 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 java.math.BigDecimal;
@@ -150,9 +151,80 @@ public class MerchantOneClickSettlementHandler extends AbstractHandler {
             return true;
         }
 
+
+        //一键结算所有通道
+        if (SETTLE_PASSAGE.equals(message.getMessageText())) {
+            Date endDate = getYesnight();
+            Date todayMidnight = getTodayMidnight(endDate);
+            List<BotGroup> botGroups = handlerManager.getGroupRepository().findAllByAgentWarningThresholdOrPaymentWarningThresholdGreaterThanZero();
+            List<BotGroup> mchGroups = botGroups.stream().filter(botGroup -> Constant.DATA_TYPE_CHANNEL.equals(botGroup.getDataType())).collect(Collectors.toList());
+            if (!mchGroups.isEmpty()) {
+                List<Long> mchIds = mchGroups.stream().map(BotGroup::getDataId).collect(Collectors.toList());
+                List<PayPassage> mchAccounts = handlerManager.getPassageRepository().findByPassageIds(mchIds);
+                if (mchAccounts.isEmpty()) {
+                    return true;
+                }
+                Map<Long, PayPassage> mchAccountMap = mchAccounts.stream()
+                        .collect(Collectors.toMap(PayPassage::getId, payPassage -> payPassage));
+                StringBuilder messageText = new StringBuilder();
+                for (BotGroup mchGroup : mchGroups) {
+                    //判断商户是否存在
+                    PayPassage mchAccount = mchAccountMap.get(mchGroup.getDataId());
+                    if (mchAccount == null) {
+                        messageText.append(mchGroup.getDataName()).append("[").append(mchGroup.getDataId()).append("]").append(": 通道不存在\n");
+                        return false;
+                    }
+                    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");
+                        return false;
+                    }
+
+                    if (SettlementMch(message, mchGroup, payOrderList, todayMidnight, endDate)) {
+                        messageText.append(mchAccount.getPassageName()).append(": 结算成功\n");
+                    } else {
+                        messageText.append(mchAccount.getPassageName()).append(": 结算失败\n");
+                    }
+
+                    //防止发送消息过快
+                    try {
+                        Thread.sleep(500);
+                    } catch (InterruptedException e) {
+                        log.error(e.getMessage());
+                        e.printStackTrace();
+                    }
+
+                }
+                SendMessage sendMessage = new SendMessage(message.getMessage().chat().id(), messageText.toString());
+                SendResponse execute = message.getTelegramBot().execute(sendMessage);
+                if (!execute.isOk()) {
+                    log.error("一键通道结算发送消息失败, 错误信息: {}", execute.description());
+                } else {
+                    //记录结算记录
+                    log.info("一键通道结算发送消息成功, 群组ID: {}, 结算记录: {}", message.getMessage().chat().id(), messageText.toString());
+                }
+            } else {
+                SendMessage sendMessage = new SendMessage(message.getMessage().chat().id(), "没有通道群组");
+                SendResponse execute = message.getTelegramBot().execute(sendMessage);
+                if (!execute.isOk()) {
+                    log.error("一键通道结算发送消息失败, 错误信息: {}", execute.description());
+                } else {
+                    //记录结算记录
+                    log.info("一键通道结算发送消息成功, 群组ID: {}, 结算记录: {}", message.getMessage().chat().id(), "没有商户群组");
+                }
+            }
+            return true;
+        }
+
         return false;
     }
 
+
+
     private boolean SettlementMch(BotMessage message, BotGroup mchGroup, List<PayOrder> payOrderList, Date todayMidnight, Date endDate) {
 
         StringBuilder stringBuilder = new StringBuilder();

+ 3 - 0
src/main/java/org/jebot/models/xxpay/PayPassage.java

@@ -24,4 +24,7 @@ public class PayPassage {
 
     @Column(name = "Status")
     private int status;      // 通道ID 通道状态,0-关闭,1-开启
+
+    @Column(name = "Codepro")
+    private int codepro;      // 码商id
 }

+ 3 - 0
src/main/java/org/jebot/repository/xxpay/PayOrderRepository.java

@@ -31,6 +31,9 @@ public interface PayOrderRepository extends JpaRepository<PayOrder, String> {
     @Query("SELECT new org.jebot.models.xxpay.PayOrder( tpo.amount,tpo.mchId,tpo.mchRate,tpo.passageId,tpo.status,tpo.createTime) FROM t_pay_order as tpo WHERE  tpo.mchId =:mchId and tpo.status in (2,3) and tpo.createTime >= :startTime and tpo.createTime <= :endTime")
     List<PayOrder> findSuccessPayOrderByMchIdAndCreateTime(Long mchId, Date startTime, Date endTime);
 
+    @Query("SELECT new org.jebot.models.xxpay.PayOrder( tpo.amount,tpo.mchId,tpo.mchRate,tpo.passageId,tpo.status,tpo.createTime) FROM t_pay_order as tpo WHERE  tpo.passageId =:passageId and tpo.status in (2,3) and tpo.createTime >= :startTime and tpo.createTime <= :endTime")
+    List<PayOrder> findSuccessPayOrderByPassageIdAndCreateTime(Long passageId, Date startTime, Date endTime);
+
     @Query("SELECT new org.jebot.models.xxpay.PayOrder( tpo.amount,tpo.mchId,tpo.mchRate,tpo.payPassageRate,tpo.passageId,tpo.status,tpo.createTime) FROM t_pay_order as tpo WHERE tpo.passageId in (:passageIds) and tpo.createTime >= :startTime and tpo.createTime <= :endTime and tpo.status in(2,3)")
     List<PayOrder> findPayOrderByPassageAndCreateTime(List<Long> passageIds, Date startTime, Date endTime);
 

+ 3 - 0
src/main/java/org/jebot/repository/xxpay/PayPassageRepository.java

@@ -16,6 +16,9 @@ public interface PayPassageRepository extends JpaRepository<PayPassage, Long> {
     @Query("SELECT t FROM t_pay_passage t WHERE t.id in (:passageIds)")
     List<PayPassage> findByPassageIds(List<Long> passageIds);
 
+    @Query("SELECT t FROM t_pay_passage t WHERE t.codepro =:codepro")
+    List<PayPassage> findByCodepro(Long codepro);
+
     @Query("SELECT t FROM t_pay_passage t WHERE t.id =:passageId")
     PayPassage findByPassageId(Long passageId);