package com.fs.live.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.constant.LiveKeysConstant;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.StringUtils;
import com.fs.framework.aspectj.lock.DistributeLock;
import com.fs.erp.service.FsJstAftersalePushService;
import com.fs.his.service.IFsUserService;
import com.fs.live.domain.*;
import com.fs.live.mapper.LiveLotteryRegistrationMapper;
import com.fs.live.param.LiveReplayParam;
import com.fs.live.service.*;
import com.fs.live.vo.LiveLotteryConfVo;
import com.fs.live.vo.LiveLotteryProductListVo;
import com.fs.live.vo.LotteryVo;
import com.fs.live.websocket.bean.SendMsgVo;
import com.fs.live.websocket.service.WebSocketServer;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.fs.common.constant.LiveKeysConstant.*;
import static com.fs.common.constant.LiveKeysConstant.LIVE_COUPON_NUM;

@Component
@AllArgsConstructor
public class Task {

    private static final Logger log = LoggerFactory.getLogger(Task.class);
    private final ILiveService liveService;

    private final ILiveDataService liveDataService;

    private final RedisCache redisCache;

    @Autowired
    private ILiveWatchUserService liveWatchUserService;
    @Autowired
    private IFsUserService fsUserService;
    @Autowired
    private ILiveRewardRecordService liveRewardRecordService;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private ILiveAutoTaskService liveAutoTaskService;
    @Autowired
    private ILiveLotteryConfService liveLotteryConfService;
    @Autowired
    private ILiveUserLotteryRecordService liveUserLotteryRecordService;
    @Autowired
    private LiveLotteryRegistrationMapper liveLotteryRegistrationMapper;
    @Autowired
    private ILiveRedConfService liveRedConfService;
    @Autowired
    private ILiveCouponIssueService liveCouponIssueService;

    @Autowired
    public FsJstAftersalePushService fsJstAftersalePushService;

    @Scheduled(cron = "0 0/1 * * * ?")
    @DistributeLock(key = "updateLiveStatusByTime", scene = "task")
    public void updateLiveStatusByTime() {
        List<Live> list = liveService.selectNoEndLiveList();
        if (list.isEmpty())
            return;
        List<Long> liveIdLists = list.stream().map(Live::getLiveId).collect(Collectors.toList());
        List<LiveAutoTask> liveAutoTasks = liveAutoTaskService.selectLiveAutoTaskByLiveIds(liveIdLists);
        List<Live> liveList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now().plusSeconds(2L);
        List<Live> startLiveList = new ArrayList<>();
        List<Live> endLiveList = new ArrayList<>();
        list.forEach(live -> {
            if (live.getLiveType() != 3) {
                if (live.getFinishTime() == null) {
                    if (now.isAfter(live.getStartTime().minusSeconds(2L))){
                        if(live.getStatus() != 2){
                            redisCache.zSetRemove(LiveKeysConstant.LIVE_HOME_PAGE_LIST, JSON.toJSONString(live));
                            live.setStatus(2);
                            startLiveList.add(live);
                            liveList.add(live);
                        }
                    } else if (now.isBefore(live.getStartTime())) {
                        if (live.getStatus() != 1) {
                            live.setStatus(1);
                            liveList.add(live);
                        }

                    }
                } else {
                    if (now.isAfter(live.getStartTime().minusSeconds(2L)) && now.isBefore(live.getFinishTime())) {
                        if(live.getStatus() != 2){
                            redisCache.zSetRemove(LiveKeysConstant.LIVE_HOME_PAGE_LIST, JSON.toJSONString(live));
                            startLiveList.add(live);
                            live.setStatus(2);
                            liveList.add(live);
                        }
                        live.setStatus(2);
                    } else if (now.isBefore(live.getStartTime().minusSeconds(2L))) {
                        if (live.getStatus() != 1) {
                            live.setStatus(1);
                            liveList.add(live);
                        }
                    } else if (now.isAfter(live.getFinishTime().minusSeconds(2L))) {
                        if(live.getStatus() != 3){
                            endLiveList.add(live);
                            live.setStatus(3);
                            liveList.add(live);
                        }
                    }
                }
            } else {
                // 直播回放只需要检测结束时间就好了
                LiveReplayParam liveReplayParam = JSON.parseObject(live.getLiveConfig(), LiveReplayParam.class);
                if (liveReplayParam.getIsPlaybackOpen()) {
                    if (liveReplayParam.getFinishTime() != null) {
                        if (now.isAfter(liveReplayParam.getFinishTime().minusSeconds(2L))) {
                            if(live.getStatus() != 3){
                                endLiveList.add(live);
                                live.setStatus(3);
                                liveList.add(live);
                            }
                        }
                    }
                }
            }
        });
        if(!liveList.isEmpty()){
            for (Live live : liveList) {
                liveService.updateLiveEntity(live);
            }
        }
        String key = "live:auto_task:";
        if (!startLiveList.isEmpty()) {
            for (Live live : startLiveList) {
                SendMsgVo sendMsgVo = new SendMsgVo();
                sendMsgVo.setMsg("开始直播");
                sendMsgVo.setCmd("live_start");
                webSocketServer.broadcastMessage(live.getLiveId(), JSONObject.toJSONString(R.ok().put("data",sendMsgVo)));
                List<LiveAutoTask> collect = liveAutoTasks.stream().filter(liveAutoTask -> liveAutoTask.getLiveId().equals(live.getLiveId())).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    collect.forEach(liveAutoTask -> {
                        liveAutoTask.setCreateTime(null);
                        liveAutoTask.setUpdateTime(null);
                        redisCache.redisTemplate.opsForZSet().add(key + live.getLiveId(), JSON.toJSONString(liveAutoTask),liveAutoTask.getAbsValue().getTime());
                        redisCache.redisTemplate.expire(key+live.getLiveId(), 1, TimeUnit.DAYS);
                    });
                }
            }
            // 重新更新所有在直播的缓存
            liveService.asyncToCache();
        }
        if (!endLiveList.isEmpty()) {
            for (Live live : endLiveList) {
                SendMsgVo sendMsgVo = new SendMsgVo();
                sendMsgVo.setMsg("结束直播");
                sendMsgVo.setCmd("live_end");
                webSocketServer.broadcastMessage(live.getLiveId(), JSONObject.toJSONString(R.ok().put("data",sendMsgVo)));
                List<LiveAutoTask> collect = liveAutoTasks.stream().filter(liveAutoTask -> liveAutoTask.getLiveId().equals(live.getLiveId())).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    redisCache.redisTemplate.delete(key + live.getLiveId());
                    collect.forEach(liveAutoTask -> {
                        liveAutoTask.setCreateTime(null);
                        liveAutoTask.setUpdateTime(null);
                        redisCache.redisTemplate.opsForZSet().remove(key + live.getLiveId(), JSON.toJSONString(liveAutoTask),liveAutoTask.getAbsValue().getTime());
                    });
                }
                webSocketServer.removeLikeCountCache(live.getLiveId());
            }
            // 重新更新所有在直播的缓存
            liveService.asyncToCache();
        }

    }
    @Scheduled(cron = "0/1 * * * * ?")
    @DistributeLock(key = "liveLotteryTask", scene = "task")
    public void liveLotteryTask() {
        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳（毫秒）
        String lotteryKey = "live:lottery_task:*";
        Set<String> allLiveKeys = redisCache.redisTemplate.keys(lotteryKey);
        if (allLiveKeys != null && !allLiveKeys.isEmpty()) {
            for (String liveKey : allLiveKeys) {
                Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
                if (range == null || range.isEmpty()) {
                    continue;
                }
                processLotteryTask(range);
                redisCache.redisTemplate.opsForZSet()
                        .removeRangeByScore(liveKey, 0, currentTime);
            }
        }

        String redKey = "live:red_task:*";
        allLiveKeys = redisCache.redisTemplate.keys(redKey);
        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
            return;
        }
        for (String liveKey : allLiveKeys) {
            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
            if (range == null || range.isEmpty()) {
                continue;
            }

            updateRedStatus(range);
            redisCache.redisTemplate.opsForZSet()
                    .removeRangeByScore(liveKey, 0, currentTime);
            try {
                // 广播红包关闭消息
                SendMsgVo sendMsgVo = new SendMsgVo();
                sendMsgVo.setLiveId(Long.valueOf(liveKey));
                sendMsgVo.setCmd("red");
                sendMsgVo.setStatus(-1);
                liveService.asyncToCacheLiveConfig(Long.parseLong(liveKey));
                webSocketServer.broadcastMessage(Long.valueOf(liveKey), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
            } catch (Exception e) {
                log.error("更新红包状态异常", e);
            }
        }
    }

    private void updateRedStatus(Set<String> range) {

        liveRedConfService.finishRedStatusBySetIds(range);
    }

    private void processLotteryTask(Set<String> range) {
        List<LiveLotteryConfVo> liveLotteries = liveLotteryConfService.selectVoListByLotteryIds(range);
        if(liveLotteries.isEmpty()) return;
        Date now = new Date();
        for (LiveLotteryConfVo liveLottery : liveLotteries) {
            // 查询抽奖数量
            List<LiveLotteryProductListVo> products = liveLottery.getProducts();
            Integer totalLots = products.stream().mapToInt(liveLotteryProductListVo -> Math.toIntExact(liveLotteryProductListVo.getTotalLots())).sum();
            if(totalLots <= 0) continue;
            // 先将参与记录插入数据库
            String hashKey = String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_DRAW, liveLottery.getLiveId(), liveLottery.getLotteryId());
            Map<Object, Object> hashEntries = redisCache.hashEntries(hashKey);
            List<LiveLotteryRegistration> registrationList = new ArrayList<>();
            if (CollUtil.isNotEmpty(hashEntries)) {
                registrationList = hashEntries.values().stream()
                        .map(value -> JSONUtil.toBean(JSONUtil.parseObj(value), LiveLotteryRegistration.class))
                        .collect(Collectors.toList());
                liveLotteryRegistrationMapper.insertLiveLotteryRegistrationBatch(registrationList);
            }

            // 查询在线用户 并且参与了抽奖的用户
            List<LiveWatchUser> liveWatchUsers = liveWatchUserService.selectLiveWatchAndRegisterUser(liveLottery.getLiveId(),liveLottery.getLotteryId());
            if(liveWatchUsers.isEmpty()) continue;
            LiveLotteryRegistration liveLotteryRegistration;
            // 收集中奖信息
            List<LotteryVo> lotteryVos = new ArrayList<>();
            for (LiveLotteryProductListVo liveLotteryProductListVo : products) {
                // 随机抽奖一个用户获取奖品
                Long totalLotsPerProduct = liveLotteryProductListVo.getTotalLots();
                for (int i = 0; i < totalLotsPerProduct && !liveWatchUsers.isEmpty(); i++) {
                    // 随机选择一个用户
                    int randomIndex = new Random().nextInt(liveWatchUsers.size());
                    LiveWatchUser winningUser = liveWatchUsers.get(randomIndex);

                    // 创建中奖记录
                    LiveUserLotteryRecord record = new LiveUserLotteryRecord();
                    record.setLotteryId(liveLottery.getLotteryId());
                    record.setLiveId(liveLottery.getLiveId());
                    record.setUserId(winningUser.getUserId());
                    record.setProductId(liveLotteryProductListVo.getProductId());
                    record.setCreateTime(new Date());
                    record.setOrderStatus(-9);

                    // 保存中奖记录
                    liveUserLotteryRecordService.insertLiveUserLotteryRecord(record);
                    liveLotteryRegistration = new LiveLotteryRegistration();
                    liveLotteryRegistration.setLotteryId(liveLottery.getLotteryId());
                    liveLotteryRegistration.setLiveId(liveLottery.getLotteryId());
                    liveLotteryRegistration.setUserId(winningUser.getUserId());
                    liveLotteryRegistration.setIsWin(1L);
                    liveLotteryRegistration.setUpdateTime(now);
                    liveLotteryRegistration.setRizeLevel(liveLotteryProductListVo.getPrizeLevel());
                    liveLotteryRegistrationMapper.updateLiveLotteryRegistrationNoId(liveLotteryRegistration);
                    // 从候选列表中移除该用户，确保每人只能中奖一次
                    liveWatchUsers.remove(randomIndex);
                    LotteryVo lotteryVo = new LotteryVo();
                    lotteryVo.setUserId(winningUser.getUserId());
                    lotteryVo.setUserName(winningUser.getNickName());
                    lotteryVo.setPrizeLevel(liveLotteryProductListVo.getPrizeLevel());
                    lotteryVo.setProductName(liveLotteryProductListVo.getProductName());
                    lotteryVo.setProductId(liveLotteryProductListVo.getProductId());
                    lotteryVos.add(lotteryVo);
                }
            }
            SendMsgVo sendMsgVo = new SendMsgVo();
            sendMsgVo.setLiveId(liveLottery.getLiveId());
            sendMsgVo.setCmd("LotteryDetail");
            sendMsgVo.setData(JSON.toJSONString(lotteryVos));
            webSocketServer.broadcastMessage(liveLottery.getLiveId(), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));

            liveService.asyncToCacheLiveConfig(liveLottery.getLiveId());
            // 删除缓存 同步抽奖记录
            redisCache.deleteObject(hashKey);
        }

        List<Long> collect = liveLotteries.stream().map(LiveLotteryConfVo::getLotteryId).collect(Collectors.toList());
        liveLotteryConfService.finishStatusByLotteryIds(collect);
    }

    @Scheduled(cron = "0/1 * * * * ?")
    @DistributeLock(key = "liveAutoTask", scene = "task")
    public void liveAutoTask() {
        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳（毫秒）

        Set<String> allLiveKeys = redisCache.redisTemplate.keys("live:auto_task:*");
        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
            return; // 没有数据，直接返回
        }
        // 2. 遍历每个直播间的ZSet键
        for (String liveKey : allLiveKeys) {
            // 3. 获取当前直播间ZSet中所有元素（按score排序）
            // range方法：0表示第一个元素，-1表示最后一个元素，即获取全部
            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
            if (range == null || range.isEmpty()) {
                continue; // 没有数据，直接返回
            }
            redisCache.redisTemplate.opsForZSet()
                    .removeRangeByScore(liveKey, 0, currentTime);
            processAutoTask(range);
        }
    }

    private void processAutoTask(Set<String> range) {
        for (String liveAutoTask : range) {
            LiveAutoTask task = JSON.parseObject(liveAutoTask, LiveAutoTask.class);
            webSocketServer.handleAutoTask(task);
            task.setFinishStatus(1L);
            liveAutoTaskService.finishLiveAutoTask(task);
        }
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    @DistributeLock(key = "autoUpdateWatchReward", scene = "task")
    @Transactional
    public void autoUpdateWatchReward() {

        // 1.查询所有直播中的直播间
        List<Live> lives = liveService.liveList();


        // 2.检查是否开启观看奖励
        List<Live> openRewardLives = lives.stream().filter(live -> StringUtils.isNotEmpty(live.getConfigJson())).collect(Collectors.toList());
        Date now = new Date();

        for (Live openRewardLive : openRewardLives) {
            String configJson = openRewardLive.getConfigJson();
            LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
            if (config.getEnabled()) {
                // 3.检查当前直播间的在线用户（可以传入一个时间，然后查出来当天没领取奖励的用户）
                List<LiveWatchUser> onlineUser = liveWatchUserService.checkOnlineNoRewardUser(openRewardLive.getLiveId(), now)
                        .stream().filter(user -> (now.getTime() - user.getUpdateTime().getTime() + ( user.getOnlineSeconds() == null ? 0L : user.getOnlineSeconds())) > config.getWatchDuration() * 60 * 1000)
                        .collect(Collectors.toList());
                if(onlineUser.isEmpty()) continue;

                List<Long> userIds = onlineUser.stream().map(LiveWatchUser::getUserId).collect(Collectors.toList());
                // 4.保存用户领取记录
                saveUserRewardRecord(openRewardLive, userIds,config.getScoreAmount());
                // 5.更新用户积分（芳华币
                fsUserService.increaseIntegral(userIds,config.getScoreAmount());
                // 6.发送websocket事件消息 通知用户自动领取成功
                userIds.forEach(userId -> webSocketServer.sendIntegralMessage(openRewardLive.getLiveId(),userId,config.getScoreAmount()));

            }
        }
    }
    private void saveUserRewardRecord(Live live, List<Long> userIds,Long scoreAmount) {
        for (Long userId : userIds) {
            LiveRewardRecord record = new LiveRewardRecord();
            record.setLiveId(live.getLiveId());
            record.setUserId(userId);
            record.setIncomeType(1L);
            record.setSourceType(3L);
            record.setSourceId(live.getCompanyId() == null ? 0L : live.getCompanyId());
            record.setRewardType(2L);
            record.setNum(BigDecimal.valueOf(scoreAmount));
            record.setRewardType(2L);
            record.setCreateTime(new Date());
            record.setCreateBy(String.valueOf(userId));
            liveRewardRecordService.insertLiveRewardRecord(record);
        }
    }
    /**
     * 从Redis获取对象并转换为Long类型
     * @param redisCache Redis缓存操作对象
     * @param key 缓存键
     * @return 转换后的Long值（若为null或转换失败则返回0L）
     */
    public static Long getAsLong(RedisCache redisCache, String key) {
        // 从Redis获取原始对象
        Object value = redisCache.getCacheObject(key);
        if (value == null) {
            return 0L; // 若缓存不存在，返回默认值0
        }

        // 根据实际类型转换为Long
        if (value instanceof Long) {
            return (Long) value;
        } else if (value instanceof Integer) {
            return ((Integer) value).longValue();
        } else if (value instanceof String) {
            // 处理字符串类型（可能是数字字符串，如"123"）
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                // 若字符串无法转为数字，返回0（或根据业务抛异常）
                return 0L;
            }
        } else {
            // 其他类型（如Double等），根据业务需求处理，这里默认返回0
            return 0L;
        }
    }

    @PostConstruct
    public void initLiveDatasOnStartup() {
        log.info("项目启动，开始初始化直播点赞数据...");
        try {
            List<LiveData> liveDatas = liveDataService.getAllLiveDatas();
            if (CollectionUtils.isNotEmpty(liveDatas)) {
                for (LiveData liveData : liveDatas) {
                    redisCache.deleteObject("live:like:" + liveData.getLiveId());
                    redisCache.setCacheObject("live:like:" + liveData.getLiveId(), liveData.getLikes().intValue());
                }
            }
        } catch (Exception e) {
            log.error("项目启动时加载直播数据失败", e);
        }
    }



    /**
     *定期将缓存的数据写入数据库
     */
    @Scheduled(cron = "0 0/1 * * * ?")// 每分钟执行一次
    public void syncLiveDataToDB() {
        List<LiveData> liveDatas = liveDataService.getAllLiveDatas(); // 获取所有正在直播的直播间数据
        if(liveDatas == null)
            return;
        liveDatas.forEach(liveData ->{

            Long resultLikeCount = getAsLong(redisCache, "live:like:" + liveData.getLiveId());
            resultLikeCount = resultLikeCount > 0L ? resultLikeCount : liveData.getLikes();
            redisCache.setCacheObject("live:like:" + liveData.getLiveId(), resultLikeCount.intValue());
            liveData.setLikes(
                    resultLikeCount
            );

       /* for (Long liveId : liveIds) {
            LiveData liveData = liveDataService.selectLiveDataByLiveId(liveId);
            if (liveData == null) {
                continue; // 防止空指针异常
            }*/


            // 从 redis 获取数据，并提供默认值，避免 NPE
            liveData.setPageViews(
                    Math.max( liveData.getPageViews(), Optional.ofNullable(redisCache.incr(PAGE_VIEWS_KEY + liveData.getLiveId(),0)).orElse(0L))
            );
            liveData.setTotalViews(
                    Math.max( liveData.getTotalViews(), Optional.ofNullable(redisCache.incr(TOTAL_VIEWS_KEY + liveData.getLiveId(),0)).orElse(0L))
            );
            liveData.setUniqueVisitors(
                    /*Optional.ofNullable(redisCache.getCacheSet(UNIQUE_VISITORS_KEY + liveId))
                            .map(Set::size)  // 获取集合大小
                            .map(Long::valueOf)  // 转换为 Long 类型
                            .orElse(0L)*/
                    Math.max( liveData.getUniqueVisitors(), Optional.ofNullable(redisCache.incr(UNIQUE_VISITORS_KEY + liveData.getLiveId(),0)).orElse(0L))
            );
            liveData.setUniqueViewers(
                    /*Optional.ofNullable(redisCache.getCacheSet(UNIQUE_VIEWERS_KEY + liveId))
                            .map(Set::size)  // 获取集合大小
                            .map(Long::valueOf)  // 转换为 Long 类型
                            .orElse(0L)*/
                    Math.max( liveData.getUniqueViewers(), Optional.ofNullable(redisCache.incr(UNIQUE_VIEWERS_KEY + liveData.getLiveId(),0)).orElse(0L))
            );
            // 使用Set大小来获取最大同时在线人数
            String onlineUsersSetKey = ONLINE_USERS_SET_KEY + liveData.getLiveId();
            Long currentSetSize = redisCache.redisTemplate.opsForSet().size(onlineUsersSetKey);
            Long maxOnlineFromRedis = Optional.ofNullable(redisCache.getCacheObject(MAX_ONLINE_USERS_KEY + liveData.getLiveId()))
                    .map(obj -> {
                        if (obj instanceof Number) {
                            return ((Number) obj).longValue();
                        }
                        try {
                            return Long.parseLong(obj.toString());
                        } catch (NumberFormatException e) {
                            return 0L;
                        }
                    })
                    .orElse(0L);
            // 取Set大小和Redis中记录的最大在线人数的较大值
            Long maxOnlineCount = Math.max(
                    currentSetSize != null ? currentSetSize : 0L,
                    maxOnlineFromRedis
            );
            liveData.setPeakConcurrentViewers(
                    Math.max(liveData.getPeakConcurrentViewers(), maxOnlineCount)
            );
        });
        if(!liveDatas.isEmpty())
            for (LiveData liveData : liveDatas) {
                liveDataService.updateLiveData(liveData);
            }
            /*// 更新数据库
            liveDataService.updateLiveData(liveData);*/
        Set<String> keys = redisCache.redisTemplate.keys(String.format(LIVE_COUPON_NUM, "*"));
        if (keys != null && !keys.isEmpty()) {
            for (String key : keys) {
                Object o = redisCache.redisTemplate.opsForValue().get(String.format(LIVE_COUPON_NUM, key));
                if (o != null) {
                    LiveCouponIssue updateEntity = new LiveCouponIssue();
                    updateEntity.setId(Long.valueOf(key));
                    updateEntity.setRemainCount(Long.parseLong(o.toString()));
                    liveCouponIssueService.updateLiveCouponIssue(updateEntity);
                }
            }
        }
    }

    /**
     * 更新红包领取数量
     */
    @Scheduled(cron = "0/5 * * * * ?")
    @DistributeLock(key = "updateRedQuantityNum", scene = "task")
    public void updateRedQuantityNum() {
        liveRedConfService.updateRedQuantityNum();
    }
}
