package com.xinelu.quartz.service.impl;

import com.alibaba.fastjson2.JSON;
import com.xinelu.applet.service.goodstock.GoodsStockService;
import com.xinelu.applet.service.wechatpaymentinfo.WeChatPaymentService;
import com.xinelu.applet.vo.wechatpaymentinfo.vo.OrderStatusInfoVO;
import com.xinelu.applet.vo.wechatpaymentinfo.vo.WeChatQueryOrderVO;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.enums.*;
import com.xinelu.manage.domain.appointmentorder.AppointmentOrder;
import com.xinelu.manage.domain.goodsOrder.GoodsOrder;
import com.xinelu.manage.domain.paymentinfo.PaymentInfo;
import com.xinelu.manage.domain.trainingorder.TrainingOrder;
import com.xinelu.manage.mapper.appointmentorder.AppointmentOrderMapper;
import com.xinelu.manage.mapper.goodsOrder.GoodsOrderMapper;
import com.xinelu.manage.mapper.patientcouponreceive.PatientCouponReceiveMapper;
import com.xinelu.manage.mapper.paymentinfo.PaymentInfoMapper;
import com.xinelu.manage.mapper.trainingorder.TrainingOrderMapper;
import com.xinelu.manage.vo.AppointOrderAndDetailsInfo;
import com.xinelu.manage.vo.goods.GoodsOrderAndDetailsInfo;
import com.xinelu.quartz.service.PaymentInfoTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.sql.rowset.serial.SerialException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description 支付定时任务实现类
 * @Author 纪寒
 * @Date 2022-10-21 15:03:41
 * @Version 1.0
 */
@Slf4j
@Service
public class PaymentInfoTaskServiceImpl implements PaymentInfoTaskService {
    @Resource
    private AppointmentOrderMapper appointmentOrderMapper;
    @Resource
    private GoodsOrderMapper goodsOrderMapper;
    @Resource
    private WeChatPaymentService weChatPaymentService;
    @Resource
    private PaymentInfoMapper paymentInfoMapper;
    @Resource(name = "transactionManager")
    private DataSourceTransactionManager transactionManager;
    @Resource
    private GoodsStockService goodsStockService;
    @Resource
    private RedisTemplate<String, Objects> redisTemplate;
    @Resource
    private PatientCouponReceiveMapper patientCouponReceiveMapper;
    @Resource
    private TrainingOrderMapper trainingOrderMapper;

    /**
     * 成功状态码
     */
    private static final int SUCCESS_CODE = 200;

    /**
     * 成功状态码
     */
    private static final int SUCCESS_CODE_TWO = 204;

    /**
     * 自动关闭商品订单2小时与预约订单2小时未支付的订单信息，每10分钟执行一次
     *
     * @throws Exception 异常信息
     */
    @Override
    public void automaticOrderTask() throws Exception {
        LocalDateTime localDateTime = LocalDateTime.now().minusHours(2);
        List<AppointOrderAndDetailsInfo> appointmentOrderList = appointmentOrderMapper.getWaitPayAppointmentOrderList(localDateTime);
        List<GoodsOrderAndDetailsInfo> goodsOrderList = goodsOrderMapper.getWaitPayGoodsOrderList(localDateTime);
        List<TrainingOrder> waitPayTrainingOrderList = trainingOrderMapper.getWaitPayTrainingOrderListByTime(localDateTime, TrainingOrderStatusEnum.WAIT_PAY.getInfo());
        if (CollectionUtils.isEmpty(appointmentOrderList) && CollectionUtils.isEmpty(goodsOrderList) && CollectionUtils.isEmpty(waitPayTrainingOrderList)) {
            return;
        }
        TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
        List<AppointOrderAndDetailsInfo> successAppointOrderList = Lists.newArrayList();
        try {
            if (CollectionUtils.isNotEmpty(appointmentOrderList)) {
                successAppointOrderList = processAppointmentOrderInfo(appointmentOrderList);
            }
            if (CollectionUtils.isNotEmpty(goodsOrderList)) {
                processGoodsOrderInfo(goodsOrderList);
            }
            if (CollectionUtils.isNotEmpty(waitPayTrainingOrderList)) {
                handleWaitPayTrainingOrderInfo(waitPayTrainingOrderList);
            }
            transactionManager.commit(transactionStatus);
        } catch (Exception e) {
            transactionManager.rollback(transactionStatus);
            log.error("自动关闭订单失败，失败原因为 =====> {}", e.getMessage());
            if (CollectionUtils.isNotEmpty(successAppointOrderList)) {
                for (AppointOrderAndDetailsInfo orderAndDetailsInfo : successAppointOrderList) {
                    String appointLimitCountKey = Constants.PRE_APPOINTMENT_LIMIT_COUNT_KEY + orderAndDetailsInfo.getNurseStationItemId() + "_" + orderAndDetailsInfo.getServiceDate() + "_" + orderAndDetailsInfo.getServiceStartTime();
                    RedisAtomicLong redisAtomicLong = new RedisAtomicLong(appointLimitCountKey, Objects.requireNonNull(redisTemplate.getConnectionFactory()));
                    if (redisAtomicLong.get() > 0) {
                        redisAtomicLong.decrementAndGet();
                    }
                }
            }
            throw e;
        }
    }

    /**
     * 自动修改未支付的订单状态，每15分钟执行一次
     *
     * @throws Exception 异常信息
     */
    @Override
    public void automaticUpdateOrderStatusTask() throws Exception {
        List<AppointmentOrder> appointmentOrderList = appointmentOrderMapper.getWaitPayStatusAppointmentOrderList(OrderStatusEnum.WAIT_PAY.getInfo());
        List<GoodsOrder> goodsOrderList = goodsOrderMapper.getWaitPayStatusGoodsOrderList(GooodsOrderStatusEnum.WAIT_PAY.getInfo());
        List<TrainingOrder> waitPayTrainingOrderList = trainingOrderMapper.getWaitPayTrainingOrderList(TrainingOrderStatusEnum.WAIT_PAY.getInfo(), null);
        if (CollectionUtils.isEmpty(appointmentOrderList) && CollectionUtils.isEmpty(goodsOrderList) && CollectionUtils.isEmpty(waitPayTrainingOrderList)) {
            return;
        }
        TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            if (CollectionUtils.isNotEmpty(appointmentOrderList)) {
                updateAppointmentPaymentInfo(appointmentOrderList);
            }
            if (CollectionUtils.isNotEmpty(goodsOrderList)) {
                updateGoodsPaymentInfo(goodsOrderList);
            }
            if (CollectionUtils.isNotEmpty(waitPayTrainingOrderList)) {
                handleWaitPayTrainingOrder(waitPayTrainingOrderList);
            }
            transactionManager.commit(transactionStatus);
        } catch (Exception e) {
            log.error("修改订单状态定时任务失败，失败原因为 =====> {}", e.getMessage());
            transactionManager.rollback(transactionStatus);
            throw e;
        }
    }

    /**
     * 处理预约订单状态
     *
     * @param appointmentOrderList 预约订单列表
     * @return List<AppointOrderAndDetailsInfo> 处理成功的预约订单信息
     * @throws Exception 异常信息
     */
    private List<AppointOrderAndDetailsInfo> processAppointmentOrderInfo(List<AppointOrderAndDetailsInfo> appointmentOrderList) throws Exception {
        List<AppointOrderAndDetailsInfo> successList = Lists.newArrayList();
        List<String> closedOrderList = Lists.newArrayList();
        for (AppointOrderAndDetailsInfo orderAndDetailsInfo : appointmentOrderList) {
            if (StringUtils.isBlank(orderAndDetailsInfo.getOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryAppointmentOrderStatus(orderAndDetailsInfo.getOrderNo(), vo);
            if (BooleanUtils.isFalse(statusInfoVO.getPayFlag())) {
                closedOrderList.add(orderAndDetailsInfo.getOrderNo());
                continue;
            }
            int statusCode = weChatPaymentService.closeWeChatOrderInfo(orderAndDetailsInfo.getOrderNo(), BuySourceEnum.NURSE_STATION.getInfo());
            if (statusCode == SUCCESS_CODE || statusCode == SUCCESS_CODE_TWO) {
                updateAppointmentOrderStatus(orderAndDetailsInfo, successList);
            }
        }
        if (CollectionUtils.isNotEmpty(closedOrderList)) {
            List<AppointOrderAndDetailsInfo> waitPayAppointList = appointmentOrderMapper.getWaitPayAppointList(closedOrderList);
            if (CollectionUtils.isNotEmpty(waitPayAppointList)) {
                for (AppointOrderAndDetailsInfo orderAndDetailsInfo : waitPayAppointList) {
                    updateAppointmentOrderStatus(orderAndDetailsInfo, successList);
                }
            }
        }
        return successList;
    }

    /**
     * 处理商品订单信息
     *
     * @param goodsOrderList 商品订单列表
     * @throws Exception 异常信息
     */
    private void processGoodsOrderInfo(List<GoodsOrderAndDetailsInfo> goodsOrderList) throws Exception {
        List<String> orderList = Lists.newArrayList();
        List<String> closedOrderList = Lists.newArrayList();
        for (GoodsOrderAndDetailsInfo goodOrder : goodsOrderList) {
            if (StringUtils.isBlank(goodOrder.getOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryGoodsOrderStatus(goodOrder.getOrderNo(), vo, goodOrder.getBuySource());
            if (BooleanUtils.isFalse(statusInfoVO.getPayFlag())) {
                closedOrderList.add(goodOrder.getOrderNo());
                continue;
            }
            int statusCode = weChatPaymentService.closeWeChatOrderInfo(goodOrder.getOrderNo(), goodOrder.getBuySource());
            if (statusCode == SUCCESS_CODE || statusCode == SUCCESS_CODE_TWO) {
                orderList.add(goodOrder.getOrderNo());
            }
            if (StringUtils.isNotBlank(goodOrder.getOrderType()) && !OrderTypeEnum.HEALTH_CONSULTATION.getInfo().equals(goodOrder.getOrderType())) {
                goodsStockService.addGoodsStockInfo(goodOrder.getOrderNo(), goodOrder.getGoodsAttributeDetailsId(), Objects.isNull(goodOrder.getGoodsCount()) ? 0 : goodOrder.getGoodsCount());
                if (Objects.nonNull(goodOrder.getCouponId()) && Objects.nonNull(goodOrder.getPatientId())) {
                    patientCouponReceiveMapper.updatePatientCouponUseStatus(goodOrder.getPatientId(), goodOrder.getCouponId(), CouponUseStatusEnum.NOT_USED.getInfo());
                }
            }
        }
        if (CollectionUtils.isNotEmpty(orderList)) {
            log.info("自动修改商品订单信息状态 ======> [{}]", orderList);
            goodsOrderMapper.updateBatchGoodsOrderStatus(orderList, GooodsOrderStatusEnum.CANCEL.getInfo());
        }
        if (CollectionUtils.isNotEmpty(closedOrderList)) {
            //说明当前订单在微信系统中已经关闭，需要重新确认本地订单状态是否同步更新，未更新则需要同步更新并且新增库存数量
            List<GoodsOrderAndDetailsInfo> goodsOrderInfoList = goodsOrderMapper.getWaitPayGoodsOrderCountList(closedOrderList);
            if (CollectionUtils.isNotEmpty(goodsOrderInfoList)) {
                //新增库存数量和修改优惠券状态，健康咨询类型的订单无需新增库存数量和退还优惠券
                for (GoodsOrderAndDetailsInfo detailsInfo : goodsOrderInfoList) {
                    if (StringUtils.isNotBlank(detailsInfo.getOrderType()) && OrderTypeEnum.HEALTH_CONSULTATION.getInfo().equals(detailsInfo.getOrderType())) {
                        continue;
                    }
                    goodsStockService.addGoodsStockInfo(detailsInfo.getOrderNo(), detailsInfo.getGoodsAttributeDetailsId(), Objects.isNull(detailsInfo.getGoodsCount()) ? 0 : detailsInfo.getGoodsCount());
                    if (Objects.nonNull(detailsInfo.getCouponId()) && Objects.nonNull(detailsInfo.getPatientId())) {
                        patientCouponReceiveMapper.updatePatientCouponUseStatus(detailsInfo.getPatientId(), detailsInfo.getCouponId(), CouponUseStatusEnum.NOT_USED.getInfo());
                    }
                }
                //批量更新本地订单状态，将订单状态修改为已取消
                List<String> orderNos = goodsOrderInfoList.stream().filter(item -> StringUtils.isNotBlank(item.getOrderNo())).map(GoodsOrderAndDetailsInfo::getOrderNo).distinct().collect(Collectors.toList());
                goodsOrderMapper.updateBatchGoodsOrderStatus(orderNos, GooodsOrderStatusEnum.CANCEL.getInfo());
            }
        }
    }

    /**
     * 新增预约订单支付信息
     *
     * @param appointmentOrderList 预约订单列表
     * @throws Exception 异常信息
     */
    private void updateAppointmentPaymentInfo(List<AppointmentOrder> appointmentOrderList) throws Exception {
        for (AppointmentOrder appointmentOrder : appointmentOrderList) {
            if (StringUtils.isBlank(appointmentOrder.getOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryAppointmentOrderStatus(appointmentOrder.getOrderNo(), vo);
            if (StringUtils.isNotBlank(statusInfoVO.getTradeStatus())
                    && WeChatTradeStateEnum.SUCCESS.getInfo().equals(statusInfoVO.getTradeStatus())) {
                insertAppointmentOrderPaymentInfo(appointmentOrder, statusInfoVO);
            }
        }
    }

    /**
     * 新增商品订单支付信息
     *
     * @param goodsOrderList 商品订单列表
     * @throws Exception 异常信息
     */
    private void updateGoodsPaymentInfo(List<GoodsOrder> goodsOrderList) throws Exception {
        for (GoodsOrder goodsOrder : goodsOrderList) {
            if (Objects.isNull(goodsOrder) || StringUtils.isBlank(goodsOrder.getOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryGoodsOrderStatus(goodsOrder.getOrderNo(), vo, goodsOrder.getBuySource());
            if (StringUtils.isNotBlank(statusInfoVO.getTradeStatus())
                    && WeChatTradeStateEnum.SUCCESS.getInfo().equals(statusInfoVO.getTradeStatus())) {
                insertGoodsOrderPaymentInfo(goodsOrder, null, statusInfoVO);
            }
        }
    }

    /**
     * 处理支付回调失败导致未及时更新学习培训订单状态的信息集合
     *
     * @param waitPayTrainingOrderList 未支付的学习培训订单集合
     * @throws Exception 异常信息
     */
    private void handleWaitPayTrainingOrder(List<TrainingOrder> waitPayTrainingOrderList) throws Exception {
        for (TrainingOrder trainingOrder : waitPayTrainingOrderList) {
            if (Objects.isNull(trainingOrder) || StringUtils.isBlank(trainingOrder.getTrainingOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            //学习培训订单状态查询接口和记录支付日志信息使用商品订单的方法，在方法中做逻辑处理
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryGoodsOrderStatus(trainingOrder.getTrainingOrderNo(), vo, BuySourceEnum.TRAINING.getInfo());
            if (StringUtils.isNotBlank(statusInfoVO.getTradeStatus())
                    && WeChatTradeStateEnum.SUCCESS.getInfo().equals(statusInfoVO.getTradeStatus())) {
                //修改订单状态和记录支付日志信息
                insertGoodsOrderPaymentInfo(null, trainingOrder, statusInfoVO);
            }
        }
    }

    /**
     * 修改预约订单状态和记录预约订单信息
     *
     * @param appointmentOrder 预约订单信息
     * @param vo               微信查单信息
     * @throws Exception 异常信息
     */
    private void insertAppointmentOrderPaymentInfo(AppointmentOrder appointmentOrder, OrderStatusInfoVO vo) throws Exception {
        appointmentOrderMapper.updateAppointmentOrderStatus(OrderStatusEnum.WAIT_DISPATCH.getInfo(), appointmentOrder.getOrderNo());
        int paymentInfoCount = paymentInfoMapper.getPaymentInfoByOrderNo(appointmentOrder.getOrderNo());
        if (paymentInfoCount <= 0) {
            WeChatQueryOrderVO weChatQueryOrderVO = vo.getWeChatQueryOrderVO();
            PaymentInfo paymentInfo = buildPaymentInfo(weChatQueryOrderVO, null, appointmentOrder, null);
            int insertCount = paymentInfoMapper.insertPaymentInfo(paymentInfo);
            if (insertCount <= 0) {
                log.error("记录预约订单支付日志出错，参数为 ====> [{}]", paymentInfo);
                throw new SerialException("记录预约订单支付日志出错，请联系管理员！");
            }
        }
    }

    /**
     * 修改商品订单状态和记录商品订单支付日志信息及学习培训订单
     *
     * @param goodsOrder 商品订单信息
     * @param vo         微信查单信息
     * @throws Exception 异常信息
     */
    private void insertGoodsOrderPaymentInfo(GoodsOrder goodsOrder, TrainingOrder trainingOrder, OrderStatusInfoVO vo) throws Exception {
        int paymentInfoCount = 0;
        if (Objects.nonNull(goodsOrder)) {
            goodsOrderMapper.updateGoodsOrderStatus(GooodsOrderStatusEnum.WAIT_RECEIVED_GOODS.getInfo(), goodsOrder.getOrderNo());
            paymentInfoCount = paymentInfoMapper.getPaymentInfoByOrderNo(goodsOrder.getOrderNo());
        }

        //修改学习培训订单状态和记录支付日志信息
        if (Objects.nonNull(trainingOrder)) {
            trainingOrderMapper.updateTrainingOrderStatus(TrainingOrderStatusEnum.PAY.getInfo(), trainingOrder.getTrainingOrderNo());
            paymentInfoCount = paymentInfoMapper.getPaymentInfoByOrderNo(trainingOrder.getTrainingOrderNo());
        }
        if (paymentInfoCount <= 0) {
            WeChatQueryOrderVO weChatQueryOrderVO = vo.getWeChatQueryOrderVO();
            PaymentInfo paymentInfo = buildPaymentInfo(weChatQueryOrderVO, goodsOrder, null, trainingOrder);
            int insertCount = paymentInfoMapper.insertPaymentInfo(paymentInfo);
            if (insertCount <= 0) {
                log.error("记录商品或者学习培训支付订单支付日志出错，参数为 ====> [{}]", paymentInfo);
                throw new SerialException("记录商品或者学习培训支付订单支付日志出错，请联系管理员！");
            }
        }
    }

    /**
     * 构建支付信息参数
     *
     * @param weChatQueryOrderVO   微信查单返回结果信息
     * @param goodsOrderInfo       商品订单信息
     * @param appointmentOrderInfo 预约订单信息
     */
    public PaymentInfo buildPaymentInfo(WeChatQueryOrderVO weChatQueryOrderVO, GoodsOrder goodsOrderInfo,
                                        AppointmentOrder appointmentOrderInfo, TrainingOrder trainingOrder) {
        PaymentInfo paymentInfo = new PaymentInfo();
        if (Objects.nonNull(goodsOrderInfo)) {
            paymentInfo.setPatientId(Objects.isNull(goodsOrderInfo.getPatientId()) ? null : goodsOrderInfo.getPatientId());
            paymentInfo.setOrderNo(StringUtils.isBlank(goodsOrderInfo.getOrderNo()) ? "" : goodsOrderInfo.getOrderNo());
            paymentInfo.setPayChannel(StringUtils.isBlank(goodsOrderInfo.getOrderChannel()) ? "" : goodsOrderInfo.getOrderChannel());
        } else if (Objects.nonNull(appointmentOrderInfo)) {
            paymentInfo.setPatientId(Objects.isNull(appointmentOrderInfo.getPatientId()) ? null : appointmentOrderInfo.getPatientId());
            paymentInfo.setOrderNo(StringUtils.isBlank(appointmentOrderInfo.getOrderNo()) ? "" : appointmentOrderInfo.getOrderNo());
            paymentInfo.setPayChannel(StringUtils.isBlank(appointmentOrderInfo.getOrderChannel()) ? "" : appointmentOrderInfo.getOrderChannel());
        } else if (Objects.nonNull(trainingOrder)) {
            paymentInfo.setNurseStationPersonId(Objects.isNull(trainingOrder.getNurseStationPersonId()) ? null : trainingOrder.getNurseStationPersonId());
            paymentInfo.setOrderNo(StringUtils.isBlank(trainingOrder.getTrainingOrderNo()) ? "" : trainingOrder.getTrainingOrderNo());
            paymentInfo.setPayChannel(StringUtils.isBlank(trainingOrder.getTrainingOrderChannel()) ? "" : trainingOrder.getTrainingOrderChannel());
        }
        paymentInfo.setTransactionNo(StringUtils.isBlank(weChatQueryOrderVO.getTransactionId()) ? "" : weChatQueryOrderVO.getTransactionId());
        paymentInfo.setPayPrice(BigDecimal.valueOf(Objects.isNull(weChatQueryOrderVO.getAmount().getPayerTotal()) ? 0 : weChatQueryOrderVO.getAmount().getPayerTotal()).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN));
        paymentInfo.setPayType(PayTypeEnum.WECHAT_PAY.getInfo());
        paymentInfo.setWechatTradeState(StringUtils.isBlank(weChatQueryOrderVO.getTradeState()) ? "" : weChatQueryOrderVO.getTradeState());
        paymentInfo.setPayNotifyContent(JSON.toJSON(weChatQueryOrderVO).toString());
        paymentInfo.setPayTime(LocalDateTime.parse(StringUtils.isBlank(weChatQueryOrderVO.getSuccessTime()) ? "" : weChatQueryOrderVO.getSuccessTime(), DateTimeFormatter.ISO_DATE_TIME));
        paymentInfo.setPaymentMerchantType(PaymentMerchantTypeEnum.XINYILU.getInfo());
        paymentInfo.setDelFlag(0);
        paymentInfo.setCreateTime(LocalDateTime.now());
        return paymentInfo;
    }

    /**
     * 修改预约订单状态和修改预约次数上限
     *
     * @param orderAndDetailsInfo 输入参数
     * @param successList         处理成功的订单集合
     */
    private void updateAppointmentOrderStatus(AppointOrderAndDetailsInfo orderAndDetailsInfo, List<AppointOrderAndDetailsInfo> successList) {
        //关闭系统内部预约订单
        List<String> orderList = Collections.singletonList(orderAndDetailsInfo.getOrderNo());
        appointmentOrderMapper.updateBatchAppointmentOrderStatus(orderList, OrderStatusEnum.CANCEL.getInfo());
        //新增Redis中的预约次数
        if (Objects.nonNull(orderAndDetailsInfo.getAppointmentLimitCount()) && StringUtils.equals(AppointmentOrderTypeEnum.OTHER.getInfo(), orderAndDetailsInfo.getOrderType())) {
            String appointLimitCountKey = Constants.PRE_APPOINTMENT_LIMIT_COUNT_KEY + orderAndDetailsInfo.getNurseStationItemId() + "_" + orderAndDetailsInfo.getServiceDate() + "_" + orderAndDetailsInfo.getServiceStartTime();
            RedisAtomicLong redisAtomicLong = new RedisAtomicLong(appointLimitCountKey, Objects.requireNonNull(redisTemplate.getConnectionFactory()));
            if (redisAtomicLong.get() >= 0 && redisAtomicLong.get() < orderAndDetailsInfo.getAppointmentLimitCount()) {
                //预约次数加一
                redisAtomicLong.incrementAndGet();
                successList.add(orderAndDetailsInfo);
            }
        }
    }

    /**
     * 处理10分钟未支付的学习培训订单信息
     *
     * @param trainingOrderList 学习培训订单集合
     * @throws Exception 异常信息
     */
    private void handleWaitPayTrainingOrderInfo(List<TrainingOrder> trainingOrderList) throws Exception {
        List<String> orderList = Lists.newArrayList();
        List<String> closedOrderList = Lists.newArrayList();
        for (TrainingOrder trainingOrder : trainingOrderList) {
            if (Objects.isNull(trainingOrder) || StringUtils.isBlank(trainingOrder.getTrainingOrderNo())) {
                continue;
            }
            OrderStatusInfoVO vo = new OrderStatusInfoVO();
            //根据订单编号查询微信系统中订单的状态
            OrderStatusInfoVO statusInfoVO = weChatPaymentService.queryGoodsOrderStatus(trainingOrder.getTrainingOrderNo(), vo, BuySourceEnum.TRAINING.getInfo());
            if (BooleanUtils.isFalse(statusInfoVO.getPayFlag())) {
                closedOrderList.add(trainingOrder.getTrainingOrderNo());
                continue;
            }
            //关闭微信系统订单
            int statusCode = weChatPaymentService.closeWeChatOrderInfo(trainingOrder.getTrainingOrderNo(), BuySourceEnum.TRAINING.getInfo());
            if (statusCode == SUCCESS_CODE || statusCode == SUCCESS_CODE_TWO) {
                orderList.add(trainingOrder.getTrainingOrderNo());
            }
        }
        //关闭本地系统订单信息
        if (CollectionUtils.isNotEmpty(orderList)) {
            trainingOrderMapper.updateBatchTrainingOrderStatus(orderList, TrainingOrderStatusEnum.CANCEL.getInfo());
        }
        //关闭微信系统中已经关闭的订单而本地系统中未及时关闭的订单信息
        if (CollectionUtils.isEmpty(closedOrderList)) {
            return;
        }
        List<TrainingOrder> waitPayTrainingOrderList = trainingOrderMapper.getWaitPayTrainingOrderList(TrainingOrderStatusEnum.WAIT_PAY.getInfo(), closedOrderList);
        if (CollectionUtils.isEmpty(waitPayTrainingOrderList)) {
            return;
        }
        List<String> waitPayOrderList = waitPayTrainingOrderList.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getTrainingOrderNo())).map(TrainingOrder::getTrainingOrderNo).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(waitPayOrderList)) {
            trainingOrderMapper.updateBatchTrainingOrderStatus(waitPayOrderList, TrainingOrderStatusEnum.CANCEL.getInfo());
        }
    }
}
