admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/service/impl/redpack/RedPackWinInviteServiceImpl.java
@@ -1,749 +1,758 @@
package com.yeshi.fanli.service.impl.redpack;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.redpack.RedPackWinInviteMapper;
import com.yeshi.fanli.dto.msg.MsgRedPackTeamRewardContentDTO;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail.MsgTypeMoneyTypeEnum;
import com.yeshi.fanli.entity.bus.user.ThreeSale;
import com.yeshi.fanli.entity.bus.user.UserActiveLog;
import com.yeshi.fanli.entity.bus.user.UserExtraTaoBaoInfo;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfoRegister;
import com.yeshi.fanli.entity.bus.user.UserSystemCoupon;
import com.yeshi.fanli.entity.order.CommonOrder;
import com.yeshi.fanli.entity.redpack.RedPackDetail;
import com.yeshi.fanli.entity.redpack.RedPackWinInvite;
import com.yeshi.fanli.entity.redpack.RedPackWinInvite.RedPackWinInviteTypeEnum;
import com.yeshi.fanli.entity.system.SystemCoupon.CouponTypeEnum;
import com.yeshi.fanli.exception.user.UserSystemCouponException;
import com.yeshi.fanli.service.inter.count.HongBaoV2CountService;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.order.CommonOrderGoodsService;
import com.yeshi.fanli.service.inter.order.CommonOrderService;
import com.yeshi.fanli.service.inter.redpack.RedPackBalanceService;
import com.yeshi.fanli.service.inter.redpack.RedPackConfigService;
import com.yeshi.fanli.service.inter.redpack.RedPackWinInviteService;
import com.yeshi.fanli.service.inter.user.UserActiveLogService;
import com.yeshi.fanli.service.inter.user.UserInfoRegisterService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.UserSystemCouponService;
import com.yeshi.fanli.service.inter.user.integral.IntegralTaskRecordService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.user.tb.UserExtraTaoBaoInfoService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.VersionUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.annotation.redpack.RedPackGetVersionLimit;
import com.yeshi.fanli.util.factory.RedPackDetailFactory;
import com.yeshi.fanli.vo.redpack.RedPackWinProgressVO;
@Service
public class RedPackWinInviteServiceImpl implements RedPackWinInviteService {
   @Resource
   private RedPackWinInviteMapper redPackWinInviteMapper;
   @Resource
   private RedPackConfigService redPackConfigService;
   @Resource
   private RedPackBalanceService redPackBalanceService;
   @Resource
   private CommonOrderService commonOrderService;
   @Resource
   private ThreeSaleSerivce threeSaleSerivce;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Resource
   private UserInfoService userInfoService;
   @Resource
   private UserInfoRegisterService userInfoRegisterService;
   @Resource
   private UserExtraTaoBaoInfoService userExtraTaoBaoInfoService;
   @Resource
   private IntegralTaskRecordService integralTaskRecordService;
   @Resource
   private UserActiveLogService userActiveLogService;
   @Resource
   private HongBaoV2CountService hongBaoV2CountService;
   @Resource
   private CommonOrderGoodsService commonOrderGoodsService;
   @Resource
   private UserSystemCouponService userSystemCouponService;
   @Override
   public List<RedPackWinInvite> getRewardList(int start, int count, Long uid) {
      return redPackWinInviteMapper.getRewardList(start, count, uid);
   }
   @Override
   public Long countRewardRecord(Long uid) {
      return redPackWinInviteMapper.countRewardRecord(uid);
   }
   @Override
   public BigDecimal getRewardMoney(Long uid) {
      return redPackWinInviteMapper.getRewardMoney(uid);
   }
   @Override
   @RequestSerializableByKeyService(key = "#teamUid")
   @Transactional(rollbackFor = Exception.class)
   public void initCreateRedPackWin(Long bossId, Long teamUid) {
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      // 小于2.0.5版本不增加
      if (!VersionUtil.greaterThan_2_0_5("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      // 同一队员只记录一次
      int totalReward = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.zeroStageReward.name());
      if (totalReward > 0)
         return;
      // 获得红包
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(new BigDecimal(0));
      winInvite.setType(RedPackWinInviteTypeEnum.zeroStageReward);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.zeroStageReward.name() + ":" + teamUid));
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      redPackWinInviteMapper.insertSelective(winInvite);
   }
   @Override
   @RequestSerializableByKeyService(key = "#teamUid")
   @Transactional(rollbackFor = Exception.class)
   public void inviteSucceedReward(Long teamUid) throws Exception {
      // 是否在上线之后的邀请关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerIdAndTime(teamUid,
            TimeUtil.convertDateToTemp(Constant.RED_PACK_ONLINE_TIME));
      if (threeSale == null)
         return;
      // 上级id
      Long bossId = threeSale.getBoss().getId();
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      // 小于2.0.2版本不增加
      if (!VersionUtil.greaterThan_2_0_5("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      int totalRewardZero = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.zeroStageReward.name());
      if (totalRewardZero <= 0)
         return;
      // 同一队员奖励一次
      int totalReward = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.oneStageReward.name());
      if (totalReward > 0)
         return;
      // 建立邀请关系时间超过20天
      Long succeedTime = threeSale.getSucceedTime();
      Date endDate = DateUtil.plusDayDate(Constant.ONE_STAGE_LIMIT_DAYS, new Date(succeedTime));
      if (endDate.getTime() < java.lang.System.currentTimeMillis())
         return;
      // 绑定电话号码和微信
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      if (userInfo == null || StringUtil.isNullOrEmpty(userInfo.getPhone())
            || StringUtil.isNullOrEmpty(userInfo.getWxOpenId()))
         return;
      // 授权淘宝
      UserExtraTaoBaoInfo taoBaoInfo = userExtraTaoBaoInfoService.getByUid(teamUid);
      if (taoBaoInfo == null || StringUtil.isNullOrEmpty(taoBaoInfo.getTaoBaoUid()))
         return;
      // 好友产生一笔返利订单(自购)且 24 小时内不失效;
      long validOrder = commonOrderService.count24HValidOrderByUid(teamUid, new Date(succeedTime));
      if (validOrder < 1)
         return;
      // 奖励金额
      BigDecimal money = Constant.ONE_STAGE_MONEY;
      // 获得红包
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.oneStageReward);
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.oneStageReward.name() + ":" + teamUid));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createInvite(winInvite));
      // 消息
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackOneStageReward, money,
            "粉丝(好友)完成第一阶段", new Gson().toJson(dto));
   }
   @RequestSerializableByKeyService(key = "#uid")
   @RedPackGetVersionLimit(uid = "#uid")
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteOrderArriveReward(Long uid, Integer source, String orderNo) throws Exception {
      if (uid == null || source == null || StringUtil.isNullOrEmpty(orderNo))
         return;
      // 获取订单对应下单人
      List<CommonOrder> list = commonOrderService.listBySourceTypeAndOrderId(source, orderNo);
      if (list == null || list.isEmpty())
         return;
      CommonOrder commonOrder = list.get(0);
      if (commonOrder == null || commonOrder.getUserInfo() == null)
         return;
      // 下单人id
      Long teamUid = commonOrder.getUserInfo().getId();
      if (teamUid == null)
         return;
      // 验证上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerIdAndTime(teamUid,
            TimeUtil.convertDateToTemp(Constant.RED_PACK_ONLINE_TIME));
      if (threeSale == null || threeSale.getBoss().getId().longValue() != uid.longValue())
         return;
      // 第一阶段(验证)
      RedPackWinInvite oneStage = redPackWinInviteMapper.getByUidAndTeamUidAndType(uid, teamUid,
            RedPackWinInviteTypeEnum.oneStageReward.name());
      if (oneStage == null)
         return;
      // 第二阶段(验证)
      RedPackWinInvite twoStage = redPackWinInviteMapper.getByUidAndTeamUidAndType(uid, teamUid,
            RedPackWinInviteTypeEnum.twoStageReward.name());
      if (twoStage == null) {
         twoStageRewardToBoss(uid, teamUid, oneStage.getCreateTime(), source, orderNo);
         return;
      }
      // 第三阶段
      threeStageRewardToBoss(uid, teamUid, twoStage.getCreateTime(), source, orderNo);
   }
   /**
    * 上级奖励--第二阶段
    *
    * @param uid
    * @param source
    * @param orderNo
    * @param bossId
    */
   @Transactional(rollbackFor = Exception.class)
   private void twoStageRewardToBoss(Long bossId, Long teamUid, Date oneStageTime, Integer source, String orderNo)
         throws Exception {
      // 第一阶段完成之后的90天内 ; 队友产生的订单中(自购+分享),邀请人累计产生≥1 元奖金
      Date endDate = DateUtil.plusDayDate(Constant.TWO_STAGE_LIMIT_DAYS, oneStageTime);
      // 统计订单奖金 (“好友自购”和“好友分享”)
      BigDecimal rewardMoney = hongBaoV2CountService.getOrderRewardByTeamUid(bossId, teamUid, endDate);
      if (rewardMoney == null || rewardMoney.compareTo(Constant.TWO_STAGE_ORDER_REWARD_MIN) < 0)
         return;
      // 计算奖励
      BigDecimal money = Constant.TWO_STAGE_MONEY_MIN;
      long total = redPackWinInviteMapper.countByUidAndType(bossId, RedPackWinInviteTypeEnum.twoStageReward.name());
      if (total > 0 && total < Constant.TWO_STAGE_MONEY_ADD_NUM) {
         long num = total % Constant.TWO_STAGE_MONEY_ADD_NUM;
         money = MoneyBigDecimalUtil.add(money,
               MoneyBigDecimalUtil.mul(Constant.TWO_STAGE_MONEY_ADD, new BigDecimal(num)));
      }
      // 获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.twoStageReward);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.twoStageReward.name() + ":" + teamUid));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 4、增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createIncreaseReward(winInvite));
      // 5、消息
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackTwoStageReward, money,
            "粉丝(好友)完成第二阶段", new Gson().toJson(dto));
   }
   /**
    * 上级奖励:次月开始产生满足条件的分享订单(分享订单实付款≥10元) 连续15个月 自然月获得(已到账)每月最高2元
    *
    * @param uid
    * @param source
    * @param orderNo
    * @param bossId
    */
   @Transactional(rollbackFor = Exception.class)
   private void threeStageRewardToBoss(Long bossId, Long teamUid, Date twoStageTime, Integer source, String orderNo)
         throws Exception {
      // 二、三阶段不可同月
      if (DateUtil.isSameMonth(twoStageTime, new Date()))
         return;
      // 是否已领取本月
      RedPackWinInvite threeStage = redPackWinInviteMapper.getByUidAndTeamUidAndTypeMonth(bossId, teamUid,
            RedPackWinInviteTypeEnum.threeStageReward.name());
      if (threeStage != null)
         return;
      // 已奖励次数
      int totalNum = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.threeStageReward.name());
      if (totalNum >= Constant.THREE_STAGE_REWARD_MONTH)
         return;
      // 是否已间断
      int monthSpace = DateUtil.getMonthSpace(twoStageTime, new Date());
      if (monthSpace != totalNum + 1)
         return;
      // 统计本月获得奖金 (“好友自购”和“好友分享”)
      BigDecimal rewardMoney = hongBaoV2CountService.getOrderRewardByTeamUidTheMonth(bossId, teamUid);
      if (rewardMoney == null || rewardMoney.compareTo(Constant.THREE_STAGE_ORDER_REWARD_MIN) < 0)
         return;
      // 计算随机奖励
      double randomMoney = Constant.THREE_STAGE_RANDOM_MIN
            + Math.random() * (Constant.THREE_STAGE_RANDOM_MAX - Constant.THREE_STAGE_RANDOM_MIN);
      // 保留两位小数
      BigDecimal money = new BigDecimal(randomMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
      // 3、获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.threeStageReward);
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setIdentifyCode(
            StringUtil.Md5(RedPackWinInviteTypeEnum.threeStageReward.name() + ":" + teamUid + "-" + monthSpace));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 4、增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createSeriesReward(winInvite));
      // 消息
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackThreeStageReward,
            money, "粉丝(好友)完成第三阶段连续[第" + monthSpace + "个月]", new Gson().toJson(dto));
   }
   @Override
   public List<RedPackWinProgressVO> getInviteProgressByWorkerId(Long uid, Long tid) {
      List<RedPackWinProgressVO> listVO = new ArrayList<RedPackWinProgressVO>();
      ThreeSale threeSale = threeSaleSerivce.getNearRelationByBossIdAndWorkerId(uid, tid);
      if (threeSale == null || threeSale.getSucceedTime() == null)
         return listVO;
      UserInfo userInfo = userInfoService.selectByPKey(tid);
      if (userInfo == null)
         return listVO;
      // 奖励记录
      List<RedPackWinInvite> listWin = redPackWinInviteMapper.getWinListByBossIdAndTeamUid(uid, tid);
      if (listWin == null || listWin.size() == 0)
         return listVO;
      int month = 1;
      for (RedPackWinInvite win : listWin) {
         if (win.getType() == RedPackWinInviteTypeEnum.zeroStageReward) {
            listVO.add(new RedPackWinProgressVO("成功注册", TimeUtil.formatDate(userInfo.getCreatetime())));
            listVO.add(new RedPackWinProgressVO("确立邀请", TimeUtil.formatDate(threeSale.getSucceedTime())));
         }
         String time = TimeUtil.formatDate(win.getCreateTime());
         BigDecimal money = win.getMoney().setScale(2);
         if (win.getType() == RedPackWinInviteTypeEnum.oneStageReward) {
            listVO.add(new RedPackWinProgressVO("第一阶段", time, money.toString()));
            continue;
         }
         if (win.getType() == RedPackWinInviteTypeEnum.twoStageReward) {
            listVO.add(new RedPackWinProgressVO("第二阶段", time, money.toString()));
            continue;
         }
         if (win.getType() == RedPackWinInviteTypeEnum.threeStageReward) {
            listVO.add(new RedPackWinProgressVO("第三阶段第" + month + "个月", time, money.toString()));
            month++;
            continue;
         }
      }
      return listVO;
   }
   @Override
   public List<RedPackWinInvite> getWinTopListByBossId(int page, int count, Long uid) {
      return redPackWinInviteMapper.getWinTopListByBossId(count * (page - 1), count, uid);
   }
   @Override
   public long countWinTopListByBossId(Long uid) {
      return redPackWinInviteMapper.countWinTopListByBossId(uid);
   }
   @Override
   public long countTeamNumByTid(Long uid, Long teamUid) {
      return redPackWinInviteMapper.countTeamNumByTid(uid, teamUid);
   }
   @Override
   public List<RedPackWinInvite> query(long page, int count, String key, String type){
      return redPackWinInviteMapper.query(count * (page - 1), count, key, type);
   }
   @Override
   public long count(String key, String type){
      Long count = redPackWinInviteMapper.count(key, type);
      if (count == null) {
         count = 0L;
      }
      return count;
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   @Transactional(rollbackFor = Exception.class)
   public void winRedPackByOrder(Long orderUid, String orderNo, Integer source) {
      if (orderUid == null || StringUtil.isNullOrEmpty(orderNo)) {
         return;
      }
      // 验证是否未首单
      CommonOrder firstOrder = commonOrderService.getFirstOrder(orderUid);
      if (!firstOrder.getOrderNo().equals(orderNo) && firstOrder.getSourceType() != source)
         return;
      Date downTime = firstOrder.getThirdCreateTime();
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return;
      long registerTime = register.getCreateTime().getTime();
      // 注册48小时内下单限制
      if (downTime.getTime() < registerTime || downTime.getTime() > registerTime + 1000*60*60*48)
         return;
      // 是否存在上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerId(orderUid);
      if (threeSale == null)
         return;
      Long bossId = threeSale.getBoss().getId();
      if (bossId == null)
         return;
      // 该邀请是否已添加
      RedPackWinInvite threeStage = redPackWinInviteMapper.getByUidAndTeamUid(bossId, orderUid);
      if (threeStage != null)
         return;
      // 小于2.1.3版本不增加
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      if (!VersionUtil.greaterThan_2_1_3("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0) {
         return;
      }
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
       boolean satisfy = false;
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 订单未结算
         if(commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 邀请关系之后
         long thirdTime = commonOrder.getThirdCreateTime().getTime();
         if (thirdTime < threeSale.getCreateTime())
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) < 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete = MoneyBigDecimalUtil.div(eIncome, settlement);
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      if (!satisfy) {
         return;
      }
      // 获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(orderUid);
      winInvite.setMoney(null);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.inviteDownOrder);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.inviteDownOrder.name() + ":" + orderUid));
      redPackWinInviteMapper.insertSelective(winInvite);
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   public boolean verifyOrder(Long orderUid, String orderNo, Integer source, Date downTime) {
       boolean satisfy = false;
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return satisfy;
      // 注册48小时 以内:新人
      long registerTime = register.getCreateTime().getTime();
      // 48小时限制
      if (downTime.getTime() < registerTime || downTime.getTime() > registerTime + 1000*60*60*48)
         return satisfy;
      CommonOrder firstOrder = commonOrderService.getFirstOrder(orderUid);
      if (!firstOrder.getOrderNo().equals(orderNo) && firstOrder.getSourceType() != source)
         return satisfy;
      // 是否已奖励
      List<UserSystemCoupon> coupons = userSystemCouponService.getUserCouponBySource(orderUid, UserSystemCoupon.SOURCE_PULL_NEW);
      if (coupons != null && coupons.size() > 0) {
         return satisfy;
      }
      // 是否存在上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerId(orderUid);
      if (threeSale == null)
         return satisfy;
      Long bossId = threeSale.getBoss().getId();
      if (bossId == null)
         return satisfy;
      // 小于2.1.3版本不增加
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(orderUid);
      if (activeLog == null)
         return satisfy;
      if (!VersionUtil.greaterThan_2_1_3("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return satisfy;
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0)
         return satisfy;
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 邀请关系之后
         long thirdTime = commonOrder.getThirdCreateTime().getTime();
         if (thirdTime < threeSale.getCreateTime())
            continue;
         // 订单失效
         if(commonOrder.getState() != CommonOrder.STATE_FK && commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) < 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete = MoneyBigDecimalUtil.div(eIncome, settlement);
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      return satisfy;
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   @Transactional(rollbackFor = Exception.class)
   public void winFreeCoupon(Long orderUid, String orderNo, Integer source, Date downTime) {
      if (orderUid == null || StringUtil.isNullOrEmpty(orderNo)) {
         return;
      }
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return;
      // 注册48小时 以内:新人
      long registerTime = register.getCreateTime().getTime();
      // 48小时限制
      if (downTime.getTime() < registerTime || downTime.getTime() > registerTime + 1000*60*60*48)
         return;
      // 是否已奖励
      List<UserSystemCoupon> coupons = userSystemCouponService.getUserCouponBySource(orderUid, UserSystemCoupon.SOURCE_PULL_NEW);
      if (coupons != null && coupons.size() > 0) {
         return;
      }
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0) {
         return;
      }
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
       boolean satisfy = false;
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 订单失效
         if(commonOrder.getState() != CommonOrder.STATE_FK && commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) < 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete = MoneyBigDecimalUtil.div(eIncome, settlement);
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      if (!satisfy) {
         return;
      }
      // 赠送购买者一张免单券
      try {
         userSystemCouponService.freeCouponWinBySystem(orderUid, CouponTypeEnum.freeCoupon,
               UserSystemCoupon.SOURCE_PULL_NEW, 1, true, 2, 1);
      } catch (UserSystemCouponException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   @Override
   public List<Long> listWinUid(int start, int count) {
      return redPackWinInviteMapper.listWinUid(start, count);
   }
   @Override
   public List<RedPackWinInvite> listLastMonthByUid(int start, int count, Long uid) {
      return redPackWinInviteMapper.listLastMonthByUid(start, count, uid);
   }
   @Override
   public long countLastMonthByUid(Long uid) {
      Long count = redPackWinInviteMapper.countLastMonthByUid(uid);
      if (count == null)
         count = 0L;
      return count;
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void arriveMoney(Long uid, BigDecimal money, Date date) throws Exception {
      RedPackDetail detail = RedPackDetailFactory.createByMonth(uid, money, date);
      redPackBalanceService.addRedPack(uid, money, detail);
   }
}
package com.yeshi.fanli.service.impl.redpack;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.redpack.RedPackWinInviteMapper;
import com.yeshi.fanli.dto.msg.MsgRedPackTeamRewardContentDTO;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail.MsgTypeMoneyTypeEnum;
import com.yeshi.fanli.entity.bus.user.ThreeSale;
import com.yeshi.fanli.entity.bus.user.UserActiveLog;
import com.yeshi.fanli.entity.bus.user.UserExtraTaoBaoInfo;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfoRegister;
import com.yeshi.fanli.entity.bus.user.UserSystemCoupon;
import com.yeshi.fanli.entity.order.CommonOrder;
import com.yeshi.fanli.entity.redpack.RedPackDetail;
import com.yeshi.fanli.entity.redpack.RedPackWinInvite;
import com.yeshi.fanli.entity.redpack.RedPackWinInvite.RedPackWinInviteTypeEnum;
import com.yeshi.fanli.entity.system.SystemCoupon.CouponTypeEnum;
import com.yeshi.fanli.exception.user.UserSystemCouponException;
import com.yeshi.fanli.service.inter.count.HongBaoV2CountService;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.order.CommonOrderGoodsService;
import com.yeshi.fanli.service.inter.order.CommonOrderService;
import com.yeshi.fanli.service.inter.redpack.RedPackBalanceService;
import com.yeshi.fanli.service.inter.redpack.RedPackConfigService;
import com.yeshi.fanli.service.inter.redpack.RedPackWinInviteService;
import com.yeshi.fanli.service.inter.user.UserActiveLogService;
import com.yeshi.fanli.service.inter.user.UserInfoRegisterService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.UserSystemCouponService;
import com.yeshi.fanli.service.inter.user.integral.IntegralTaskRecordService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.user.invite.UserInviteMsgNotificationService;
import com.yeshi.fanli.service.inter.user.tb.UserExtraTaoBaoInfoService;
import com.yeshi.fanli.util.Constant;
import org.yeshi.utils.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.StringUtil;
import org.yeshi.utils.TimeUtil;
import com.yeshi.fanli.util.VersionUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.annotation.redpack.RedPackGetVersionLimit;
import com.yeshi.fanli.util.factory.RedPackDetailFactory;
import com.yeshi.fanli.vo.redpack.RedPackWinProgressVO;
@Service
public class RedPackWinInviteServiceImpl implements RedPackWinInviteService {
   @Resource
   private RedPackWinInviteMapper redPackWinInviteMapper;
   @Resource
   private RedPackConfigService redPackConfigService;
   @Resource
   private RedPackBalanceService redPackBalanceService;
   @Resource
   private CommonOrderService commonOrderService;
   @Resource
   private ThreeSaleSerivce threeSaleSerivce;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Resource
   private UserInfoService userInfoService;
   @Resource
   private UserInfoRegisterService userInfoRegisterService;
   @Resource
   private UserExtraTaoBaoInfoService userExtraTaoBaoInfoService;
   @Resource
   private IntegralTaskRecordService integralTaskRecordService;
   @Resource
   private UserActiveLogService userActiveLogService;
   @Resource
   private HongBaoV2CountService hongBaoV2CountService;
   @Resource
   private CommonOrderGoodsService commonOrderGoodsService;
   @Resource
   private UserSystemCouponService userSystemCouponService;
   @Resource
   private UserInviteMsgNotificationService userInviteMsgNotificationService;
   @Override
   public List<RedPackWinInvite> getRewardList(int start, int count, Long uid) {
      return redPackWinInviteMapper.getRewardList(start, count, uid);
   }
   @Override
   public Long countRewardRecord(Long uid) {
      return redPackWinInviteMapper.countRewardRecord(uid);
   }
   @Override
   public BigDecimal getRewardMoney(Long uid) {
      return redPackWinInviteMapper.getRewardMoney(uid);
   }
   @Override
   @RequestSerializableByKeyService(key = "#teamUid")
   @Transactional(rollbackFor = Exception.class)
   public void initCreateRedPackWin(Long bossId, Long teamUid) {
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      // 小于2.0.5版本不增加
      if (!VersionUtil.greaterThan_2_0_5("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      // 同一队员只记录一次
      int totalReward = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.zeroStageReward.name());
      if (totalReward > 0)
         return;
      // 获得红包
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(new BigDecimal(0));
      winInvite.setType(RedPackWinInviteTypeEnum.zeroStageReward);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.zeroStageReward.name() + ":" + teamUid));
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      redPackWinInviteMapper.insertSelective(winInvite);
   }
   @Override
   @RequestSerializableByKeyService(key = "#teamUid")
   @Transactional(rollbackFor = Exception.class)
   public void inviteSucceedReward(Long teamUid) throws Exception {
      // 是否在上线之后的邀请关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerIdAndTime(teamUid,
            TimeUtil.convertDateToTemp(Constant.RED_PACK_ONLINE_TIME));
      if (threeSale == null)
         return;
      // 上级id
      Long bossId = threeSale.getBoss().getId();
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      // 小于2.0.2版本不增加
      if (!VersionUtil.greaterThan_2_0_5("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      int totalRewardZero = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.zeroStageReward.name());
      if (totalRewardZero <= 0)
         return;
      // 同一队员奖励一次
      int totalReward = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.oneStageReward.name());
      if (totalReward > 0)
         return;
      // 建立邀请关系时间超过20天
      Long succeedTime = threeSale.getSucceedTime();
      Date endDate = DateUtil.plusDayDate(Constant.ONE_STAGE_LIMIT_DAYS, new Date(succeedTime));
      if (endDate.getTime() < java.lang.System.currentTimeMillis())
         return;
      // 绑定电话号码和微信
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      if (userInfo == null || StringUtil.isNullOrEmpty(userInfo.getPhone())
            || StringUtil.isNullOrEmpty(userInfo.getWxOpenId()))
         return;
      // 授权淘宝
      UserExtraTaoBaoInfo taoBaoInfo = userExtraTaoBaoInfoService.getByUid(teamUid);
      if (taoBaoInfo == null || StringUtil.isNullOrEmpty(taoBaoInfo.getTaoBaoUid()))
         return;
      // 好友产生一笔返利订单(自购)且 24 小时内不失效;
      long validOrder = commonOrderService.count24HValidOrderByUid(teamUid, new Date(succeedTime));
      if (validOrder < 1)
         return;
      // 奖励金额
      BigDecimal money = Constant.ONE_STAGE_MONEY;
      // 获得红包
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.oneStageReward);
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.oneStageReward.name() + ":" + teamUid));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createInvite(winInvite));
      // 消息
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackOneStageReward, money,
            "粉丝(好友)完成第一阶段", new Gson().toJson(dto));
   }
   @RequestSerializableByKeyService(key = "#uid")
   @RedPackGetVersionLimit(uid = "#uid")
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void inviteOrderArriveReward(Long uid, Integer source, String orderNo) throws Exception {
      if (uid == null || source == null || StringUtil.isNullOrEmpty(orderNo))
         return;
      // 获取订单对应下单人
      List<CommonOrder> list = commonOrderService.listBySourceTypeAndOrderId(source, orderNo);
      if (list == null || list.isEmpty())
         return;
      CommonOrder commonOrder = list.get(0);
      if (commonOrder == null || commonOrder.getUserInfo() == null)
         return;
      // 下单人id
      Long teamUid = commonOrder.getUserInfo().getId();
      if (teamUid == null)
         return;
      // 验证上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerIdAndTime(teamUid,
            TimeUtil.convertDateToTemp(Constant.RED_PACK_ONLINE_TIME));
      if (threeSale == null || threeSale.getBoss().getId().longValue() != uid.longValue())
         return;
      // 第一阶段(验证)
      RedPackWinInvite oneStage = redPackWinInviteMapper.getByUidAndTeamUidAndType(uid, teamUid,
            RedPackWinInviteTypeEnum.oneStageReward.name());
      if (oneStage == null)
         return;
      // 第二阶段(验证)
      RedPackWinInvite twoStage = redPackWinInviteMapper.getByUidAndTeamUidAndType(uid, teamUid,
            RedPackWinInviteTypeEnum.twoStageReward.name());
      if (twoStage == null) {
         twoStageRewardToBoss(uid, teamUid, oneStage.getCreateTime(), source, orderNo);
         return;
      }
      // 第三阶段
      threeStageRewardToBoss(uid, teamUid, twoStage.getCreateTime(), source, orderNo);
   }
   /**
    * 上级奖励--第二阶段
    *
    * @param uid
    * @param source
    * @param orderNo
    * @param bossId
    */
   @Transactional(rollbackFor = Exception.class)
   private void twoStageRewardToBoss(Long bossId, Long teamUid, Date oneStageTime, Integer source, String orderNo)
         throws Exception {
      // 第一阶段完成之后的90天内 ; 队友产生的订单中(自购+分享),邀请人累计产生≥1 元奖金
      Date endDate = DateUtil.plusDayDate(Constant.TWO_STAGE_LIMIT_DAYS, oneStageTime);
      // 统计订单奖金 (“好友自购”和“好友分享”)
      BigDecimal rewardMoney = hongBaoV2CountService.getOrderRewardByTeamUid(bossId, teamUid, endDate);
      if (rewardMoney == null || rewardMoney.compareTo(Constant.TWO_STAGE_ORDER_REWARD_MIN) < 0)
         return;
      // 计算奖励
      BigDecimal money = Constant.TWO_STAGE_MONEY_MIN;
      long total = redPackWinInviteMapper.countByUidAndType(bossId, RedPackWinInviteTypeEnum.twoStageReward.name());
      if (total > 0 && total < Constant.TWO_STAGE_MONEY_ADD_NUM) {
         long num = total % Constant.TWO_STAGE_MONEY_ADD_NUM;
         money = MoneyBigDecimalUtil.add(money,
               MoneyBigDecimalUtil.mul(Constant.TWO_STAGE_MONEY_ADD, new BigDecimal(num)));
      }
      // 获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.twoStageReward);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.twoStageReward.name() + ":" + teamUid));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 4、增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createIncreaseReward(winInvite));
      // 5、消息
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackTwoStageReward, money,
            "粉丝(好友)完成第二阶段", new Gson().toJson(dto));
   }
   /**
    * 上级奖励:次月开始产生满足条件的分享订单(分享订单实付款≥10元) 连续15个月 自然月获得(已到账)每月最高2元
    *
    * @param uid
    * @param source
    * @param orderNo
    * @param bossId
    */
   @Transactional(rollbackFor = Exception.class)
   private void threeStageRewardToBoss(Long bossId, Long teamUid, Date twoStageTime, Integer source, String orderNo)
         throws Exception {
      // 二、三阶段不可同月
      if (DateUtil.isSameMonth(twoStageTime, new Date()))
         return;
      // 是否已领取本月
      RedPackWinInvite threeStage = redPackWinInviteMapper.getByUidAndTeamUidAndTypeMonth(bossId, teamUid,
            RedPackWinInviteTypeEnum.threeStageReward.name());
      if (threeStage != null)
         return;
      // 已奖励次数
      int totalNum = redPackWinInviteMapper.countByUidAndTeamUidAndType(bossId, teamUid,
            RedPackWinInviteTypeEnum.threeStageReward.name());
      if (totalNum >= Constant.THREE_STAGE_REWARD_MONTH)
         return;
      // 是否已间断
      int monthSpace = DateUtil.getMonthSpace(twoStageTime, new Date());
      if (monthSpace != totalNum + 1)
         return;
      // 统计本月获得奖金 (“好友自购”和“好友分享”)
      BigDecimal rewardMoney = hongBaoV2CountService.getOrderRewardByTeamUidTheMonth(bossId, teamUid);
      if (rewardMoney == null || rewardMoney.compareTo(Constant.THREE_STAGE_ORDER_REWARD_MIN) < 0)
         return;
      // 计算随机奖励
      double randomMoney = Constant.THREE_STAGE_RANDOM_MIN
            + Math.random() * (Constant.THREE_STAGE_RANDOM_MAX - Constant.THREE_STAGE_RANDOM_MIN);
      // 保留两位小数
      BigDecimal money = new BigDecimal(randomMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
      // 3、获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.threeStageReward);
      winInvite.setUid(bossId);
      winInvite.setTeamUid(teamUid);
      winInvite.setMoney(money);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setIdentifyCode(
            StringUtil.Md5(RedPackWinInviteTypeEnum.threeStageReward.name() + ":" + teamUid + "-" + monthSpace));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 4、增加红包
      redPackBalanceService.addRedPack(bossId, money, RedPackDetailFactory.createSeriesReward(winInvite));
      // 消息
      UserInfo userInfo = userInfoService.selectByPKey(teamUid);
      MsgRedPackTeamRewardContentDTO dto = new MsgRedPackTeamRewardContentDTO();
      dto.setNickName(userInfo.getNickName());
      dto.setPortrait(userInfo.getPortrait());
      userMoneyMsgNotificationService.teamRedPackRewardMsg(bossId, MsgTypeMoneyTypeEnum.redPackThreeStageReward,
            money, "粉丝(好友)完成第三阶段连续[第" + monthSpace + "个月]", new Gson().toJson(dto));
   }
   @Override
   public List<RedPackWinProgressVO> getInviteProgressByWorkerId(Long uid, Long tid) {
      List<RedPackWinProgressVO> listVO = new ArrayList<RedPackWinProgressVO>();
      ThreeSale threeSale = threeSaleSerivce.getNearRelationByBossIdAndWorkerId(uid, tid);
      if (threeSale == null || threeSale.getSucceedTime() == null)
         return listVO;
      UserInfo userInfo = userInfoService.selectByPKey(tid);
      if (userInfo == null)
         return listVO;
      // 奖励记录
      List<RedPackWinInvite> listWin = redPackWinInviteMapper.getWinListByBossIdAndTeamUid(uid, tid);
      if (listWin == null || listWin.size() == 0)
         return listVO;
      int month = 1;
      for (RedPackWinInvite win : listWin) {
         if (win.getType() == RedPackWinInviteTypeEnum.zeroStageReward) {
            listVO.add(new RedPackWinProgressVO("成功注册", TimeUtil.formatDate(userInfo.getCreatetime())));
            listVO.add(new RedPackWinProgressVO("确立邀请", TimeUtil.formatDate(threeSale.getSucceedTime())));
         }
         String time = TimeUtil.formatDate(win.getCreateTime());
         BigDecimal money = win.getMoney().setScale(2);
         if (win.getType() == RedPackWinInviteTypeEnum.oneStageReward) {
            listVO.add(new RedPackWinProgressVO("第一阶段", time, money.toString()));
            continue;
         }
         if (win.getType() == RedPackWinInviteTypeEnum.twoStageReward) {
            listVO.add(new RedPackWinProgressVO("第二阶段", time, money.toString()));
            continue;
         }
         if (win.getType() == RedPackWinInviteTypeEnum.threeStageReward) {
            listVO.add(new RedPackWinProgressVO("第三阶段第" + month + "个月", time, money.toString()));
            month++;
            continue;
         }
      }
      return listVO;
   }
   @Override
   public List<RedPackWinInvite> getWinTopListByBossId(int page, int count, Long uid) {
      return redPackWinInviteMapper.getWinTopListByBossId(count * (page - 1), count, uid);
   }
   @Override
   public long countWinTopListByBossId(Long uid) {
      return redPackWinInviteMapper.countWinTopListByBossId(uid);
   }
   @Override
   public long countTeamNumByTid(Long uid, Long teamUid) {
      return redPackWinInviteMapper.countTeamNumByTid(uid, teamUid);
   }
   @Override
   public List<RedPackWinInvite> query(long page, int count, String key, String type){
      return redPackWinInviteMapper.query(count * (page - 1), count, key, type);
   }
   @Override
   public long count(String key, String type){
      Long count = redPackWinInviteMapper.count(key, type);
      if (count == null) {
         count = 0L;
      }
      return count;
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   @Transactional(rollbackFor = Exception.class)
   public void winRedPackByOrder(Long orderUid, String orderNo, Integer source) {
      if (orderUid == null || StringUtil.isNullOrEmpty(orderNo)) {
         return;
      }
      // 验证是否未首单
      CommonOrder firstOrder = commonOrderService.getFirstOrder(orderUid);
      if (!firstOrder.getOrderNo().equals(orderNo) || firstOrder.getSourceType() != source)
         return;
      Date downTime = firstOrder.getThirdCreateTime();
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return;
      long registerTime = register.getCreateTime().getTime();
      // 注册48小时内下单限制
      if (downTime.getTime() < registerTime || downTime.getTime() > registerTime + 1000*60*60*48L)
         return;
      // 是否存在上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerId(orderUid);
      if (threeSale == null)
         return;
      Long bossId = threeSale.getBoss().getId();
      if (bossId == null)
         return;
      // 该邀请是否已添加
      RedPackWinInvite threeStage = redPackWinInviteMapper.getByUidAndTeamUid(bossId, orderUid);
      if (threeStage != null)
         return;
      // 小于2.1.3版本不增加
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
      if (activeLog == null)
         return;
      if (!VersionUtil.greaterThan_2_1_3("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return;
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0) {
         return;
      }
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
       boolean satisfy = false;
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 订单未结算
         if(commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 邀请关系之后
         long thirdTime = commonOrder.getThirdCreateTime().getTime();
         if (thirdTime < threeSale.getCreateTime())
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) < 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete =MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil.div(eIncome, settlement), BigDecimal.valueOf(100)) ;
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      if (!satisfy) {
         return;
      }
      // 获得红包记录
      RedPackWinInvite winInvite = new RedPackWinInvite();
      winInvite.setUid(bossId);
      winInvite.setTeamUid(orderUid);
      winInvite.setMoney(null);
      winInvite.setSource(source);
      winInvite.setOrderNo(orderNo);
      winInvite.setCreateTime(new Date());
      winInvite.setUpdateTime(new Date());
      winInvite.setType(RedPackWinInviteTypeEnum.inviteDownOrder);
      winInvite.setIdentifyCode(StringUtil.Md5(RedPackWinInviteTypeEnum.inviteDownOrder.name() + ":" + orderUid));
      redPackWinInviteMapper.insertSelective(winInvite);
      // 消息提醒
      UserInfo userInfo = userInfoService.selectByPKey(orderUid);
      userInviteMsgNotificationService.pullNewRedPack(bossId, userInfo.getNickName(), userInfo.getPortrait());
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   public boolean verifyOrder(Long orderUid, String orderNo, Integer source, Date downTime) {
       boolean satisfy = false;
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return satisfy;
      // 注册48小时 以内:新人
      long registerTime = register.getCreateTime().getTime();
      // 48小时限制
      if (downTime.getTime() > registerTime || downTime.getTime() < registerTime + 1000*60*60*48)
         return satisfy;
      // 验证是否未首单
      CommonOrder firstOrder = commonOrderService.getFirstOrder(orderUid);
      if (!firstOrder.getOrderNo().equals(orderNo) || firstOrder.getSourceType() != source)
         return satisfy;
      // 是否已奖励
      List<UserSystemCoupon> coupons = userSystemCouponService.getUserCouponBySource(orderUid, UserSystemCoupon.SOURCE_PULL_NEW);
      if (coupons != null && coupons.size() > 0) {
         return satisfy;
      }
      // 是否存在上下级关系
      ThreeSale threeSale = threeSaleSerivce.getByWorkerId(orderUid);
      if (threeSale == null)
         return satisfy;
      Long bossId = threeSale.getBoss().getId();
      if (bossId == null)
         return satisfy;
      // 小于2.1.3版本不增加
      UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(orderUid);
      if (activeLog == null)
         return satisfy;
      if (!VersionUtil.greaterThan_2_1_3("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
            activeLog.getVersionCode()))
         return satisfy;
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0)
         return satisfy;
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 邀请关系之后
         long thirdTime = commonOrder.getThirdCreateTime().getTime();
         if (thirdTime < threeSale.getCreateTime())
            continue;
         // 订单失效
         if(commonOrder.getState() != CommonOrder.STATE_FK && commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) <= 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete = MoneyBigDecimalUtil.div(eIncome, settlement);
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      return satisfy;
   }
   @Override
   @RequestSerializableByKeyService(key = "#orderUid")
   @Transactional(rollbackFor = Exception.class)
   public void winFreeCoupon(Long orderUid, String orderNo, Integer source, Date downTime) {
      if (orderUid == null || StringUtil.isNullOrEmpty(orderNo)) {
         return;
      }
      // 注册时间
      UserInfoRegister register = userInfoRegisterService.selectByPrimaryKey(orderUid);
      if (register == null)
         return;
      // 注册48小时 以内:新人
      long registerTime = register.getCreateTime().getTime();
      // 48小时限制
      if (downTime.getTime() > registerTime || downTime.getTime() < registerTime + 1000*60*60*48)
         return;
      // 是否已奖励
      List<UserSystemCoupon> coupons = userSystemCouponService.getUserCouponBySource(orderUid, UserSystemCoupon.SOURCE_PULL_NEW);
      if (coupons != null && coupons.size() > 0) {
         return;
      }
      // 查询订单
      List<CommonOrder> list = commonOrderService.getByOrderNo(orderUid, orderNo);
      if (list == null || list.size() ==0) {
         return;
      }
       // 商品比例限制
       BigDecimal limitRate = new BigDecimal(redPackConfigService.getValueByKey("goods_reate_limit"));
       BigDecimal limitPayMent = new BigDecimal(redPackConfigService.getValueByKey("goods_pay_ment_limit"));
       boolean satisfy = false;
      // 遍历是否存在符合相应商品
      for (CommonOrder commonOrder: list) {
         // 订单失效
         if(commonOrder.getState() != CommonOrder.STATE_FK && commonOrder.getState() != CommonOrder.STATE_JS)
            continue;
         // 付款金额限制
         BigDecimal payment = commonOrder.getPayment();
         if (payment == null || payment.compareTo(limitPayMent) <= 0)
            continue;
         // 商品佣金比例限制
         BigDecimal eIncome = commonOrder.geteIncome();
         BigDecimal settlement = commonOrder.getSettlement();
         if(eIncome == null || settlement == null) {
            continue;
         }
         BigDecimal rete = MoneyBigDecimalUtil.div(eIncome, settlement);
         if (rete.compareTo(limitRate) >= 0) {
            satisfy = true;
            break;
         }
      }
      if (!satisfy) {
         return;
      }
      // 赠送购买者一张免单券
      try {
         userSystemCouponService.freeCouponWinBySystem(orderUid, CouponTypeEnum.freeCoupon,
               UserSystemCoupon.SOURCE_PULL_NEW, 1, true, 2, 1);
      } catch (UserSystemCouponException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   @Override
   public List<Long> listWinUid(int start, int count) {
      return redPackWinInviteMapper.listWinUid(start, count);
   }
   @Override
   public List<RedPackWinInvite> listLastMonthByUid(int start, int count, Long uid) {
      return redPackWinInviteMapper.listLastMonthByUid(start, count, uid);
   }
   @Override
   public long countLastMonthByUid(Long uid) {
      Long count = redPackWinInviteMapper.countLastMonthByUid(uid);
      if (count == null)
         count = 0L;
      return count;
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void arriveMoney(Long uid, BigDecimal money, Date date) throws Exception {
      RedPackDetail detail = RedPackDetailFactory.createByMonth(uid, money, date);
      redPackBalanceService.addRedPack(uid, money, detail);
   }
}