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.*;
|
|
/**
|
* @author hxh
|
* @title: OrderPayFailProcessor
|
* @description: 订单支付失败处理器
|
* @date 2024/7/26 21:27
|
*/
|
@Component
|
public class OrderPayFailProcessor {
|
|
@Data
|
@Builder
|
public static class OrderQueue implements Comparable {
|
private String id;
|
private long expireTime;
|
|
@Override
|
public int compareTo(Object o) {
|
return 0;
|
}
|
}
|
|
@Resource
|
private KeyOrderService keyOrderService;
|
|
private Map<String, Integer> reProcessCountMap = new HashMap<>();
|
|
private Queue<OrderQueue> orderQueues = new PriorityQueue<>();
|
|
@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()) {
|
return;
|
}
|
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;
|
}
|
|
// 超时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();
|
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
|
**/
|
@Transactional(rollbackFor = Exception.class)
|
public void processPayFail(String id, String msg) {
|
if (msg == null || !msg.contains("超时")) {
|
return;
|
}
|
//加入重试队列
|
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<>();
|
orderQueues.add(OrderQueue.builder().id("1").build());
|
orderQueues.add(OrderQueue.builder().id("2").build());
|
OrderQueue queue = orderQueues.peek();
|
queue = orderQueues.poll();
|
orderQueues.isEmpty();
|
|
|
}
|
|
}
|