2025-10-14 17:15:09 +08:00
|
|
|
package com.xscm.moduleutil.utils;
|
|
|
|
|
|
|
|
|
|
import android.os.Handler;
|
|
|
|
|
import android.os.Looper;
|
2025-10-15 18:57:40 +08:00
|
|
|
import com.blankj.utilcode.util.LogUtils;
|
2025-10-14 17:15:09 +08:00
|
|
|
import com.xscm.moduleutil.bean.RedPacketInfo;
|
2025-10-15 18:57:40 +08:00
|
|
|
import lombok.Getter;
|
|
|
|
|
import lombok.Setter;
|
2025-10-14 17:15:09 +08:00
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
2025-10-15 18:57:40 +08:00
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
2025-10-14 17:15:09 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 红包管理器单例类
|
|
|
|
|
*/
|
|
|
|
|
public class QXRedPacketManager {
|
|
|
|
|
private static QXRedPacketManager instance;
|
|
|
|
|
private final Map<String, RedPacketInfo> redPackets;
|
|
|
|
|
private Handler checkTimerHandler;
|
|
|
|
|
private Runnable checkTimerRunnable;
|
|
|
|
|
|
|
|
|
|
// 私有构造函数,防止外部实例化
|
|
|
|
|
private QXRedPacketManager() {
|
2025-10-15 18:57:40 +08:00
|
|
|
this.redPackets = new ConcurrentHashMap<>();
|
2025-10-14 17:15:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取单例实例
|
|
|
|
|
*
|
|
|
|
|
* @return QXRedPacketManager 单例
|
|
|
|
|
*/
|
|
|
|
|
public static QXRedPacketManager getInstance() {
|
|
|
|
|
if (instance == null) {
|
|
|
|
|
synchronized (QXRedPacketManager.class) {
|
|
|
|
|
if (instance == null) {
|
|
|
|
|
instance = new QXRedPacketManager();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加红包列表
|
|
|
|
|
*
|
|
|
|
|
* @param redPackets 红包模型列表
|
|
|
|
|
*/
|
|
|
|
|
public void addRedPackets(List<RedPacketInfo> redPackets) {
|
|
|
|
|
if (redPackets == null || redPackets.isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (RedPacketInfo model : redPackets) {
|
|
|
|
|
this.redPackets.put(model.getRedpacket_id(), model);
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-15 18:57:40 +08:00
|
|
|
// 在添加数据后启动定时器(如果尚未启动)
|
|
|
|
|
startCheckTimer();
|
2025-10-14 17:15:09 +08:00
|
|
|
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
|
|
|
|
((QXRedPacketManagerDelegate) this.delegate).onRedPacketsAdded(redPackets, this.redPackets.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加单个红包
|
|
|
|
|
*
|
|
|
|
|
* @param redPacket 红包模型
|
|
|
|
|
*/
|
|
|
|
|
public void addRedPacket(RedPacketInfo redPacket) {
|
|
|
|
|
if (redPacket == null || redPacket.getRedpacket_id() == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.redPackets.put(redPacket.getRedpacket_id(), redPacket);
|
|
|
|
|
|
2025-10-15 18:57:40 +08:00
|
|
|
// 在添加数据后启动定时器(如果尚未启动)
|
|
|
|
|
startCheckTimer();
|
2025-10-14 17:15:09 +08:00
|
|
|
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
|
|
|
|
((QXRedPacketManagerDelegate) this.delegate).onRedPacketAdded(redPacket, this.redPackets.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 移除红包
|
|
|
|
|
*
|
|
|
|
|
* @param packetId 红包ID
|
|
|
|
|
*/
|
|
|
|
|
public void removeRedPacket(String packetId) {
|
|
|
|
|
this.redPackets.remove(packetId);
|
|
|
|
|
|
|
|
|
|
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
|
|
|
|
((QXRedPacketManagerDelegate) this.delegate).onRedPacketRemoved(packetId, this.redPackets.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取所有红包
|
|
|
|
|
*
|
|
|
|
|
* @return 红包列表
|
|
|
|
|
*/
|
|
|
|
|
public List<RedPacketInfo> getAllRedPackets() {
|
|
|
|
|
return new ArrayList<>(this.redPackets.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据ID获取红包
|
|
|
|
|
*
|
|
|
|
|
* @param packetId 红包ID
|
|
|
|
|
* @return 红包模型
|
|
|
|
|
*/
|
|
|
|
|
public RedPacketInfo getRedPacket(String packetId) {
|
|
|
|
|
return this.redPackets.get(packetId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 开始检查定时器
|
|
|
|
|
*/
|
|
|
|
|
public void startCheckTimer() {
|
2025-10-15 18:57:40 +08:00
|
|
|
// 如果定时器已经在运行,直接返回
|
|
|
|
|
if (checkTimerRunnable != null && checkTimerHandler != null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-10-14 17:15:09 +08:00
|
|
|
if (checkTimerRunnable == null) {
|
|
|
|
|
checkTimerRunnable = new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
checkAndUpdateRedPackets();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
checkTimerHandler = new Handler(Looper.getMainLooper());
|
|
|
|
|
checkTimerHandler.post(checkTimerRunnable);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 检查并更新红包状态
|
|
|
|
|
*/
|
|
|
|
|
private void checkAndUpdateRedPackets() {
|
2025-10-15 18:57:40 +08:00
|
|
|
// 添加空值检查
|
|
|
|
|
if (this.redPackets == null || this.redPackets.isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-10-14 17:15:09 +08:00
|
|
|
List<RedPacketInfo> packets = new ArrayList<>(this.redPackets.values());
|
|
|
|
|
|
|
|
|
|
for (RedPacketInfo packet : packets) {
|
2025-10-15 18:57:40 +08:00
|
|
|
long packetTime = packet.remainingTime();
|
|
|
|
|
LogUtils.e("红包剩余时间:" + packet.getRedpacket_time());
|
|
|
|
|
long redpacketTime = 0;
|
|
|
|
|
try {
|
|
|
|
|
if (packet.getRedpacket_time() != null) {
|
|
|
|
|
redpacketTime = Long.parseLong(packet.getRedpacket_time());
|
|
|
|
|
}
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
LogUtils.e("红包时间格式错误: " + packet.getRedpacket_time());
|
|
|
|
|
}
|
|
|
|
|
if (packetTime <= -redpacketTime) {
|
|
|
|
|
|
|
|
|
|
removeRedPacket(packet.getRedpacket_id());
|
|
|
|
|
}
|
|
|
|
|
if (packet.getCountdown()==0){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
|
|
|
|
((QXRedPacketManagerDelegate) this.delegate).didUpdateRedPacketTime(packet, packetTime);
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-14 17:15:09 +08:00
|
|
|
boolean wasAvailable = packet.isAvailable();
|
|
|
|
|
packet.setAvailable(packet.canOpenNow());
|
|
|
|
|
|
|
|
|
|
// 状态发生变化时通知
|
|
|
|
|
if (wasAvailable != packet.isAvailable()) {
|
|
|
|
|
if (this.delegate != null && this.delegate instanceof QXRedPacketManagerDelegate) {
|
|
|
|
|
((QXRedPacketManagerDelegate) this.delegate).onRedPacketUpdated(packet, this.redPackets.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 继续执行定时任务
|
|
|
|
|
checkTimerHandler.postDelayed(checkTimerRunnable, 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 移除所有红包
|
|
|
|
|
*/
|
|
|
|
|
public void removeAllRedPackets() {
|
|
|
|
|
this.redPackets.clear();
|
2025-10-15 18:57:40 +08:00
|
|
|
endCheckTimer();
|
2025-10-14 17:15:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 结束检查定时器
|
|
|
|
|
*/
|
|
|
|
|
public void endCheckTimer() {
|
|
|
|
|
if (checkTimerHandler != null) {
|
|
|
|
|
checkTimerHandler.removeCallbacks(checkTimerRunnable);
|
|
|
|
|
checkTimerHandler = null;
|
|
|
|
|
checkTimerRunnable = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 销毁红包信息
|
|
|
|
|
*/
|
|
|
|
|
public void destroyRedpacketInfo() {
|
|
|
|
|
removeAllRedPackets();
|
|
|
|
|
endCheckTimer();
|
|
|
|
|
this.delegate = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 委托接口
|
|
|
|
|
*/
|
|
|
|
|
public interface QXRedPacketManagerDelegate {
|
|
|
|
|
/**
|
|
|
|
|
* 添加红包列表回调
|
|
|
|
|
*
|
|
|
|
|
* @param redPackets 红包列表
|
|
|
|
|
* @param remainingCount 剩余数量
|
|
|
|
|
*/
|
|
|
|
|
void onRedPacketsAdded(List<RedPacketInfo> redPackets, int remainingCount);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加单个红包回调
|
|
|
|
|
*
|
|
|
|
|
@param redPacket 红包模型
|
|
|
|
|
* @param remainingCount 剩余数量
|
|
|
|
|
*/
|
|
|
|
|
void onRedPacketAdded(RedPacketInfo redPacket, int remainingCount);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 移除红包回调
|
|
|
|
|
*
|
|
|
|
|
* @param packetId 红包ID
|
|
|
|
|
* @param remainingCount 剩余数量
|
|
|
|
|
*/
|
|
|
|
|
void onRedPacketRemoved(String packetId, int remainingCount);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 更新红包状态回调
|
|
|
|
|
*
|
|
|
|
|
* @param packet 红包模型
|
|
|
|
|
* @param remainingCount 剩余数量
|
|
|
|
|
*/
|
|
|
|
|
void onRedPacketUpdated(RedPacketInfo packet, int remainingCount);
|
2025-10-15 18:57:40 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 更新红包时间回调
|
|
|
|
|
*
|
|
|
|
|
* @param packet 红包模型
|
|
|
|
|
* @param packetTime 红包剩余时间
|
|
|
|
|
*/
|
|
|
|
|
void didUpdateRedPacketTime(RedPacketInfo packet, long packetTime);
|
2025-10-14 17:15:09 +08:00
|
|
|
}
|
|
|
|
|
|
2025-10-15 18:57:40 +08:00
|
|
|
/**
|
|
|
|
|
* -- SETTER --
|
|
|
|
|
* 设置委托对象
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* -- GETTER --
|
|
|
|
|
* 获取委托对象
|
|
|
|
|
*
|
|
|
|
|
@param delegate 委托对象
|
|
|
|
|
* @return 委托对象
|
|
|
|
|
*/
|
|
|
|
|
@Getter
|
|
|
|
|
@Setter
|
2025-10-14 17:15:09 +08:00
|
|
|
private QXRedPacketManagerDelegate delegate;
|
|
|
|
|
}
|
|
|
|
|
|