package com.seamew.lottery.application.mq.consumer;

import com.alibaba.fastjson2.JSON;
import com.seamew.lottery.application.mq.producer.KafkaProducer;
import com.seamew.lottery.domain.activity.model.vo.ActivityPartakeRecordVO;
import com.seamew.lottery.domain.activity.service.partake.IActivityPartake;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author: seamew
 * @Title: LotteryActivityPartakeRecordListener
 * @CreateTime: 2023年03月03日 16:34:00
 * @Description:
 * @Version: 1.0
 */
@Component
@Slf4j
public class LotteryActivityPartakeRecordListener {
    @Resource
    private IActivityPartake activityPartake;

    @KafkaListener(topics = KafkaProducer.TOPIC_ACTIVITY_PARTAKE, groupId = KafkaProducer.GROUP_NAME)
    public void onMessage(ConsumerRecord<?, ?> record, Acknowledgment ack) {
        // 1. 判断消息是否存在
        if (ObjectUtils.isEmpty(record.value())) {
            return;
        }

        try {
            // 2. 转化对象
            ActivityPartakeRecordVO activityPartakeRecordVO = JSON.parseObject((String) record.value(), ActivityPartakeRecordVO.class);
            log.info("消费MQ消息，异步扣减活动库存 message：{}", activityPartakeRecordVO);

            // 3. 更新数据库库存【实际场景业务体量较大，可能也会由于MQ消费引起并发，对数据库产生压力，所以如果并发量较大，可以把库存记录缓存中，并使用定时任务进行处理缓存和数据库库存同步，减少对数据库的操作次数】
            activityPartake.updateActivityStock(activityPartakeRecordVO);
            ack.acknowledge();
        } catch (Exception e) {
            // 更新库存失败
            log.error("更新库存失败--消费MQ消息，失败 topic：{} message：{}", record.topic(), record.value());
            throw e;
        }
    }
}
