admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/service/impl/order/OrderMoneySettleServiceImpl.java
@@ -1,1055 +1,785 @@
package com.yeshi.fanli.service.impl.order;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionExecuter;
import com.aliyun.openservices.ons.api.transaction.TransactionProducer;
import com.aliyun.openservices.ons.api.transaction.TransactionStatus;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.HongBaoV2Mapper;
import com.yeshi.fanli.dao.mybatis.UserInfoMapper;
import com.yeshi.fanli.dao.mybatis.order.HongBaoOrderMapper;
import com.yeshi.fanli.dao.mybatis.taobao.TaoBaoWeiQuanOrderMapper;
import com.yeshi.fanli.dto.HongBao;
import com.yeshi.fanli.dto.mq.order.OrderTopicTagEnum;
import com.yeshi.fanli.dto.mq.order.body.OrderMoneyRecievedMQMsg;
import com.yeshi.fanli.entity.bus.user.HongBaoV2;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.money.UserMoneyDetail;
import com.yeshi.fanli.entity.order.CommonOrder;
import com.yeshi.fanli.entity.order.HongBaoOrder;
import com.yeshi.fanli.entity.order.HongBaoV2SettleTemp;
import com.yeshi.fanli.entity.order.InviteOrderSubsidy;
import com.yeshi.fanli.entity.taobao.TaoBaoOrder;
import com.yeshi.fanli.entity.taobao.TaoBaoWeiQuanOrder;
import com.yeshi.fanli.exception.money.InviteOrderSubsidyDebtException;
import com.yeshi.fanli.exception.money.OrderMoneySettleException;
import com.yeshi.fanli.exception.money.UserMoneyDetailException;
import com.yeshi.fanli.exception.order.TaoBaoWeiQuanException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.hongbao.AccountDetailsHongBaoMapService;
import com.yeshi.fanli.service.inter.hongbao.HongBaoV2SettleTempService;
import com.yeshi.fanli.service.inter.money.InviteOrderSubsidyDebtService;
import com.yeshi.fanli.service.inter.money.UserMoneyService;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.money.tb.TaoBaoWeiQuanDrawBackService;
import com.yeshi.fanli.service.inter.order.CommonOrderService;
import com.yeshi.fanli.service.inter.order.InviteOrderSubsidyService;
import com.yeshi.fanli.service.inter.order.OrderMoneySettleService;
import com.yeshi.fanli.service.inter.order.tb.TaoBaoOrderService;
import com.yeshi.fanli.service.inter.user.UserSystemCouponService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.cmq.HongBaoRecieveCMQManager;
import com.yeshi.fanli.util.factory.UserMoneyDetailFactory;
import com.yeshi.fanli.util.rocketmq.MQMsgBodyFactory;
import com.yeshi.fanli.util.rocketmq.MQTopicName;
import com.yeshi.fanli.util.taobao.TaoKeOrderApiUtil;
@Service
public class OrderMoneySettleServiceImpl implements OrderMoneySettleService {
   @Resource
   private HongBaoV2Mapper hongBaoV2Mapper;
   @Resource
   private HongBaoOrderMapper hongBaoOrderMapper;
   @Resource
   private UserInfoMapper userInfoMapper;
   @Resource
   private TaoBaoWeiQuanOrderMapper taoBaoWeiQuanOrderMapper;
   @Resource
   private UserMoneyService userMoneyService;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Resource
   private TaoBaoWeiQuanDrawBackService taoBaoWeiQuanDrawBackService;
   @Resource
   private AccountDetailsHongBaoMapService accountDetailsHongBaoMapService;
   @Resource
   private CommonOrderService commonOrderService;
   @Resource
   private UserSystemCouponService userSystemCouponService;
   @Resource
   private TaoBaoOrderService taoBaoOrderService;
   @Resource(name = "orderTransactionProducer")
   private TransactionProducer orderTransactionProducer;
   // 邀请补贴
   @Resource
   private InviteOrderSubsidyService inviteOrderSubsidyService;
   @Resource
   private InviteOrderSubsidyDebtService inviteOrderSubsidyDebtService;
   @Resource
   private HongBaoV2SettleTempService hongBaoV2SettleTempService;
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteSettleTB(Long uid) throws OrderMoneySettleException {
      // 查询UID的一二级邀请赚
      int sourceType = Constant.SOURCE_TYPE_TAOBAO;
      List<Integer> types = new ArrayList<>();
      types.add(HongBaoV2.TYPE_YIJI);
      types.add(HongBaoV2.TYPE_ERJI);
      types.add(HongBaoV2.TYPE_SHARE_YIJI);
      types.add(HongBaoV2.TYPE_SHARE_ERJI);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      for (int i = 0; i < hongBaoList.size(); i++) {
         HongBaoV2 item = hongBaoList.get(i);
         if (item != null && item.getParent() != null) {
            if (item != null) {
               HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(item.getParent().getId());
               if (hongBaoOrder != null && hongBaoOrder.getCommonOrder() != null) {
                  CommonOrder co = hongBaoOrder.getCommonOrder();
                  // 上级用户不是正常用户,订单均不能到账
                  UserInfo userInfo = userInfoMapper.selectAvailableByPrimaryKey(co.getUserInfo().getId());
                  if (userInfo == null || userInfo.getState() != UserInfo.STATE_NORMAL) {
                     hongBaoList.remove(i);
                     i--;
                  }
               }
            }
         }
      }
      // 邀请赚到账事务消息
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_INVITE, uid,
            sourceType, null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               try {
                  fanliInviteTB(hongBaoList, uid, taskKey);
               } catch (TaoBaoWeiQuanException e) {
                  return TransactionStatus.RollbackTransaction;
               }
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
      System.out.println(new Gson().toJson(mqMsg));
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteSettleJD(Long uid) throws OrderMoneySettleException {
      // 查询UID的一二级邀请赚
      int sourceType = Constant.SOURCE_TYPE_JD;
      List<Integer> types = new ArrayList<>();
      types.add(HongBaoV2.TYPE_YIJI);
      types.add(HongBaoV2.TYPE_ERJI);
      types.add(HongBaoV2.TYPE_SHARE_YIJI);
      types.add(HongBaoV2.TYPE_SHARE_ERJI);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      for (int i = 0; i < hongBaoList.size(); i++) {
         HongBaoV2 item = hongBaoList.get(i);
         if (item != null && item.getParent() != null) {
            if (item != null) {
               HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(item.getParent().getId());
               if (hongBaoOrder != null && hongBaoOrder.getCommonOrder() != null) {
                  CommonOrder co = hongBaoOrder.getCommonOrder();
                  // 上级用户不是正常用户,订单均不能到账
                  UserInfo userInfo = userInfoMapper.selectAvailableByPrimaryKey(co.getUserInfo().getId());
                  if (userInfo == null || userInfo.getState() != UserInfo.STATE_NORMAL) {
                     hongBaoList.remove(i);
                     i--;
                  }
               }
            }
         }
      }
      // 邀请赚到账事务消息
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_INVITE, uid,
            sourceType, null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               fanliInviteOther(hongBaoList, uid, sourceType, taskKey);
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteSettlePDD(Long uid) throws OrderMoneySettleException {
      // 查询UID的一二级邀请赚
      int sourceType = Constant.SOURCE_TYPE_PDD;
      List<Integer> types = new ArrayList<>();
      types.add(HongBaoV2.TYPE_YIJI);
      types.add(HongBaoV2.TYPE_ERJI);
      types.add(HongBaoV2.TYPE_SHARE_YIJI);
      types.add(HongBaoV2.TYPE_SHARE_ERJI);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      for (int i = 0; i < hongBaoList.size(); i++) {
         HongBaoV2 item = hongBaoList.get(i);
         if (item != null && item.getParent() != null) {
            if (item != null) {
               HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(item.getParent().getId());
               if (hongBaoOrder != null && hongBaoOrder.getCommonOrder() != null) {
                  CommonOrder co = hongBaoOrder.getCommonOrder();
                  // 上级用户不是正常用户,订单均不能到账
                  UserInfo userInfo = userInfoMapper.selectAvailableByPrimaryKey(co.getUserInfo().getId());
                  if (userInfo == null || userInfo.getState() != UserInfo.STATE_NORMAL) {
                     hongBaoList.remove(i);
                     i--;
                  }
               }
            }
         }
      }
      // 邀请赚到账事务消息
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_INVITE, uid,
            sourceType, null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               fanliInviteOther(hongBaoList, uid, sourceType, taskKey);
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void shareSettleTB(Long uid) throws OrderMoneySettleException {
      /**
       * 处理分享赚
       */
      int sourceType = Constant.SOURCE_TYPE_TAOBAO;
      List<Integer> types = new ArrayList<>();
      // 查询UID的分享赚订单
      types.add(HongBaoV2.TYPE_SHARE_GOODS);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
            null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               try {
                  fanLiShareTB(hongBaoList, uid, taskKey);
               } catch (TaoBaoWeiQuanException e) {
                  return TransactionStatus.RollbackTransaction;
               }
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void shareSettleJD(Long uid) throws OrderMoneySettleException {
      /**
       * 处理分享赚
       */
      int sourceType = Constant.SOURCE_TYPE_JD;
      List<Integer> types = new ArrayList<>();
      // 查询UID的分享赚订单
      types.add(HongBaoV2.TYPE_SHARE_GOODS);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
            null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               fanLiShareOther(hongBaoList, uid, sourceType, taskKey);
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void shareSettlePDD(Long uid) throws OrderMoneySettleException {
      /**
       * 处理分享赚
       */
      int sourceType = Constant.SOURCE_TYPE_PDD;
      List<Integer> types = new ArrayList<>();
      // 查询UID的分享赚订单
      types.add(HongBaoV2.TYPE_SHARE_GOODS);
      long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      // 1000条数据为1页
      int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
      for (int i = 0; i < page; i++) {
         List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
               i * 1000, 1000);
         if (tempHongBaoList != null && tempHongBaoList.size() > 0)
            hongBaoList.addAll(tempHongBaoList);
      }
      OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
            null, null, new Date(), 0);
      Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
      String taskKey = getTaskKey(uid);
      msg.setKey(taskKey);
      // 添加事务消息
      try {
         orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
            @Override
            public TransactionStatus execute(Message arg0, Object arg1) {
               fanLiShareOther(hongBaoList, uid, sourceType, taskKey);
               return TransactionStatus.CommitTransaction;
            }
         }, null);
      } catch (Exception e) {
         LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
      }
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void ziGouSettle(String orderId, int sourceType, String taskKey) throws OrderMoneySettleException {
      // 查询同一订单号的红包
      List<CommonOrder> orderList = commonOrderService.listBySourceTypeAndOrderId(sourceType, orderId);
      List<HongBaoV2> hongBaoList = new ArrayList<>();
      Map<Long, BigDecimal> userMoney = new HashMap<>();
      Map<Long, List<HongBaoV2>> userHongBao = new HashMap<>();
      Map<Long, Integer> userGoodsCount = new HashMap<>();
      for (CommonOrder co : orderList) {
         HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByCommonOrderId(co.getId());
         hongBaoList.add(hongBaoOrder.getHongBaoV2());
         Long uid = co.getUserInfo().getId();
         if (userGoodsCount.get(uid) == null)
            userGoodsCount.put(uid, co.getCount());
         else
            userGoodsCount.put(uid, Integer.valueOf(co.getCount() + userGoodsCount.get(uid)));
      }
      for (HongBaoV2 hb : hongBaoList) {
         long currentTimeMillis = System.currentTimeMillis();
         if (hb.getState() != HongBao.STATE_SHIXIAO) {
            // 设置为已返利
            // 处理主红包
            if (hb.getState() != HongBaoV2.STATE_SHIXIAO && hb.getState() != HongBaoV2.STATE_YILINGQU
                  && hb.getType() == HongBaoV2.TYPE_ZIGOU) {
               // 如果红包没被领取
               Long uid = hb.getUserInfo().getId();
               HongBaoV2 updateHongBao = new HongBaoV2();
               updateHongBao.setId(hb.getId());
               updateHongBao.setState(HongBaoV2.STATE_YILINGQU);
               updateHongBao.setGetTime(new Date(currentTimeMillis));
               hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
               if (userMoney.get(uid) == null)
                  userMoney.put(uid, hb.getMoney());
               else
                  userMoney.put(uid, userMoney.get(uid).add(hb.getMoney()));
               // 添加红包到用户
               if (userHongBao.get(uid) == null)
                  userHongBao.put(uid, new ArrayList<>());
               userHongBao.get(uid).add(hb);
            }
         }
      }
      // 获取维权资金
      if (sourceType == Constant.SOURCE_TYPE_TAOBAO) {
         try {
            Map<Long, BigDecimal> userSubMoneyMap = taoBaoWeiQuanDrawBackService.doWeiQuanFanli(orderId, false);
            if (userSubMoneyMap != null) {
               for (Iterator<Long> its = userMoney.keySet().iterator(); its.hasNext();) {
                  Long uid = its.next();
                  if (userSubMoneyMap.get(uid) != null) {
                     // 减去维权资金
                     userMoney.put(uid, userMoney.get(uid).subtract(userSubMoneyMap.get(uid)));
                  }
               }
            }
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
            throw new OrderMoneySettleException(2, "维权订单出错");
         }
      }
      // if (userMoney.isEmpty()) {
      // throw new OrderMoneySettleException(1, "没有需要结算的订单");
      // }
      Iterator<Long> its = userMoney.keySet().iterator();
      while (its.hasNext()) {
         // 将自己添加到用户
         Long uid = its.next();
         BigDecimal money = userMoney.get(uid);
         UserMoneyDetail userMoneyDetail = null;
         // 插入新版资金明细
         try {
            // 此处不用订单号做唯一性索引
            userMoneyDetail = UserMoneyDetailFactory.createFanLi(uid, orderId, sourceType, null, money);
         } catch (UserMoneyDetailException e1) {
            try {
               LogHelper.errorDetailInfo(e1, "订单号:" + orderId, "");
            } catch (Exception e2) {
               e2.printStackTrace();
            }
         }
         userMoneyService.addUserMoney(uid, money, userMoneyDetail);
         List<Long> hbIdList = new ArrayList<>();
         // 添加资金明细与红包的映射关系
         for (HongBaoV2 v2 : userHongBao.get(uid)) {
            hbIdList.add(v2.getId());
            accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(v2.getId(), userMoneyDetail.getId());
            try {
               HongBaoRecieveCMQManager.getInstance().addHongBaoRecieveMsg(v2.getId());
            } catch (Exception e) {
               LogHelper.errorDetailInfo(e);
            }
         }
         // 添加结算映射
         hongBaoV2SettleTempService.addTemp(hbIdList, taskKey);
         // 站内信+推送
         UserInfo user = userInfoMapper.selectByPrimaryKey(uid);
         // 新版通知
         userMoneyMsgNotificationService.fanliOrderReceived(uid, orderId, sourceType, userGoodsCount.get(uid), money,
               user.getMyHongBao());
      }
      // 通知免单到账
      try {
         userSystemCouponService.updateStateByArrivalAccount(orderId);
      } catch (Exception e) {
         e.printStackTrace();
      }
      // 添加结算映射
   }
   private HongBaoV2 filterWeiQuanINGHongBao(HongBaoV2 hongBao) {
      long hbId = hongBao.getId();
      if (hongBao.getParent() != null) {
         hbId = hongBao.getParent().getId();
      }
      HongBaoOrder hongbaoOrder = hongBaoOrderMapper.selectByHongBaoId(hbId);
      if (hongbaoOrder == null)
         return null;
      List<TaoBaoWeiQuanOrder> taoBaoWeiQuanList = taoBaoWeiQuanOrderMapper
            .selectListByOrderIdAndState(hongbaoOrder.getCommonOrder().getOrderNo(), "维权创建");
      List<TaoBaoWeiQuanOrder> taoBaoWeiQuanList1 = taoBaoWeiQuanOrderMapper
            .selectListByOrderIdAndState(hongbaoOrder.getCommonOrder().getOrderNo(), "等待处理");
      if ((taoBaoWeiQuanList != null && taoBaoWeiQuanList.size() > 0)
            || (taoBaoWeiQuanList1 != null && taoBaoWeiQuanList1.size() > 0)) {
         return null;
      }
      return hongBao;
   }
   @Transactional(rollbackFor = Exception.class)
   private void fanliInviteTB(List<HongBaoV2> hongBaoList, Long uid, String key) throws TaoBaoWeiQuanException {
      List<Long> hbIdList = new ArrayList<>();
      BigDecimal invitemoney = new BigDecimal(0);
      Set<String> inviteOrders = new HashSet<>();
      int inviteGoodsCount = 0;
      // 需要判断退款的订单号
      Set<String> drawBackOrders = new HashSet<String>();
      for (HongBaoV2 hongBao : hongBaoList) {
         hongBao = filterWeiQuanINGHongBao(hongBao);
         if (hongBao == null)
            continue;
         hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
         if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
            invitemoney = invitemoney.add(hongBao.getMoney());
            HongBaoV2 updateHongBao = new HongBaoV2();
            updateHongBao.setId(hongBao.getId());
            updateHongBao.setGetTime(new Date());
            updateHongBao.setState(HongBaoV2.STATE_YILINGQU);
            updateHongBao.setUpdateTime(new Date());
            hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
            // 添加到红包返利记录集合
            hbIdList.add(hongBao.getId());
            HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getParent().getId());
            inviteGoodsCount += hongBaoOrder.getCommonOrder().getCount();
            inviteOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
            Date balanceTime = hongBaoOrder.getCommonOrder().getSettleTime();
            if (balanceTime != null
                  && balanceTime.getTime() >= TimeUtil.convertToTimeTemp("2018-08-05", "yyyy-MM-dd")) {
               if (!StringUtil.isNullOrEmpty(hongBaoOrder.getCommonOrder().getOrderNo()))
                  drawBackOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
            }
         }
      }
      // 邀请赚到账
      if (invitemoney.compareTo(new BigDecimal(0)) > 0) {
         // 添加新版详情记录
         try {
            // 查询邀请赚的有效订单,失效订单,维权订单
            Calendar ca = Calendar.getInstance();
            Date maxDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            ca.add(Calendar.MONTH, -1);
            Date minDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            long validCount = hongBaoV2Mapper.countInviteOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_JS,
                  minDate, maxDate, Constant.SOURCE_TYPE_TAOBAO);
            long weiQuanCount = hongBaoV2Mapper.countInviteOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_WQ,
                  minDate, maxDate, Constant.SOURCE_TYPE_TAOBAO);
            UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createInvite(uid, Constant.SOURCE_TYPE_TAOBAO,
                  (int) validCount, (int) weiQuanCount, invitemoney, new Date());
            // 增加资金
            userMoneyService.addUserMoney(uid, invitemoney, userMoneyDetail);
            // 添加到红包返利记录集合
            accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
         } catch (UserMoneyDetailException e) {
            try {
               LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
               e1.printStackTrace();
            }
         }
         // 新版通知
         userMoneyMsgNotificationService.inviteOrderReceived(uid, Constant.SOURCE_TYPE_TAOBAO, inviteOrders.size(),
               inviteGoodsCount, invitemoney, userInfoMapper.selectByPrimaryKey(uid).getMyHongBao());
         for (String orderId : drawBackOrders)
            taoBaoWeiQuanDrawBackService.doWeiQuanInvite(orderId);
      }
      try {
         hongBaoV2SettleTempService.addTemp(hbIdList, key);
      } catch (Exception e1) {
         throw new TaoBaoWeiQuanException(200, "插入返利临时表出错");
      }
      // 所有的返利到账红包ID
      for (Long hongBaoId : hbIdList) {
         try {
            HongBaoRecieveCMQManager.getInstance().addHongBaoRecieveMsg(hongBaoId);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
         }
      }
   }
   @Transactional
   private void fanliInviteOther(List<HongBaoV2> hongBaoList, Long uid, int sourceType, String key) {
      List<Long> hbIdList = new ArrayList<>();
      BigDecimal invitemoney = new BigDecimal(0);
      Set<String> inviteOrders = new HashSet<>();
      int inviteGoodsCount = 0;
      // 需要判断退款的订单号
      for (HongBaoV2 hongBao : hongBaoList) {
         hongBao = filterWeiQuanINGHongBao(hongBao);
         if (hongBao == null)
            continue;
         hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
         if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
            invitemoney = invitemoney.add(hongBao.getMoney());
            HongBaoV2 updateHongBao = new HongBaoV2();
            updateHongBao.setId(hongBao.getId());
            updateHongBao.setGetTime(new Date());
            updateHongBao.setState(HongBaoV2.STATE_YILINGQU);
            updateHongBao.setUpdateTime(new Date());
            hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
            // 添加到红包返利记录集合
            hbIdList.add(hongBao.getId());
            // 2018-08-05 过后的订单才处理维权
            HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getParent().getId());
            inviteGoodsCount += hongBaoOrder.getCommonOrder().getCount();
            inviteOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
         }
      }
      // 邀请赚到账
      if (invitemoney.compareTo(new BigDecimal(0)) > 0) {
         // 添加新版详情记录
         try {
            // 查询邀请赚的有效订单,失效订单,维权订单
            Calendar ca = Calendar.getInstance();
            Date maxDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            ca.add(Calendar.MONTH, -1);
            Date minDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            long validCount = hongBaoV2Mapper.countInviteOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_JS,
                  minDate, maxDate, sourceType);
            long weiQuanCount = hongBaoV2Mapper.countInviteOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_WQ,
                  minDate, maxDate, sourceType);
            UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createInvite(uid, sourceType, (int) validCount,
                  (int) weiQuanCount, invitemoney, new Date());
            // 增加资金
            userMoneyService.addUserMoney(uid, invitemoney, userMoneyDetail);
            // 添加到红包返利记录集合
            accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
         } catch (UserMoneyDetailException e) {
            try {
               LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
               e1.printStackTrace();
            }
         }
         // 新版通知
         userMoneyMsgNotificationService.inviteOrderReceived(uid, sourceType, inviteOrders.size(), inviteGoodsCount,
               invitemoney, userInfoMapper.selectByPrimaryKey(uid).getMyHongBao());
      }
      hongBaoV2SettleTempService.addTemp(hbIdList, key);
      // 所有的返利到账红包ID
      for (Long hongBaoId : hbIdList) {
         try {
            HongBaoRecieveCMQManager.getInstance().addHongBaoRecieveMsg(hongBaoId);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
         }
      }
   }
   /**
    * 淘宝分享赚返利
    *
    * @param hongBaoList
    * @param uid
    * @throws TaoBaoWeiQuanException
    */
   private void fanLiShareTB(List<HongBaoV2> hongBaoList, Long uid, String key) throws TaoBaoWeiQuanException {
      BigDecimal sharemoney = new BigDecimal(0);
      List<Long> hbIdList = new ArrayList<>();
      Set<String> drawBackOrders = new HashSet<String>();
      List<Long> recieveHongBaoIds = new ArrayList<>();
      int shareGoodsCount = 0;
      Set<String> shareOrders = new HashSet<>();
      for (HongBaoV2 hongBao : hongBaoList) {
         hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
         hongBao = filterWeiQuanINGHongBao(hongBao);
         if (hongBao == null)
            continue;
         if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
            sharemoney = sharemoney.add(hongBao.getMoney());
            HongBaoV2 updateHongBao = new HongBaoV2();
            updateHongBao.setId(hongBao.getId());
            updateHongBao.setGetTime(new Date());
            updateHongBao.setState(HongBao.STATE_YILINGQU);
            updateHongBao.setUpdateTime(new Date());
            hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
            // 添加到红包返利记录集合
            hbIdList.add(hongBao.getId());
            // 2018-08-05 过后的订单才处理维权
            Date balanceTime = null;
            HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getId());
            if (hongBaoOrder != null) {
               balanceTime = hongBaoOrder.getCommonOrder().getSettleTime();
               shareGoodsCount += hongBaoOrder.getCommonOrder().getCount();
            }
            shareOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
            if (balanceTime != null
                  && balanceTime.getTime() >= TimeUtil.convertToTimeTemp("2018-08-05", "yyyy-MM-dd")) {
               drawBackOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
            }
         }
      }
      /**
       * 分享赚到账
       */
      if (sharemoney.compareTo(new BigDecimal(0)) > 0) {
         // 添加新版详情记录
         try {
            // 计算本月的有效订单,失效订单,维权订单
            Calendar ca = Calendar.getInstance();
            Date maxDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            ca.add(Calendar.MONTH, -1);
            Date minDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            long validCount = hongBaoV2Mapper.countShareOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_JS,
                  minDate, maxDate, Constant.SOURCE_TYPE_TAOBAO);
            long weiQuanCount = hongBaoV2Mapper.countShareOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_WQ,
                  minDate, maxDate, Constant.SOURCE_TYPE_TAOBAO);
            UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createShare(uid, Constant.SOURCE_TYPE_TAOBAO,
                  (int) validCount, (int) weiQuanCount, sharemoney, new Date());
            // 添加资金
            userMoneyService.addUserMoney(uid, sharemoney, userMoneyDetail);
            // 添加到红包返利记录集合
            accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
            if (hbIdList.size() > 0)
               recieveHongBaoIds.addAll(hbIdList);
         } catch (UserMoneyDetailException e) {
            try {
               LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
               e1.printStackTrace();
            }
         }
         // 新版通知
         userMoneyMsgNotificationService.shareOrderReceived(uid, Constant.SOURCE_TYPE_TAOBAO, shareOrders.size(),
               shareGoodsCount, sharemoney, userInfoMapper.selectAvailableByPrimaryKey(uid).getMyHongBao());
         for (String orderId : drawBackOrders)
            taoBaoWeiQuanDrawBackService.doWeiQuanShare(orderId);
      }
      hongBaoV2SettleTempService.addTemp(recieveHongBaoIds, key);
      // 所有的返利到账红包ID
      for (Long hongBaoId : recieveHongBaoIds) {
         try {
            HongBaoRecieveCMQManager.getInstance().addHongBaoRecieveMsg(hongBaoId);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
         }
      }
   }
   /**
    * 其他平台分享赚返利
    *
    * @param hongBaoList
    * @param uid
    * @param sourceType
    */
   private void fanLiShareOther(List<HongBaoV2> hongBaoList, Long uid, int sourceType, String key) {
      BigDecimal sharemoney = new BigDecimal(0);
      List<Long> hbIdList = new ArrayList<>();
      List<Long> recieveHongBaoIds = new ArrayList<>();
      int shareGoodsCount = 0;
      Set<String> shareOrders = new HashSet<>();
      for (HongBaoV2 hongBao : hongBaoList) {
         hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
         hongBao = filterWeiQuanINGHongBao(hongBao);
         if (hongBao == null)
            continue;
         if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
            sharemoney = sharemoney.add(hongBao.getMoney());
            HongBaoV2 updateHongBao = new HongBaoV2();
            updateHongBao.setId(hongBao.getId());
            updateHongBao.setGetTime(new Date());
            updateHongBao.setState(HongBao.STATE_YILINGQU);
            updateHongBao.setUpdateTime(new Date());
            hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
            // 添加到红包返利记录集合
            hbIdList.add(hongBao.getId());
            // 2018-08-05 过后的订单才处理维权
            HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getId());
            if (hongBaoOrder != null) {
               shareGoodsCount += hongBaoOrder.getCommonOrder().getCount();
            }
            shareOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
         }
      }
      /**
       * 分享赚到账
       */
      if (sharemoney.compareTo(new BigDecimal(0)) > 0) {
         // 添加新版详情记录
         try {
            // 计算本月的有效订单,失效订单,维权订单
            Calendar ca = Calendar.getInstance();
            Date maxDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            ca.add(Calendar.MONTH, -1);
            Date minDate = new Date(TimeUtil
                  .convertToTimeTemp(ca.get(Calendar.YEAR) + "-" + (ca.get(Calendar.MONTH) + 1), "yyyy-M"));
            long validCount = hongBaoV2Mapper.countShareOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_JS,
                  minDate, maxDate, sourceType);
            long weiQuanCount = hongBaoV2Mapper.countShareOrderCountByUidAndSettleTime(uid, CommonOrder.STATE_WQ,
                  minDate, maxDate, sourceType);
            UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createShare(uid, sourceType, (int) validCount,
                  (int) weiQuanCount, sharemoney, new Date());
            // 添加资金
            userMoneyService.addUserMoney(uid, sharemoney, userMoneyDetail);
            // 添加到红包返利记录集合
            accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
            if (hbIdList.size() > 0)
               recieveHongBaoIds.addAll(hbIdList);
         } catch (UserMoneyDetailException e) {
            try {
               LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
               e1.printStackTrace();
            }
         }
         // 新版通知
         userMoneyMsgNotificationService.shareOrderReceived(uid, Constant.SOURCE_TYPE_TAOBAO, shareOrders.size(),
               shareGoodsCount, sharemoney, userInfoMapper.selectAvailableByPrimaryKey(uid).getMyHongBao());
      }
      hongBaoV2SettleTempService.addTemp(recieveHongBaoIds, key);
      // 所有的返利到账红包ID
      for (Long hongBaoId : recieveHongBaoIds) {
         try {
            HongBaoRecieveCMQManager.getInstance().addHongBaoRecieveMsg(hongBaoId);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
         }
      }
   }
   /**
    * 邀请补贴结算
    *
    * @param orderId
    * @param sourceType
    */
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteSubsidySettle(Long uid, String taskKey) throws OrderMoneySettleException {
      // 查询key
      List<HongBaoV2SettleTemp> list = hongBaoV2SettleTempService.listByKey(taskKey);
      if (list != null && list.size() > 0) {
         Integer sourceType = null;
         List<InviteOrderSubsidy> subsidyList = new ArrayList<>();
         for (HongBaoV2SettleTemp temp : list) {
            Long hongBaoId = temp.getHongBaoId();
            HongBaoV2 hongBao = hongBaoV2Mapper.selectByPrimaryKey(hongBaoId);
            if (hongBao != null)
               sourceType = hongBao.getOrderType();
            if (hongBao.getParent() != null)
               hongBao = hongBao.getParent();
            HongBaoOrder order = hongBaoOrderMapper.selectByHongBaoId(hongBao.getId());
            if (order != null && order.getCommonOrder() != null) {
               InviteOrderSubsidy subSidy = inviteOrderSubsidyService.getByOrderNoAndTypeForUpdate(uid,
                     order.getCommonOrder().getOrderNo(), order.getCommonOrder().getSourceType());
               if (subSidy != null && subSidy.getState() == InviteOrderSubsidy.STATE_VALID) {
                  subsidyList.add(subSidy);
               }
            }
         }
         if (sourceType == null)
            throw new OrderMoneySettleException(1, "订单类型未获取到");
         if (subsidyList.size() > 0) {
            BigDecimal debtMoney = inviteOrderSubsidyDebtService.getTotalDebtMoney(uid);
            BigDecimal originalDebtMoney = new BigDecimal(debtMoney.toString());// 总的欠款
            List<InviteOrderSubsidy> copySubsidyList = new ArrayList<>();
            copySubsidyList.addAll(subsidyList);
            while (debtMoney.compareTo(new BigDecimal(0)) > 0 && copySubsidyList.size() > 0) {// 有欠款,还有还的
               debtMoney = kouKuan(copySubsidyList, debtMoney);
            }
            // 还款
            BigDecimal repayMoney = originalDebtMoney.subtract(debtMoney);
            BigDecimal bannce = null;
            if (repayMoney.compareTo(new BigDecimal(0)) > 0) {
               try {
                  bannce = inviteOrderSubsidyDebtService.repayDebtByUid(uid, repayMoney);
                  // 剩余的补贴金额
               } catch (InviteOrderSubsidyDebtException e) {
                  throw new OrderMoneySettleException(2, "还款异常");
               }
            }
            if (bannce != null && bannce.compareTo(new BigDecimal(0)) > 0) {
               // 如果有还剩下的钱就加到第一个上面
               subsidyList.get(0).setMoney(subsidyList.get(0).getMoney().add(bannce));
            }
            BigDecimal totalMoney = new BigDecimal(0);
            for (InviteOrderSubsidy subsidy : subsidyList) {
               inviteOrderSubsidyService.settleById(subsidy.getId(), subsidy.getMoney());
               totalMoney = totalMoney.add(subsidy.getMoney());
            }
            // 到账
            UserMoneyDetail userMoneyDetail = null;
            try {
               userMoneyDetail = UserMoneyDetailFactory.createInviteSubsidy(uid, sourceType, totalMoney,
                     new Date());
            } catch (UserMoneyDetailException e) {
               throw new OrderMoneySettleException(1, "账户明细构建出错");
            }
            // 添加资金
            userMoneyService.addUserMoney(uid, totalMoney, userMoneyDetail);
            // 添加消息
            userMoneyMsgNotificationService.inviteOrderSubSidy(uid, new Date(), "系统自动下发", totalMoney,
                  userInfoMapper.selectAvailableByPrimaryKey(uid).getMyHongBao());
         }
      }
   }
   private String getTaskKey(Long uid) {
      return uid + "-" + UUID.randomUUID().toString();
   }
   private BigDecimal kouKuan(List<InviteOrderSubsidy> subsidyList, BigDecimal debtMoney) {
      BigDecimal average = debtMoney.divide(new BigDecimal(subsidyList.size()), 2, RoundingMode.UP);
      for (int i = 0; i < subsidyList.size(); i++) {
         InviteOrderSubsidy sidy = subsidyList.get(i);
         BigDecimal subMoney = null;
         if (average.compareTo(sidy.getMoney()) >= 0) {
            subMoney = sidy.getMoney();
         } else {
            subMoney = average;
         }
         if (subMoney.compareTo(debtMoney) > 0)
            subMoney = debtMoney;
         debtMoney = debtMoney.subtract(subMoney);
         sidy.setMoney(sidy.getMoney().subtract(subMoney));
         if (sidy.getMoney().compareTo(new BigDecimal(0)) == 0) {
            subsidyList.remove(i);
            i--;
         }
      }
      return debtMoney;
   }
}
package com.yeshi.fanli.service.impl.order;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Resource;
import com.yeshi.fanli.util.mq.rabbit.RabbitmqManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionExecuter;
import com.aliyun.openservices.ons.api.transaction.TransactionProducer;
import com.aliyun.openservices.ons.api.transaction.TransactionStatus;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.HongBaoV2Mapper;
import com.yeshi.fanli.dao.mybatis.UserInfoMapper;
import com.yeshi.fanli.dao.mybatis.order.HongBaoOrderMapper;
import com.yeshi.fanli.dao.mybatis.taobao.TaoBaoWeiQuanOrderMapper;
import com.yeshi.fanli.dto.HongBao;
import com.yeshi.fanli.dto.mq.order.OrderTopicTagEnum;
import com.yeshi.fanli.dto.mq.order.body.OrderMoneyRecievedMQMsg;
import com.yeshi.fanli.dto.mq.order.body.TeamRewardPreRecieveMQMsg;
import com.yeshi.fanli.entity.bus.user.HongBaoV2;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.money.TeamRewardDebt;
import com.yeshi.fanli.entity.money.UserMoneyDetail;
import com.yeshi.fanli.entity.order.CommonOrder;
import com.yeshi.fanli.entity.order.HongBaoOrder;
import com.yeshi.fanli.entity.taobao.TaoBaoWeiQuanOrder;
import com.yeshi.fanli.exception.ParamsException;
import com.yeshi.fanli.exception.money.OrderMoneySettleException;
import com.yeshi.fanli.exception.money.TeamEincomeRecordException;
import com.yeshi.fanli.exception.money.TeamRewardDebtException;
import com.yeshi.fanli.exception.money.UserMoneyDetailException;
import com.yeshi.fanli.exception.order.TaoBaoWeiQuanException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.hongbao.AccountDetailsHongBaoMapService;
import com.yeshi.fanli.service.inter.hongbao.HongBaoV2SettleTempService;
import com.yeshi.fanli.service.inter.money.TeamRewardDebtService;
import com.yeshi.fanli.service.inter.money.UserMoneyService;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.money.tb.TaoBaoWeiQuanDrawBackService;
import com.yeshi.fanli.service.inter.order.CommonOrderService;
import com.yeshi.fanli.service.inter.order.OrderMoneySettleService;
import com.yeshi.fanli.service.inter.user.UserSystemCouponService;
import com.yeshi.fanli.service.manger.msg.RocketMQManager;
import com.yeshi.fanli.service.manger.order.TeamRewardManager;
import com.yeshi.fanli.util.Constant;
import org.yeshi.utils.TimeUtil;
import com.yeshi.fanli.util.factory.UserMoneyDetailFactory;
import com.yeshi.fanli.util.mq.cmq.HongBaoRecieveCMQManager;
import com.yeshi.fanli.util.rocketmq.MQMsgBodyFactory;
import com.yeshi.fanli.util.rocketmq.MQTopicName;
@Service
public class OrderMoneySettleServiceImpl implements OrderMoneySettleService {
    Logger logger = LoggerFactory.getLogger(OrderMoneySettleService.class);
    @Resource
    private HongBaoV2Mapper hongBaoV2Mapper;
    @Resource
    private HongBaoOrderMapper hongBaoOrderMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private TaoBaoWeiQuanOrderMapper taoBaoWeiQuanOrderMapper;
    @Resource
    private UserMoneyService userMoneyService;
    @Resource
    private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
    @Resource
    private TaoBaoWeiQuanDrawBackService taoBaoWeiQuanDrawBackService;
    @Resource
    private AccountDetailsHongBaoMapService accountDetailsHongBaoMapService;
    @Resource
    private CommonOrderService commonOrderService;
    @Resource
    private UserSystemCouponService userSystemCouponService;
    @Resource(name = "orderTransactionProducer")
    private TransactionProducer orderTransactionProducer;
    // 邀请补贴
    @Resource
    private HongBaoV2SettleTempService hongBaoV2SettleTempService;
    @Resource
    private TeamRewardDebtService teamRewardDebtService;
    @Resource
    private TeamRewardManager teamRewardManager;
    @Resource
    private RocketMQManager rocketMQManager;
    @Resource
    private HongBaoRecieveCMQManager hongBaoRecieveCMQManager;
    // 下级被封禁,红包失效
    private void invalidHongBaoForbidden(HongBaoV2 hongBaoV2) throws TeamRewardDebtException {
        if (hongBaoV2.getState() == HongBaoV2.STATE_SHIXIAO || hongBaoV2.getState() == HongBaoV2.STATE_YILINGQU || hongBaoV2.getState() == HongBaoV2.STATE_LINGQUING)
            return;
        //如果在偿还里面就先偿还,然后再失效
        TeamRewardDebt debt = teamRewardDebtService.selectBySourceId(hongBaoV2.getId());
        if (debt != null &&debt.getLeftMoney().compareTo(new BigDecimal(0))>0  && debt.getLeftMoney().compareTo(hongBaoV2.getMoney()) <= 0) {
            teamRewardDebtService.repayDebt(debt.getId(), hongBaoV2.getMoney(), "封禁失效,先偿还再失效");
        }
        HongBaoV2 updateHongBaoV2 = new HongBaoV2(hongBaoV2.getId());
        updateHongBaoV2.setState(HongBaoV2.STATE_SHIXIAO);
        updateHongBaoV2.setBeizhu("封禁失效");
        updateHongBaoV2.setUpdateTime(new Date());
        hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBaoV2);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void inviteSettleTB(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_TAOBAO;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void inviteSettleJD(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_JD;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void inviteSettlePDD(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_PDD;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void inviteSettleVipShop(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_VIP;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    @Override
    public void inviteSettleDY(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_DY;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void inviteSettleSuning(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        int sourceType = Constant.SOURCE_TYPE_SUNING;
        inviteSettle(uid, sourceType, maxPregetTime);
    }
    private void inviteSettle(Long uid, int sourceType, Date maxPregetTime) throws OrderMoneySettleException {
        // 查询UID的一二级邀请赚
        List<Integer> types = new ArrayList<>();
        types.add(HongBaoV2.TYPE_YIJI);
        types.add(HongBaoV2.TYPE_ERJI);
        types.add(HongBaoV2.TYPE_SHARE_YIJI);
        types.add(HongBaoV2.TYPE_SHARE_ERJI);
        long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType, maxPregetTime);
        List<HongBaoV2> hongBaoList = new ArrayList<>();
        // 1000条数据为1页
        int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
        for (int i = 0; i < page; i++) {
            List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
                    maxPregetTime, i * 1000, 1000);
            if (tempHongBaoList != null && tempHongBaoList.size() > 0)
                hongBaoList.addAll(tempHongBaoList);
        }
        for (int i = 0; i < hongBaoList.size(); i++) {
            HongBaoV2 item = hongBaoList.get(i);
            if (item != null && item.getParent() != null) {
                if (item != null) {
                    HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(item.getParent().getId());
                    if (hongBaoOrder != null && hongBaoOrder.getCommonOrder() != null) {
                        CommonOrder co = hongBaoOrder.getCommonOrder();
                        // 上级用户不是正常用户,订单均不能到账
                        UserInfo userInfo = userInfoMapper.selectAvailableByPrimaryKey(co.getUserInfo().getId());
                        if (userInfo == null || userInfo.getState() != UserInfo.STATE_NORMAL) {
                            try {
                                invalidHongBaoForbidden(item);
                            } catch (TeamRewardDebtException e) {
                                e.printStackTrace();
                                throw new OrderMoneySettleException(10, "偿还出错");
                            }
                            hongBaoList.remove(i);
                            i--;
                        }
                    }
                }
            }
        }
        if (hongBaoList.size() == 0)
            return;
        // 邀请赚到账事务消息
        String taskKey = getTaskKey(uid);
        TeamRewardPreRecieveMQMsg mqMsg = new TeamRewardPreRecieveMQMsg(taskKey, uid, sourceType, maxPregetTime,
                new Date());
        Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.teamRewardPreRecieved, mqMsg);
        msg.setKey(taskKey);
        // 添加事务消息
        try {
            orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
                @Override
                public TransactionStatus execute(Message arg0, Object arg1) {
                    try {
                        fanliInvite(hongBaoList, uid, sourceType, taskKey, maxPregetTime);
                    } catch (Exception e) {
                        return TransactionStatus.RollbackTransaction;
                    }
                    return TransactionStatus.CommitTransaction;
                }
            }, null);
        } catch (Exception e) {
            LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void shareSettleTB(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        /**
         * 处理分享赚
         */
        int sourceType = Constant.SOURCE_TYPE_TAOBAO;
        List<Integer> types = new ArrayList<>();
        // 查询UID的分享赚订单
        types.add(HongBaoV2.TYPE_SHARE_GOODS);
        long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType, maxPregetTime);
        List<HongBaoV2> hongBaoList = new ArrayList<>();
        // 1000条数据为1页
        int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
        for (int i = 0; i < page; i++) {
            List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
                    maxPregetTime, i * 1000, 1000);
            if (tempHongBaoList != null && tempHongBaoList.size() > 0)
                hongBaoList.addAll(tempHongBaoList);
        }
        OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
                null, null, new Date(), 0);
        Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
        String taskKey = getTaskKey(uid);
        msg.setKey(taskKey);
        // 添加事务消息
        try {
            orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
                @Override
                public TransactionStatus execute(Message arg0, Object arg1) {
                    try {
                        fanLiShareTB(hongBaoList, uid, taskKey,maxPregetTime);
                    } catch (TaoBaoWeiQuanException e) {
                        return TransactionStatus.RollbackTransaction;
                    }
                    return TransactionStatus.CommitTransaction;
                }
            }, null);
        } catch (Exception e) {
            LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void shareSettleJD(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        /**
         * 处理分享赚
         */
        int sourceType = Constant.SOURCE_TYPE_JD;
        List<Integer> types = new ArrayList<>();
        // 查询UID的分享赚订单
        types.add(HongBaoV2.TYPE_SHARE_GOODS);
        long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType, maxPregetTime);
        List<HongBaoV2> hongBaoList = new ArrayList<>();
        // 1000条数据为1页
        int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
        for (int i = 0; i < page; i++) {
            List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
                    maxPregetTime, i * 1000, 1000);
            if (tempHongBaoList != null && tempHongBaoList.size() > 0)
                hongBaoList.addAll(tempHongBaoList);
        }
        OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
                null, null, new Date(), 0);
        Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
        String taskKey = getTaskKey(uid);
        msg.setKey(taskKey);
        // 添加事务消息
        try {
            orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
                @Override
                public TransactionStatus execute(Message arg0, Object arg1) {
                    fanLiShareOther(hongBaoList, uid, sourceType, taskKey,maxPregetTime);
                    return TransactionStatus.CommitTransaction;
                }
            }, null);
        } catch (Exception e) {
            LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void shareSettlePDD(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        shareSettle(Constant.SOURCE_TYPE_PDD, uid, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void shareSettleVipShop(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        shareSettle(Constant.SOURCE_TYPE_VIP, uid, maxPregetTime);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void shareSettleSuning(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        shareSettle(Constant.SOURCE_TYPE_SUNING, uid, maxPregetTime);
    }
    @Override
    public void shareSettleDY(Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        shareSettle(Constant.SOURCE_TYPE_DY, uid, maxPregetTime);
    }
    private void shareSettle(int sourceType, Long uid, Date maxPregetTime) throws OrderMoneySettleException {
        /**
         * 处理分享赚
         */
        List<Integer> types = new ArrayList<>();
        // 查询UID的分享赚订单
        types.add(HongBaoV2.TYPE_SHARE_GOODS);
        long count = hongBaoV2Mapper.countCanBalanceHongBaoByTypeAndUid(types, uid, sourceType, maxPregetTime);
        List<HongBaoV2> hongBaoList = new ArrayList<>();
        // 1000条数据为1页
        int page = (int) (count % 1000 == 0 ? count / 1000 : count / 1000 + 1);
        for (int i = 0; i < page; i++) {
            List<HongBaoV2> tempHongBaoList = hongBaoV2Mapper.listCanBalanceHongBaoByTypeAndUid(types, uid, sourceType,
                    maxPregetTime, i * 1000, 1000);
            if (tempHongBaoList != null && tempHongBaoList.size() > 0)
                hongBaoList.addAll(tempHongBaoList);
        }
        OrderMoneyRecievedMQMsg mqMsg = new OrderMoneyRecievedMQMsg(OrderMoneyRecievedMQMsg.TYPE_SHARE, uid, sourceType,
                null, null, new Date(), 0);
        Message msg = MQMsgBodyFactory.create(MQTopicName.TOPIC_ORDER, OrderTopicTagEnum.orderFanLiActual, mqMsg);
        String taskKey = getTaskKey(uid);
        msg.setKey(taskKey);
        // 添加事务消息
        try {
            orderTransactionProducer.send(msg, new LocalTransactionExecuter() {
                @Override
                public TransactionStatus execute(Message arg0, Object arg1) {
                    fanLiShareOther(hongBaoList, uid, sourceType, taskKey,maxPregetTime);
                    return TransactionStatus.CommitTransaction;
                }
            }, null);
        } catch (Exception e) {
            LogHelper.mqError(e.getMessage(), msg.getTopic(), msg.getTag(), new Gson().toJson(mqMsg));
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void ziGouSettle(String orderId, int sourceType, String taskKey) throws OrderMoneySettleException {
        // 查询同一订单号的红包
        List<CommonOrder> orderList = commonOrderService.listBySourceTypeAndOrderId(sourceType, orderId);
        List<HongBaoV2> hongBaoList = new ArrayList<>();
        Map<Long, BigDecimal> userMoney = new HashMap<>();
        Map<Long, List<HongBaoV2>> userHongBao = new HashMap<>();
        Map<Long, Integer> userGoodsCount = new HashMap<>();
        for (CommonOrder co : orderList) {
            HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByCommonOrderId(co.getId());
            if (hongBaoOrder == null) {
                continue;
            }
            hongBaoList.add(hongBaoOrder.getHongBaoV2());
            Long uid = co.getUserInfo().getId();
            if (userGoodsCount.get(uid) == null)
                userGoodsCount.put(uid, co.getCount());
            else
                userGoodsCount.put(uid, Integer.valueOf(co.getCount() + userGoodsCount.get(uid)));
        }
        for (HongBaoV2 hb : hongBaoList) {
            long currentTimeMillis = System.currentTimeMillis();
            if (hb.getState() != HongBao.STATE_SHIXIAO) {
                // 设置为已返利
                // 处理主红包
                if (hb.getState() != HongBaoV2.STATE_SHIXIAO && hb.getState() != HongBaoV2.STATE_YILINGQU
                        && hb.getType() == HongBaoV2.TYPE_ZIGOU) {
                    // 如果红包没被领取
                    Long uid = hb.getUserInfo().getId();
                    HongBaoV2 updateHongBao = new HongBaoV2();
                    updateHongBao.setId(hb.getId());
                    updateHongBao.setState(HongBaoV2.STATE_YILINGQU);
                    updateHongBao.setGetTime(new Date(currentTimeMillis));
                    hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
                    if (userMoney.get(uid) == null)
                        userMoney.put(uid, hb.getMoney());
                    else
                        userMoney.put(uid, userMoney.get(uid).add(hb.getMoney()));
                    // 添加红包到用户
                    if (userHongBao.get(uid) == null)
                        userHongBao.put(uid, new ArrayList<>());
                    userHongBao.get(uid).add(hb);
                }
            }
        }
        // 获取维权资金
        if (sourceType == Constant.SOURCE_TYPE_TAOBAO) {
            try {
                Map<Long, BigDecimal> userSubMoneyMap = taoBaoWeiQuanDrawBackService.doWeiQuanFanli(orderId, false);
                if (userSubMoneyMap != null) {
                    for (Iterator<Long> its = userMoney.keySet().iterator(); its.hasNext(); ) {
                        Long uid = its.next();
                        if (userSubMoneyMap.get(uid) != null) {
                            // 减去维权资金
                            userMoney.put(uid, userMoney.get(uid).subtract(userSubMoneyMap.get(uid)));
                        }
                    }
                }
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e);
                throw new OrderMoneySettleException(2, "维权订单出错");
            }
        }
        // if (userMoney.isEmpty()) {
        // throw new OrderMoneySettleException(1, "没有需要结算的订单");
        // }
        Iterator<Long> its = userMoney.keySet().iterator();
        while (its.hasNext()) {
            // 将自己添加到用户
            Long uid = its.next();
            BigDecimal money = userMoney.get(uid);
            UserMoneyDetail userMoneyDetail = null;
            // 插入新版资金明细
            try {
                // 此处不用订单号做唯一性索引
                userMoneyDetail = UserMoneyDetailFactory.createFanLi(uid, orderId, sourceType, null, money);
            } catch (UserMoneyDetailException e1) {
                try {
                    LogHelper.errorDetailInfo(e1, "订单号:" + orderId, "");
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            userMoneyService.addUserMoney(uid, money, userMoneyDetail);
            List<Long> hbIdList = new ArrayList<>();
            // 添加资金明细与红包的映射关系
            for (HongBaoV2 v2 : userHongBao.get(uid)) {
                hbIdList.add(v2.getId());
                accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(v2.getId(), userMoneyDetail.getId());
                try {
                    hongBaoRecieveCMQManager.addHongBaoRecieveMsg(v2.getId());
                } catch (Exception e) {
                    LogHelper.errorDetailInfo(e);
                }
            }
            // 添加结算映射
            hongBaoV2SettleTempService.addTemp(hbIdList, taskKey);
            // 站内信+推送
            UserInfo user = userInfoMapper.selectByPrimaryKey(uid);
            // 新版通知
            userMoneyMsgNotificationService.fanliOrderReceived(uid, orderId, sourceType, userGoodsCount.get(uid), money,
                    user.getMyHongBao(), orderList.get(0).getThirdCreateTime());
        }
        // 通知免单到账
        try {
            userSystemCouponService.updateStateByArrivalAccount(orderId, sourceType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 添加结算映射
    }
    private HongBaoV2 filterWeiQuanINGHongBao(HongBaoV2 hongBao) {
        long hbId = hongBao.getId();
        if (hongBao.getParent() != null) {
            hbId = hongBao.getParent().getId();
        }
        HongBaoOrder hongbaoOrder = hongBaoOrderMapper.selectByHongBaoId(hbId);
        if (hongbaoOrder == null)
            return null;
        List<TaoBaoWeiQuanOrder> taoBaoWeiQuanList = taoBaoWeiQuanOrderMapper
                .selectListByOrderIdAndState(hongbaoOrder.getCommonOrder().getOrderNo(), "维权创建");
        List<TaoBaoWeiQuanOrder> taoBaoWeiQuanList1 = taoBaoWeiQuanOrderMapper
                .selectListByOrderIdAndState(hongbaoOrder.getCommonOrder().getOrderNo(), "等待处理");
        if ((taoBaoWeiQuanList != null && taoBaoWeiQuanList.size() > 0)
                || (taoBaoWeiQuanList1 != null && taoBaoWeiQuanList1.size() > 0)) {
            return null;
        }
        return hongBao;
    }
    private void fanliInvite(List<HongBaoV2> hongBaoList, Long uid, int sourceType, String key, Date maxPreGetTime)
            throws TeamEincomeRecordException, ParamsException, TeamRewardDebtException {
        logger.info("邀请奖金预到账:uid-{} sourceType-{} key-{}", new Object[]{uid, sourceType, key});
        List<Long> hbIdList = new ArrayList<>();
        BigDecimal invitemoney = new BigDecimal(0);
        Set<String> inviteOrders = new HashSet<>();
        // 需要判断退款的订单号
        for (HongBaoV2 hongBao : hongBaoList) {
            hongBao = filterWeiQuanINGHongBao(hongBao);
            if (hongBao == null)
                continue;
            hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
            if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
                logger.info("邀请奖金预到账-每个红包-到账开始:hongbaoid-{}", hongBao.getId());
                TeamRewardDebt debt = teamRewardDebtService.selectBySourceId(hongBao.getId());
                BigDecimal money = hongBao.getMoney();
                if (debt != null && debt.getLeftMoney().compareTo(new BigDecimal(0)) > 0
                        && money.compareTo(debt.getLeftMoney()) >= 0) {
                    money = money.subtract(debt.getLeftMoney());
                    // 还钱
                    teamRewardDebtService.repayDebt(debt.getId(), debt.getLeftMoney(), null);
                    logger.info("邀请奖金预到账-每个红包-还款:hongbaoid-{} debtId-{} debtMoney-{}", new Object[]{hongBao.getId(), debt.getId(), debt.getLeftMoney()});
                }
                logger.info("邀请奖金预到账-每个红包:hongbaoid-{} money-{}", new Object[]{hongBao.getId(), money});
                invitemoney = invitemoney.add(money);
                HongBaoV2 updateHongBao = new HongBaoV2();
                updateHongBao.setId(hongBao.getId());
                updateHongBao.setGetTime(new Date());
                updateHongBao.setState(HongBaoV2.STATE_LINGQUING);
                updateHongBao.setUpdateTime(new Date());
                hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
                // 添加到红包返利记录集合
                hbIdList.add(hongBao.getId());
                HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getParent().getId());
                inviteOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
                logger.info("邀请奖金预到账-每个红包-到账成功:hongbaoid-{}", hongBao.getId());
            }
        }
        // 邀请赚到账
        if (invitemoney.compareTo(new BigDecimal(0)) > 0) {
            // 获取当前的月份
            teamRewardManager.addToEincome(uid, maxPreGetTime, invitemoney, sourceType);
            logger.info("邀请奖金预到账-添加到团队收益成功:uid-{} day-{} money-{} sourceType-{}", new Object[]{uid, maxPreGetTime, invitemoney, sourceType});
        }
        hongBaoV2SettleTempService.addTemp(hbIdList, key);
        // 所有的返利到账红包ID
        for (Long hongBaoId : hbIdList) {
            try {
                if (Constant.ENABLE_MQ)
                    hongBaoRecieveCMQManager.addHongBaoRecieveMsg(hongBaoId);
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e);
            }
        }
    }
    /**
     * 淘宝分享赚返利
     *
     * @param hongBaoList
     * @param uid
     * @throws TaoBaoWeiQuanException
     */
    private void fanLiShareTB(List<HongBaoV2> hongBaoList, Long uid, String key,Date recieveMonth) throws TaoBaoWeiQuanException {
        BigDecimal sharemoney = new BigDecimal(0);
        List<Long> hbIdList = new ArrayList<>();
        Set<String> drawBackOrders = new HashSet<String>();
        List<Long> recieveHongBaoIds = new ArrayList<>();
        Set<String> shareOrders = new HashSet<>();
        for (HongBaoV2 hongBao : hongBaoList) {
            hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
            hongBao = filterWeiQuanINGHongBao(hongBao);
            if (hongBao == null)
                continue;
            if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
                sharemoney = sharemoney.add(hongBao.getMoney());
                HongBaoV2 updateHongBao = new HongBaoV2();
                updateHongBao.setId(hongBao.getId());
                updateHongBao.setGetTime(new Date());
                updateHongBao.setState(HongBao.STATE_YILINGQU);
                updateHongBao.setUpdateTime(new Date());
                hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
                // 添加到红包返利记录集合
                hbIdList.add(hongBao.getId());
                // 2018-08-05 过后的订单才处理维权
                Date balanceTime = null;
                HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getId());
                if (hongBaoOrder != null) {
                    balanceTime = hongBaoOrder.getCommonOrder().getSettleTime();
                }
                shareOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
                if (balanceTime != null
                        && balanceTime.getTime() >= TimeUtil.convertToTimeTemp("2018-08-05", "yyyy-MM-dd")) {
                    drawBackOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
                }
            }
        }
        /**
         * 分享赚到账
         */
        if (sharemoney.compareTo(new BigDecimal(0)) > 0) {
            // 添加新版详情记录
            try {
                UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createShare(uid, Constant.SOURCE_TYPE_TAOBAO,
                        sharemoney,recieveMonth);
                // 添加资金
                userMoneyService.addUserMoney(uid, sharemoney, userMoneyDetail);
                // 添加到红包返利记录集合
                accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
                if (hbIdList.size() > 0)
                    recieveHongBaoIds.addAll(hbIdList);
            } catch (UserMoneyDetailException e) {
                try {
                    LogHelper.errorDetailInfo(e);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            // 新版通知
            userMoneyMsgNotificationService.shareOrderReceived(uid, Constant.SOURCE_TYPE_TAOBAO, sharemoney,
                    userInfoMapper.selectAvailableByPrimaryKey(uid).getMyHongBao(), new Date());
            for (String orderId : drawBackOrders)
                taoBaoWeiQuanDrawBackService.doWeiQuanShare(orderId);
        }
        hongBaoV2SettleTempService.addTemp(recieveHongBaoIds, key);
        // 所有的返利到账红包ID
        for (Long hongBaoId : recieveHongBaoIds) {
            try {
                if (Constant.ENABLE_MQ)
                    hongBaoRecieveCMQManager.addHongBaoRecieveMsg(hongBaoId);
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e);
            }
        }
    }
    /**
     * 其他平台分享赚返利
     *
     * @param hongBaoList
     * @param uid
     * @param sourceType
     */
    private void fanLiShareOther(List<HongBaoV2> hongBaoList, Long uid, int sourceType, String key,Date recieveMonth) {
        BigDecimal sharemoney = new BigDecimal(0);
        List<Long> hbIdList = new ArrayList<>();
        List<Long> recieveHongBaoIds = new ArrayList<>();
        Set<String> shareOrders = new HashSet<>();
        for (HongBaoV2 hongBao : hongBaoList) {
            hongBao = hongBaoV2Mapper.selectByPrimaryKeyForUpdate(hongBao.getId());
            hongBao = filterWeiQuanINGHongBao(hongBao);
            if (hongBao == null)
                continue;
            if (hongBao.getState() == HongBaoV2.STATE_BUKELINGQU || hongBao.getState() == HongBaoV2.STATE_KELINGQU) {
                sharemoney = sharemoney.add(hongBao.getMoney());
                HongBaoV2 updateHongBao = new HongBaoV2();
                updateHongBao.setId(hongBao.getId());
                updateHongBao.setGetTime(new Date());
                updateHongBao.setState(HongBao.STATE_YILINGQU);
                updateHongBao.setUpdateTime(new Date());
                hongBaoV2Mapper.updateByPrimaryKeySelective(updateHongBao);
                // 添加到红包返利记录集合
                hbIdList.add(hongBao.getId());
                // 2018-08-05 过后的订单才处理维权
                HongBaoOrder hongBaoOrder = hongBaoOrderMapper.selectByHongBaoId(hongBao.getId());
                shareOrders.add(hongBaoOrder.getCommonOrder().getOrderNo());
            }
        }
        /**
         * 分享赚到账
         */
        if (sharemoney.compareTo(new BigDecimal(0)) > 0) {
            // 添加新版详情记录
            try {
                UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createShare(uid, sourceType, sharemoney,
                        recieveMonth);
                // 添加资金
                userMoneyService.addUserMoney(uid, sharemoney, userMoneyDetail);
                // 添加到红包返利记录集合
                accountDetailsHongBaoMapService.saveAccountDetailsHongBaoMap(hbIdList, userMoneyDetail.getId());
                if (hbIdList.size() > 0)
                    recieveHongBaoIds.addAll(hbIdList);
            } catch (UserMoneyDetailException e) {
                try {
                    LogHelper.errorDetailInfo(e);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            userMoneyMsgNotificationService.shareOrderReceived(uid, sourceType, sharemoney,
                    userInfoMapper.selectAvailableByPrimaryKey(uid).getMyHongBao(), new Date());
        }
        hongBaoV2SettleTempService.addTemp(recieveHongBaoIds, key);
        // 所有的返利到账红包ID
        for (Long hongBaoId : recieveHongBaoIds) {
            try {
                if (Constant.ENABLE_MQ)
                    hongBaoRecieveCMQManager.addHongBaoRecieveMsg(hongBaoId);
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e);
            }
        }
    }
    private String getTaskKey(Long uid) {
        return uid + "-" + UUID.randomUUID().toString();
    }
}