# ChargebackBlacklistSendEventService.java

    package cloud.wconnect.finance.service.chargeback;

    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.MoudleEventSubjectEnum;
    import cloud.wconnect.commonlib.cons.OperationBlackCons;
    import cloud.wconnect.commonlib.pojo.bo.black.BlackBO;
    import cloud.wconnect.commonlib.pojo.bo.black.OperationBlackBO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.finance.entity.chargeback.CbCase;
    import cloud.wconnect.finance.entity.chargeback.CbCaseSendBlackRecord;
    import cloud.wconnect.finance.mapper.chargeback.CbCaseSendBlackRecordMapper;
    import cloud.wconnect.sns.http.processor.Sender;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;

    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * @author yyt
     * 2023/9/1
     */
    @Slf4j
    @Service
    @DS("finance")
    public class ChargebackBlacklistSendEventService {

        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private CbCaseSendBlackRecordMapper cbCaseSendBlackRecordMapper;
        @Autowired
        private ICbCaseSendBlackRecordService cbCaseSendBlackRecordService;

        private final Sender snsSender;

        public ChargebackBlacklistSendEventService(@Qualifier("moduleEventSender") Sender snsSender) {
            this.snsSender = snsSender;
        }

        /**
         * 发送黑名单事件
         *
         * @param cases case
         * @author yyt
         * @date 2023/9/1
         */
        public void sendAddBlackEvent(List<CbCase> cases) {
            if (CollectionUtils.isEmpty(cases)) {
                return;
            }

            Integer propertyId = cases.get(0).getPropertyId();
            List<Long> caseIds = cases.stream().map(CbCase::getId).toList();
            List<Long> sendBlackRecordCaseIds = cbCaseSendBlackRecordService.list(new QueryWrapper<CbCaseSendBlackRecord>()
                            .lambda().eq(CbCaseSendBlackRecord::getPropertyId, propertyId).in(CbCaseSendBlackRecord::getCaseId, caseIds))
                    .stream().map(CbCaseSendBlackRecord::getCaseId).toList();
            List<CbCase> notSentCases = cases.stream().filter(item -> !sendBlackRecordCaseIds.contains(item.getId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(notSentCases)) {
                return;
            }

            int userId = sessionContext.getLoginUserId();
            List<BlackBO> blacks = packageBlackBO(notSentCases, userId);
            sendBlack(OperationBlackCons.ADD, blacks, propertyId);

            // 插入发送黑名单记录
            long now = DateTimeUtils.nowTimestamp();
            cbCaseSendBlackRecordService.saveBatch(notSentCases.stream().map(item -> new CbCaseSendBlackRecord().setPropertyId(item.getPropertyId())
                    .setCaseId(item.getId()).setGuestFirstName(item.getGuestFirstName()).setGuestLastName(item.getGuestLastName())
                    .setCheckInDate(item.getCheckInDate()).setCheckOutDate(item.getCheckOutDate()).setFolioNumber(item.getFolioNumber())
                    .setPhone(item.getPhone()).setAddress(item.getAddress()).setMemberCardNum(item.getMemberCardNum())
                    .setEmail(item.getEmail()).setCreatedTime(now)).toList());
        }

        /**
         * 发送删除黑名单事件
         *
         * @param cs case
         * @author yyt
         * @date 2023/9/1
         */
        public void sendDeleteBlackEvent(CbCase cs) {
            if (Objects.isNull(cs)) {
                return;
            }

            int userId = sessionContext.getLoginUserId();
            List<BlackBO> blacks = packageBlackBO(Lists.newArrayList(cs), userId);
            sendBlack(OperationBlackCons.DELETE, blacks, cs.getPropertyId());

            // 删除发送黑名单记录
            cbCaseSendBlackRecordMapper.delete(new QueryWrapper<CbCaseSendBlackRecord>().lambda()
                    .eq(CbCaseSendBlackRecord::getPropertyId, cs.getPropertyId()).eq(CbCaseSendBlackRecord::getCaseId, cs.getId()));
        }

        /**
         * 封装 BlackBO
         *
         * @param cases  case
         * @param userId 操作人
         * @return BlackBO
         * @author yyt
         * @date 2024/4/23
         **/
        private List<BlackBO> packageBlackBO(List<CbCase> cases, int userId) {
            return cases.stream().map(cs -> BlackBO.builder().propertyId(cs.getPropertyId())
                    .firstName(cs.getGuestFirstName()).lastName(cs.getGuestLastName()).checkInDate(cs.getCheckInDate())
                    .checkOutDate(cs.getCheckOutDate()).folioNumber(cs.getFolioNumber())
                    .phone(cs.getPhone()).address(cs.getAddress()).memberCardNum(cs.getMemberCardNum())
                    .email(cs.getEmail()).createdBy(userId)
                    .caseNumber(cs.getCaseNumber())
                    .reason(cs.getReason())
                    .actualReason(cs.getActualReason())
                    .build()).collect(Collectors.toList());
        }

        /**
         * 发送黑名单事件
         *
         * @param operation  操作
         * @param blacks     黑名单信息
         * @param propertyId 资产ID
         * @author yyt
         * @date 2024/2/1
         **/
        private void sendBlack(int operation, List<BlackBO> blacks, Integer propertyId) {
            if (CollectionUtils.isEmpty(blacks)) {
                return;
            }

            snsSender.publish(MoudleEventSubjectEnum.SAVE_BLACK.getSubject(),
                    JsonUtils.convertObjToString(objectMapper, new OperationBlackBO(operation, propertyId, blacks)));
        }

    }