admin
2025-02-20 fa677dec1c55db004a31beefb1e346e18c7858c2
src/main/java/com/taoke/autopay/manager/OrderPayFailProcessor.java
@@ -1,22 +1,25 @@
package com.taoke.autopay.manager;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.utils.StringUtil;
import lombok.Builder;
import lombok.Data;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.*;
/**
 * @author hxh
 * @title: OrderPayFailProcessor
 * @description: TODO
 * @description: 订单支付失败处理器
 * @date 2024/7/26 21:27
 */
@Component
@@ -24,7 +27,7 @@
    @Data
    @Builder
    public static class OrderQueue implements Comparable{
    public static class OrderQueue implements Comparable {
        private String id;
        private long expireTime;
@@ -37,73 +40,125 @@
    @Resource
    private KeyOrderService keyOrderService;
    private Map<String,Integer> reProcessCountMap=new HashMap<>();
    private Map<String, Integer> reProcessCountMap = new HashMap<>();
    private Queue<OrderQueue> orderQueues=new PriorityQueue<>();
    private Queue<OrderQueue> orderQueues = new PriorityQueue<>();
    public void clearCacheData(){
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private ClientInfoService clientInfoService;
    public void clearCacheData() {
        reProcessCountMap.clear();
        orderQueues.clear();
    }
    private Long getTargetClientId() {
        List<Long> clientIds = clientInfoService.getRePayClientIds();
        if (clientIds != null && clientIds.size() > 0) {
            // 查询设备未执行的数量
            List<List<Long>> clist=new ArrayList<>();
            for (Long cuid : clientIds) {
                KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
                daoQuery.distributeClientUid =cuid;
                daoQuery.state =  KeyOrder.STATE_NOT_PAY;
                daoQuery.minCreateTime=new Date(System.currentTimeMillis() - 1000*60*30L);
                long count =  keyOrderService.count(daoQuery);
                clist.add(Arrays.asList(new Long[]{cuid,count}));
            }
            clist.sort(new Comparator<List<Long>>() {
                @Override
                public int compare(List<Long> o1, List<Long> o2) {
                    return (int)(o1.get(1)-o2.get(1));
                }
            });
            if(clist.size()>1) {
                for (int i = 1; i < clist.size(); i++) {
                    if (clist.get(i).get(1).longValue() != clist.get(i - 1).get(1)) {
                        clist = clist.subList(0, i);
                        break;
                    }
                }
            }
            Collections.shuffle(clist);
            return clist.get(0).get(0);
        }
        return null;
    }
    @Transactional(rollbackFor = Exception.class)
    public void processFromQueue(){
        if(orderQueues.isEmpty()){
    public void processFromQueue() {
        if (orderQueues.isEmpty()) {
            return;
        }
        OrderQueue queue =  orderQueues.peek();
        if(queue!=null&&System.currentTimeMillis() > queue.expireTime){
            queue =  orderQueues.poll();
           KeyOrder order = keyOrderService.selectById(queue.getId());
           if(order==null||order.getState()!=KeyOrder.STATE_REJECT_PAY){
               return;
           }
            if(reProcessCountMap.containsKey(queue.getId())&&reProcessCountMap.get(queue.getId())>3){
        Long targetCUID = getTargetClientId();
        if (targetCUID == null) {
            return;
        }
        OrderQueue queue = orderQueues.peek();
        if (queue != null && System.currentTimeMillis() >= queue.expireTime) {
            queue = orderQueues.poll();
            KeyOrder order = keyOrderService.selectById(queue.getId());
            if (order == null || order.getState() != KeyOrder.STATE_REJECT_PAY) {
                return;
            }
            if (reProcessCountMap.containsKey(queue.getId()) && reProcessCountMap.get(queue.getId()) > 3) {
                return;
            }
           if(!reProcessCountMap.containsKey(queue.getId())){
               reProcessCountMap.put(queue.getId(), 0);
           }
            reProcessCountMap.put(queue.getId(), reProcessCountMap.get(queue.getId())+1);
            // 超时30分钟不执行
            if (System.currentTimeMillis() - order.getCreateTime().getTime() > 30 * 60 * 1000L) {
                return;
            }
            if (!reProcessCountMap.containsKey(queue.getId())) {
                reProcessCountMap.put(queue.getId(), 0);
            }
            reProcessCountMap.put(queue.getId(), reProcessCountMap.get(queue.getId()) + 1);
            keyOrderService.removeDistributedClient(queue.getId());
            // 移除已经分配的设备,改变状态为未分配
            KeyOrder update=new KeyOrder();
            KeyOrder update = new KeyOrder();
            update.setId(queue.getId());
            update.setState(KeyOrder.STATE_NOT_PROCESS);
            update.setStateDesc("重新分配");
            update.setDistributeClientUid(targetCUID);
            update.setDistributeTime(new Date());
            keyOrderService.update(update);
        }
    }
    /**
     * @return void
     * @author hxh
     * @description 处理支付失败
     * @date 21:28 2024/7/26
     * @param: id
     * @param: msg
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void processPayFail(String id,String msg){
        if(msg==null||!msg.contains("超时")){
    public void processPayFail(String id, String msg) {
        if (msg == null || !msg.contains("超时")) {
            return;
        }
        //加入重试队列
        orderQueues.add(OrderQueue.builder().id(id).expireTime(System.currentTimeMillis()+2*60*1000).build());
        KeyOrder update=new KeyOrder();
        orderQueues.add(OrderQueue.builder().id(id).expireTime(System.currentTimeMillis()).build());
        KeyOrder update = new KeyOrder();
        update.setId(id);
        update.setState(KeyOrder.STATE_REJECT_PAY);
        update.setStateDesc(msg);
        keyOrderService.update(update);
        processFromQueue();
    }
    public static void main(String[] args){
        Queue<OrderQueue> orderQueues=new PriorityQueue<>();
    public static void main(String[] args) {
        Queue<OrderQueue> orderQueues = new PriorityQueue<>();
        orderQueues.add(OrderQueue.builder().id("1").build());
        orderQueues.add(OrderQueue.builder().id("2").build());
        OrderQueue queue =  orderQueues.peek();
        queue =  orderQueues.poll();
        OrderQueue queue = orderQueues.peek();
        queue = orderQueues.poll();
        orderQueues.isEmpty();