admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/service/impl/tlj/UserTaoLiJinNewbiesServiceImpl.java
@@ -1,397 +1,427 @@
package com.yeshi.fanli.service.impl.tlj;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.yeshi.fanli.dao.mybatis.tlj.UserTaoLiJinNewbiesMapper;
import com.yeshi.fanli.dto.taobao.TaoLiJinDTO;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinDetail;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinDetail.TaoLiJinDetailTypeEnum;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinNewbies;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.taobao.TLJFreeBuyGoods;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.entity.taobao.TaoKeAppInfo;
import com.yeshi.fanli.exception.taobao.TaoKeApiException;
import com.yeshi.fanli.exception.tlj.TaoLiJinCreateException;
import com.yeshi.fanli.exception.tlj.UserTaoLiJinNewbiesException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.service.inter.redpack.UserTaoLiJinNewbiesService;
import com.yeshi.fanli.service.inter.taobao.TLJFreeBuyGoodsService;
import com.yeshi.fanli.service.inter.taobao.TaoBaoBuyRelationMapService;
import com.yeshi.fanli.service.inter.tlj.ConfigTaoLiJinService;
import com.yeshi.fanli.service.inter.tlj.UserTaoLiJinDetailService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TaoBaoConstant;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.taobao.TaoBaoUtil;
import com.yeshi.fanli.util.taobao.TaoKeApiUtil;
import com.yeshi.fanli.vo.redpack.TaoLiJinWinDetailVO;
@Service
public class UserTaoLiJinNewbiesServiceImpl implements UserTaoLiJinNewbiesService {
   @Resource
   private UserTaoLiJinNewbiesMapper userTaoLiJinNewbiesMapper;
   @Resource
   private ConfigTaoLiJinService configTaoLiJinService;
   @Resource
   private UserInfoExtraService userInfoExtraService;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Resource
   private DeviceActiveService deviceActiveService;
   @Resource
   private JumpDetailV2Service jumpDetailV2Service;
   @Resource(name = "taskExecutor")
   private TaskExecutor executor;
   @Resource
   private TLJFreeBuyGoodsService tljFreeBuyGoodsService;
   @Resource
   private UserTaoLiJinDetailService userTaoLiJinDetailService;
   @Resource
   private TaoBaoBuyRelationMapService taoBaoBuyRelationMapService;
   @Override
   public boolean verifyHasReward(Long uid, String device) {
      try {
         if (StringUtil.isNullOrEmpty(device) && (uid == null || uid <= 0))
            return false;
         if (uid == null || uid <= 0) {
            DeviceActive deviceActive = deviceActiveService.getFirstActiveInfo(device);
            if (deviceActive == null)
               return true; // 新设备弹出
            Date nowTime = new Date();
            Date createTime = deviceActive.getCreateTime();
            int days = DateUtil.daysBetween2(createTime, nowTime);
            if (days >= Constant.TLJ_NEW_USER_DAYS) {
               return false; // 已经超出设置天数
            }
            return true; // 未超过时间
         }
         UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
         if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
            return false;
         Date nowTime = new Date();
         Date firstLoginTime = userInfoExtra.getFirstLoginTime();
         int days = DateUtil.daysBetween2(firstLoginTime, nowTime);
         if (days >= Constant.TLJ_NEW_USER_DAYS)
            return false; // 已经超出设置天数
         UserTaoLiJinNewbies redPackWin = userTaoLiJinNewbiesMapper.selectByPrimaryKey(uid);
         if (redPackWin != null) {
            if (redPackWin.getMoney().compareTo(Constant.TLJ_NEW_USER_MONEY) >= 0)
               return false; // 已领取完
            Date updateTime = redPackWin.getUpdateTime();
            int daysNum = DateUtil.daysBetween2(updateTime, nowTime);
            if (daysNum == 0)
               return false; // 今日已领取
            Integer num = redPackWin.getNum();
            if (num >= Constant.TLJ_NEW_USER_DAYS)
               return false; // 领取次数超限
         }
         return true;
      } catch (Exception e) {
         LogHelper.errorDetailInfo(e);
      }
      return false;
   }
   @RequestSerializableByKeyService(key = "#uid")
   @Transactional(rollbackFor = Exception.class)
   @Override
   public TaoLiJinWinDetailVO receiveReward(Long uid) throws Exception {
      if (uid == null || uid <= 0)
         return null; // 未登录弹出
      UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
      if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
         return null;
      Date nowTime = new Date();
      Date firstLoginTime = userInfoExtra.getFirstLoginTime();
      int days = DateUtil.daysBetween2(firstLoginTime, nowTime);
      if (days >= Constant.TLJ_NEW_USER_DAYS)
         return null; // 已经超出设置天数
      UserTaoLiJinNewbies redPackWin = userTaoLiJinNewbiesMapper.selectForUpdate(uid);
      if (redPackWin != null) {
         if (redPackWin.getMoney().compareTo(Constant.TLJ_NEW_USER_MONEY) >= 0)
            return null; // 已领取完
         Date updateTime = redPackWin.getUpdateTime();
         int daysNum = DateUtil.daysBetween2(updateTime, nowTime);
         if (daysNum == 0)
            return null; // 今日已领取
         Integer num = redPackWin.getNum();
         if (num >= Constant.TLJ_NEW_USER_DAYS)
            return null; // 领取次数超限
      }
      BigDecimal money = null;
      if (redPackWin == null) { // 第一次
         if (days == Constant.TLJ_NEW_USER_DAYS - 1) {  // 最后一天
            money = Constant.TLJ_NEW_USER_MONEY;
         } else { // 计算随机奖励
            double randomNum = Constant.TLJ_NEW_USER_MIN +  Math.random() * (Constant.TLJ_NEW_USER_MAX - Constant.TLJ_NEW_USER_MIN);
            randomNum = randomNum/100;
            BigDecimal rate = new BigDecimal(randomNum).setScale(2, BigDecimal.ROUND_DOWN);
            money = MoneyBigDecimalUtil.mul(Constant.TLJ_NEW_USER_MONEY,rate);
         }
      } else if (days == Constant.TLJ_NEW_USER_DAYS - 1) { // 最后一天
         money = MoneyBigDecimalUtil.sub(Constant.TLJ_NEW_USER_MONEY, redPackWin.getMoney());
      } else { // 计算剩余随机奖励 10%-25%
         double randomNum = 10 +  Math.random() * (20 - 10);
         BigDecimal rate = new BigDecimal(randomNum/100).setScale(2, BigDecimal.ROUND_DOWN);
         money = MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil.sub(Constant.TLJ_NEW_USER_MONEY,redPackWin.getMoney()),rate);
      }
      if (money.compareTo(new BigDecimal(0)) <= 0)
         return null;
      money = money.setScale(2);
      int num = 1;
      BigDecimal balance = null;
      if (redPackWin == null) {
         balance = money;
         // 注册开始 有效期
         Date endDate = DateUtil.plusDayDate(Constant.TLJ_NEW_USER_LIMIT, firstLoginTime);
         redPackWin = new UserTaoLiJinNewbies();
         redPackWin.setId(uid);
         redPackWin.setNum(1);
         redPackWin.setMoney(money);
         redPackWin.setEndTime(endDate);
         redPackWin.setCreateTime(nowTime);
         redPackWin.setUpdateTime(nowTime);
         userTaoLiJinNewbiesMapper.insertSelective(redPackWin);
      } else {
         userTaoLiJinNewbiesMapper.addMoney(uid, money);
         num = redPackWin.getNum() + 1;
         balance = MoneyBigDecimalUtil.add(money, redPackWin.getMoney());
      }
      // 明细
      UserTaoLiJinDetail detail = new UserTaoLiJinDetail();
      detail.setUid(uid);
      detail.setMoney(money);
      detail.setTitle(TaoLiJinDetailTypeEnum.add.getDesc());
      detail.setType(TaoLiJinDetailTypeEnum.add);
      detail.setCreateTime(new Date());
      detail.setRemark("新人红包");
      userTaoLiJinDetailService.insertSelective(detail);
      Map<String,String> map = new HashMap<String,String>();
      map.put("url", configTaoLiJinService.getValueByKey("new_user_free_buy_list"));
      TaoLiJinWinDetailVO winDetailVO = new TaoLiJinWinDetailVO();
      winDetailVO.setTitle("新人红包");
      winDetailVO.setBless("恭喜你!已领" + num + "/" + Constant.TLJ_NEW_USER_DAYS + "次");
      winDetailVO.setMoney(money.toString());
      winDetailVO.setDesc("已领取:" + balance + "元");
      winDetailVO.setTips(configTaoLiJinService.getValueByKey("new_user_win_tips"));
      winDetailVO.setParams(map.toString());
      winDetailVO.setJumpDetail(jumpDetailV2Service.getByTypeCache("web"));
      winDetailVO.setLogo(Constant.systemCommonConfig.getDefaultPortrait());
      winDetailVO.setLogoLight(Constant.systemCommonConfig.getDefaultPortrait());
      return winDetailVO;
   }
   @RequestSerializableByKeyService(key = "#uid")
   @Transactional(rollbackFor = Exception.class)
   @Override
   public String createTaoLiJinForBuy(TaoBaoGoodsBrief goods, Long uid) throws UserTaoLiJinNewbiesException {
      if (uid == null || uid <= 0 || goods == null)
         throw new UserTaoLiJinNewbiesException(1,"参数信息缺失");
      // 验证商品是否在免单商品库
      TLJFreeBuyGoods tljFreeBuyGoods = tljFreeBuyGoodsService.selectByAuctionIdAndDay(goods.getAuctionId(),
            TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyy-MM-dd"));
      if (tljFreeBuyGoods == null)
         throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
      // 验证是否有券
      if (goods == null || goods.getCouponAmount() == null ||
            goods.getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
         executor.execute(new Runnable() {
            @Override
            public void run() {
               tljFreeBuyGoodsService.deleteByGoodsId(goods.getAuctionId());
            }
         });
         throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
      }
      // 验证券后价 是否在 1-2元
      BigDecimal money = TaoBaoUtil.getAfterUseCouplePrice(goods);
      if (money.compareTo(new BigDecimal(1.0)) < 0 || money.compareTo(new BigDecimal(2.0)) > 0) {
         executor.execute(new Runnable() {
            @Override
            public void run() {
               tljFreeBuyGoodsService.deleteByGoodsId(goods.getAuctionId());
            }
         });
         throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
      }
      // 验证用户信息
      UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
      if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
         throw new UserTaoLiJinNewbiesException(1001, "你不是“新用户”无法使用新人红包0元购买。");
      // 验证是否已超出新用户定义
      try {
         int days = DateUtil.daysBetween2(userInfoExtra.getFirstLoginTime(), new Date());
         if (days > Constant.TLJ_NEW_USER_DEFINE)
            throw new UserTaoLiJinNewbiesException(1001, "你不是“新用户”无法使用新人红包0元购买。");
      } catch (ParseException e1) {
         throw new UserTaoLiJinNewbiesException(1, "日期信息计算失败");
      }
      // 验证余额
      UserTaoLiJinNewbies taoLiJinNewbies = userTaoLiJinNewbiesMapper.selectForUpdate(uid);
      if (taoLiJinNewbies == null || taoLiJinNewbies.getMoney() == null ||
            taoLiJinNewbies.getMoney().compareTo(money)   < 0)
         throw new UserTaoLiJinNewbiesException(1001, "新人红包不足,请换个商品再试或继续领取到足额新人红包。");
      // 验证是否已过期
      if (taoLiJinNewbies.getEndTime() == null
            || taoLiJinNewbies.getEndTime().getTime() < java.lang.System.currentTimeMillis())
         throw new UserTaoLiJinNewbiesException(1, "新人红包已过期");
      // 红包减少
      userTaoLiJinNewbiesMapper.subMoney(uid, money);
      // 加入明细
      UserTaoLiJinDetail detail = new UserTaoLiJinDetail();
      detail.setUid(uid);
      detail.setMoney(new BigDecimal("-" + money));
      detail.setTitle(TaoLiJinDetailTypeEnum.reduce.getDesc());
      detail.setType(TaoLiJinDetailTypeEnum.reduce);
      detail.setCreateTime(new Date());
      detail.setRemark("新人免单使用红包");
      userTaoLiJinDetailService.insertSelective(detail);
      // 创建淘礼金链接
      if (TaoBaoUtil.isSpecialGoods(goods.getMaterialLibType())) {
         return createTaoLiJin(goods.getAuctionId(), money, 1, TaoBaoConstant.TAOBAO_SPECIAL_PID_DEFAULT);
      } else { // 非返利库商品
         String relationId = null;
         try {
            relationId = taoBaoBuyRelationMapService.getRelationId(uid);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e, "uid:" + uid, null);
         }
         if (StringUtil.isNullOrEmpty(relationId))
            throw new UserTaoLiJinNewbiesException(1, "渠道未备案");
         return createTaoLiJin(goods.getAuctionId(), money, 1, TaoBaoConstant.TAOBAO_RELATION_AS_SPECIAL_PID)
               + "&relationId=" + relationId;
      }
   }
   @Transactional
   private String createTaoLiJin(Long auctionId, BigDecimal perface, int totalNum, String pid) throws UserTaoLiJinNewbiesException {
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
      SimpleDateFormat formatStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String name = "新人免单购";
      Date date = new Date();
      String date_str = format.format(date);
      String sendEndTime_str = date_str + " 22:00:00";
      String useEndTime_str = date_str + " 23:59:59";
      // 发放时间
      Date sendStartTime = date;
      Date sendEndTime = null;
      // 使用时间
      Date useStartTime = null;
      Date useEndTime = null;
      try {
         sendEndTime = formatStr.parse(sendEndTime_str);
         useEndTime = formatStr.parse(useEndTime_str);
      } catch (ParseException e2) {
         e2.printStackTrace();
      }
      // 创建淘礼金红包
      TaoLiJinDTO taoLiJinDTO = null;
      TaoKeAppInfo taoKeAppInfo = new TaoKeAppInfo(TaoBaoConstant.TAOBAO_AUTH_APPKEY, TaoBaoConstant.TAOBAO_AUTH_APPSECRET, pid);
      try {
         taoLiJinDTO = TaoKeApiUtil.createTaoLiJin(auctionId, name, perface, totalNum, sendStartTime,
               sendEndTime, useStartTime, useEndTime, taoKeAppInfo);
      } catch (TaoLiJinCreateException e) {
         LogHelper.errorDetailInfo(e);
         executor.execute(new Runnable() {
            @Override
            public void run() {
               if (e.getCode() == TaoLiJinCreateException.CODE_TLJ_FORBIDDEN) {
                  // 该商品不支持创建淘礼金红包
                  tljFreeBuyGoodsService.deleteByGoodsId(auctionId);
               } else if (e.getCode() == TaoLiJinCreateException.CODE_TLJ_NO_MONEY) {
                  // 官方玩法钱包余额不足 TODO
               }
            }
         });
      } catch (TaoKeApiException e) {
         LogHelper.errorDetailInfo(e);
      }
      if (taoLiJinDTO == null || StringUtil.isNullOrEmpty(taoLiJinDTO.getSendUrl()))
         throw new UserTaoLiJinNewbiesException(1, "淘宝API红包创建失败");
      return taoLiJinDTO.getSendUrl();
   }
   @Override
   public UserTaoLiJinNewbies selectByPrimaryKey(Long uid) {
      return userTaoLiJinNewbiesMapper.selectByPrimaryKey(uid);
   }
}
package com.yeshi.fanli.service.impl.tlj;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import com.yeshi.fanli.entity.SystemEnum;
import com.yeshi.fanli.entity.SystemPIDInfo;
import com.yeshi.fanli.service.inter.config.SystemConfigService;
import com.yeshi.fanli.service.manger.PIDManager;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.yeshi.fanli.dao.mybatis.tlj.UserTaoLiJinNewbiesMapper;
import com.yeshi.fanli.dto.taobao.TaoLiJinDTO;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinDetail;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinDetail.TaoLiJinDetailTypeEnum;
import com.yeshi.fanli.entity.bus.tlj.UserTaoLiJinNewbies;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.taobao.TLJFreeBuyGoods;
import com.yeshi.goods.facade.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.common.entity.taobao.TaoKeAppInfo;
import com.yeshi.fanli.exception.taobao.TaoKeApiException;
import com.yeshi.fanli.exception.tlj.TaoLiJinCreateException;
import com.yeshi.fanli.exception.tlj.UserTaoLiJinNewbiesException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.service.inter.redpack.UserTaoLiJinNewbiesService;
import com.yeshi.fanli.service.inter.taobao.TLJFreeBuyGoodsService;
import com.yeshi.fanli.service.inter.taobao.TaoBaoBuyRelationMapService;
import com.yeshi.fanli.service.inter.tlj.ConfigTaoLiJinService;
import com.yeshi.fanli.service.inter.tlj.UserTaoLiJinDetailService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.util.Constant;
import org.yeshi.utils.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TaoBaoConstant;
import org.yeshi.utils.TimeUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.taobao.TaoBaoUtil;
import com.yeshi.fanli.util.taobao.TaoKeApiUtil;
import com.yeshi.fanli.vo.redpack.TaoLiJinWinDetailVO;
import net.sf.json.JSONObject;
@Service
public class UserTaoLiJinNewbiesServiceImpl implements UserTaoLiJinNewbiesService {
    @Resource
    private UserTaoLiJinNewbiesMapper userTaoLiJinNewbiesMapper;
    @Resource
    private ConfigTaoLiJinService configTaoLiJinService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserInfoExtraService userInfoExtraService;
    @Resource
    private DeviceActiveService deviceActiveService;
    @Resource
    private JumpDetailV2Service jumpDetailV2Service;
    @Resource(name = "taskExecutor")
    private TaskExecutor executor;
    @Resource
    private TLJFreeBuyGoodsService tljFreeBuyGoodsService;
    @Resource
    private UserTaoLiJinDetailService userTaoLiJinDetailService;
    @Resource
    private TaoBaoBuyRelationMapService taoBaoBuyRelationMapService;
    @Resource
    private PIDManager pidManager;
    @Override
    public boolean verifyHasReward(Long uid, String device) {
        try {
            if (StringUtil.isNullOrEmpty(device) && (uid == null || uid <= 0))
                return false;
            if (uid == null || uid <= 0) {
                DeviceActive deviceActive = deviceActiveService.getFirstActiveInfo(device);
                if (deviceActive == null)
                    return true; // 新设备弹出
                Date nowTime = new Date();
                Date createTime = deviceActive.getCreateTime();
                int days = DateUtil.daysBetween2(createTime, nowTime);
                if (days >= Constant.TLJ_NEW_USER_DAYS) {
                    return false; // 已经超出设置天数
                }
                return true; // 未超过时间
            }
            UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
            if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
                return false;
            Date nowTime = new Date();
            Date firstLoginTime = userInfoExtra.getFirstLoginTime();
            int days = DateUtil.daysBetween2(firstLoginTime, nowTime);
            if (days >= Constant.TLJ_NEW_USER_DAYS)
                return false; // 已经超出设置天数
            UserTaoLiJinNewbies redPackWin = userTaoLiJinNewbiesMapper.selectByPrimaryKey(uid);
            if (redPackWin != null) {
                if (redPackWin.getMoney().compareTo(Constant.TLJ_NEW_USER_MONEY) >= 0)
                    return false; // 已领取完
                Date updateTime = redPackWin.getUpdateTime();
                int daysNum = DateUtil.daysBetween2(updateTime, nowTime);
                if (daysNum == 0)
                    return false; // 今日已领取
                Integer num = redPackWin.getNum();
                if (num >= Constant.TLJ_NEW_USER_DAYS)
                    return false; // 领取次数超限
            }
            return true;
        } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
        }
        return false;
    }
    @RequestSerializableByKeyService(key = "#uid")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public TaoLiJinWinDetailVO receiveReward(Long uid) throws Exception {
        if (uid == null || uid <= 0)
            return null; // 未登录弹出
        UserInfo userInfo = userInfoService.selectByPKey(uid);
        if (userInfo == null)
            return null;
        UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
        if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
            return null;
        Date nowTime = new Date();
        Date firstLoginTime = userInfoExtra.getFirstLoginTime();
        int days = DateUtil.daysBetween2(firstLoginTime, nowTime);
        if (days >= Constant.TLJ_NEW_USER_DAYS)
            return null; // 已经超出设置天数
        UserTaoLiJinNewbies redPackWin = userTaoLiJinNewbiesMapper.selectForUpdate(uid);
        if (redPackWin != null) {
            if (redPackWin.getMoney().compareTo(Constant.TLJ_NEW_USER_MONEY) >= 0)
                return null; // 已领取完
            Date updateTime = redPackWin.getUpdateTime();
            int daysNum = DateUtil.daysBetween2(updateTime, nowTime);
            if (daysNum == 0)
                return null; // 今日已领取
            Integer num = redPackWin.getNum();
            if (num >= Constant.TLJ_NEW_USER_DAYS)
                return null; // 领取次数超限
        }
        BigDecimal money = null;
        if (redPackWin == null) { // 第一次
            if (days == Constant.TLJ_NEW_USER_DAYS - 1) {  // 最后一天
                money = Constant.TLJ_NEW_USER_MONEY;
            } else { // 计算随机奖励
                double randomNum = Constant.TLJ_NEW_USER_MIN + Math.random() * (Constant.TLJ_NEW_USER_MAX - Constant.TLJ_NEW_USER_MIN);
                randomNum = randomNum / 100;
                BigDecimal rate = new BigDecimal(randomNum).setScale(2, BigDecimal.ROUND_DOWN);
                money = MoneyBigDecimalUtil.mul(Constant.TLJ_NEW_USER_MONEY, rate);
            }
        } else if (days == Constant.TLJ_NEW_USER_DAYS - 1) { // 最后一天
            money = MoneyBigDecimalUtil.sub(Constant.TLJ_NEW_USER_MONEY, redPackWin.getMoney());
        } else { // 计算剩余随机奖励 10%-25%
            double randomNum = 10 + Math.random() * (20 - 10);
            BigDecimal rate = new BigDecimal(randomNum / 100).setScale(2, BigDecimal.ROUND_DOWN);
            money = MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil.sub(Constant.TLJ_NEW_USER_MONEY, redPackWin.getMoney()), rate);
        }
        if (money.compareTo(new BigDecimal(0)) <= 0)
            return null;
        money = money.setScale(2);
        int num = 1;
        BigDecimal balance = null;
        if (redPackWin == null) {
            balance = money;
            // 注册开始 有效期
            Date endDate = DateUtil.plusDayDate(Constant.TLJ_NEW_USER_LIMIT, firstLoginTime);
            redPackWin = new UserTaoLiJinNewbies();
            redPackWin.setId(uid);
            redPackWin.setNum(1);
            redPackWin.setMoney(money);
            redPackWin.setEndTime(endDate);
            redPackWin.setCreateTime(nowTime);
            redPackWin.setUpdateTime(nowTime);
            userTaoLiJinNewbiesMapper.insertSelective(redPackWin);
        } else {
            userTaoLiJinNewbiesMapper.addMoney(uid, money);
            num = redPackWin.getNum() + 1;
            balance = MoneyBigDecimalUtil.add(money, redPackWin.getMoney());
        }
        // 明细
        UserTaoLiJinDetail detail = new UserTaoLiJinDetail();
        detail.setUid(uid);
        detail.setMoney(money);
        detail.setTitle(TaoLiJinDetailTypeEnum.add.getDesc());
        detail.setType(TaoLiJinDetailTypeEnum.add);
        detail.setCreateTime(new Date());
        detail.setRemark("新人红包");
        userTaoLiJinDetailService.insertSelective(detail);
        JSONObject json = new JSONObject();
        json.put("url", configTaoLiJinService.getValueByKey("new_user_free_buy_list"));
        TaoLiJinWinDetailVO winDetailVO = new TaoLiJinWinDetailVO();
        winDetailVO.setTitle("新人红包");
        winDetailVO.setBless("恭喜你!已领" + num + "/" + Constant.TLJ_NEW_USER_DAYS + "次");
        winDetailVO.setMoney(money.toString());
        winDetailVO.setDesc("已领取:" + balance + "元");
        winDetailVO.setTips(configTaoLiJinService.getValueByKey("new_user_win_tips"));
        winDetailVO.setParams(json.toString());
        winDetailVO.setJumpDetail(jumpDetailV2Service.getByTypeCache("web",userInfo.getSystem()));
        winDetailVO.setLogo(userInfoService.getDefaultPortrait(userInfo.getSystem()));
        winDetailVO.setLogoLight(userInfo.getPortrait());
        return winDetailVO;
    }
    @RequestSerializableByKeyService(key = "#uid")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String createTaoLiJinForBuy(TaoBaoGoodsBrief goods, Long uid) throws UserTaoLiJinNewbiesException {
        if (uid == null || uid <= 0 || goods == null)
            throw new UserTaoLiJinNewbiesException(1, "参数信息缺失");
        // 验证商品是否在免单商品库
        TLJFreeBuyGoods tljFreeBuyGoods = tljFreeBuyGoodsService.selectByAuctionIdAndDay(goods.getAuctionId(),
                TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyy-MM-dd"));
        if (tljFreeBuyGoods == null)
            throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
        // 验证是否有券
        if (goods == null || goods.getCouponAmount() == null ||
                goods.getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    tljFreeBuyGoodsService.deleteByGoodsId(goods.getAuctionId());
                }
            });
            throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
        }
        // 验证券后价 是否在 1-2元
        BigDecimal money = TaoBaoUtil.getCouponPrice(goods);
        if (money.compareTo(new BigDecimal(1.0)) < 0 || money.compareTo(new BigDecimal(2.0)) > 0) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    tljFreeBuyGoodsService.deleteByGoodsId(goods.getAuctionId());
                }
            });
            throw new UserTaoLiJinNewbiesException(1, "该商品非免单商品");
        }
        // 验证用户信息
        UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
        if (userInfoExtra == null || userInfoExtra.getFirstLoginTime() == null)
            throw new UserTaoLiJinNewbiesException(1001, "你不是“新用户”无法使用新人红包0元购买。");
        // 验证是否激活
        if (StringUtil.isNullOrEmpty(userInfoExtra.getInviteCode()))
            throw new UserTaoLiJinNewbiesException(1002, "邀请码未激活,无法使用新人红包0元购买。");
        // 验证是否已超出新用户定义
        try {
            int days = DateUtil.daysBetween2(userInfoExtra.getFirstLoginTime(), new Date());
            if (days > Constant.TLJ_NEW_USER_DEFINE)
                throw new UserTaoLiJinNewbiesException(1001, "你不是“新用户”无法使用新人红包0元购买。");
        } catch (ParseException e1) {
            throw new UserTaoLiJinNewbiesException(1, "日期信息计算失败");
        }
        // 验证余额
        UserTaoLiJinNewbies taoLiJinNewbies = userTaoLiJinNewbiesMapper.selectForUpdate(uid);
        if (taoLiJinNewbies == null || taoLiJinNewbies.getMoney() == null ||
                taoLiJinNewbies.getMoney().compareTo(money) < 0)
            throw new UserTaoLiJinNewbiesException(1001, "新人红包不足,请换个商品再试或继续领取到足额新人红包。");
        // 验证是否已过期
        if (taoLiJinNewbies.getEndTime() == null
                || taoLiJinNewbies.getEndTime().getTime() < java.lang.System.currentTimeMillis())
            throw new UserTaoLiJinNewbiesException(1, "新人红包已过期");
        // 红包减少
        userTaoLiJinNewbiesMapper.subMoney(uid, money);
        // 加入明细
        UserTaoLiJinDetail detail = new UserTaoLiJinDetail();
        detail.setUid(uid);
        detail.setMoney(new BigDecimal("-" + money));
        detail.setTitle(TaoLiJinDetailTypeEnum.reduce.getDesc());
        detail.setType(TaoLiJinDetailTypeEnum.reduce);
        detail.setCreateTime(new Date());
        detail.setRemark("新人免单使用红包");
        userTaoLiJinDetailService.insertSelective(detail);
        String specialId = pidManager.getPid(SystemEnum.blks, Constant.SOURCE_TYPE_TAOBAO, SystemPIDInfo.PidType.fanli);
        String specialRelationIdId = pidManager.getPid(SystemEnum.blks, Constant.SOURCE_TYPE_TAOBAO, SystemPIDInfo.PidType.fanliChannel);
        // 创建淘礼金链接
        if (TaoBaoUtil.isSpecialGoods(goods.getMaterialLibType())) {
            return createTaoLiJin(goods.getAuctionId(), money, 1, specialId);
        } else { // 非返利库商品
            String relationId = null;
            try {
                relationId = taoBaoBuyRelationMapService.getRelationId(uid);
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e, "uid:" + uid, null);
            }
            if (StringUtil.isNullOrEmpty(relationId))
                throw new UserTaoLiJinNewbiesException(1, "渠道未备案");
            return createTaoLiJin(goods.getAuctionId(), money, 1, specialRelationIdId)
                    + "&relationId=" + relationId;
        }
    }
    private String createTaoLiJin(String auctionId, BigDecimal perface, int totalNum, String pid) throws UserTaoLiJinNewbiesException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String name = "新人免单购";
        Date date = new Date();
        String date_str = format.format(date);
        String sendEndTime_str = date_str + " 22:00:00";
        String useEndTime_str = date_str + " 23:59:59";
        // 发放时间
        Date sendStartTime = date;
        Date sendEndTime = null;
        // 使用时间
        Date useStartTime = null;
        Date useEndTime = null;
        try {
            sendEndTime = formatStr.parse(sendEndTime_str);
            useEndTime = formatStr.parse(useEndTime_str);
        } catch (ParseException e2) {
            e2.printStackTrace();
        }
        // 创建淘礼金红包
        TaoLiJinDTO taoLiJinDTO = null;
        TaoKeAppInfo taoKeAppInfo = new TaoKeAppInfo(TaoBaoConstant.TAOBAO_AUTH_APPKEY, TaoBaoConstant.TAOBAO_AUTH_APPSECRET, pid);
        try {
            taoLiJinDTO = TaoKeApiUtil.createTaoLiJin(auctionId, name, perface, totalNum, sendStartTime,
                    sendEndTime, useStartTime, useEndTime, taoKeAppInfo);
        } catch (TaoLiJinCreateException e) {
            LogHelper.errorDetailInfo(e);
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    if (e.getCode() == TaoLiJinCreateException.CODE_TLJ_FORBIDDEN) {
                        // 该商品不支持创建淘礼金红包
                        tljFreeBuyGoodsService.deleteByGoodsId(auctionId);
                    } else if (e.getCode() == TaoLiJinCreateException.CODE_TLJ_NO_MONEY) {
                        // 官方玩法钱包余额不足 TODO
                    }
                }
            });
        } catch (TaoKeApiException e) {
            LogHelper.errorDetailInfo(e);
        }
        if (taoLiJinDTO == null || StringUtil.isNullOrEmpty(taoLiJinDTO.getSendUrl()))
            throw new UserTaoLiJinNewbiesException(1, "淘宝API红包创建失败");
        return taoLiJinDTO.getSendUrl();
    }
    @Override
    public UserTaoLiJinNewbies selectByPrimaryKey(Long uid) {
        return userTaoLiJinNewbiesMapper.selectByPrimaryKey(uid);
    }
    @Override
    public long count(String key) {
        return userTaoLiJinNewbiesMapper.count(key);
    }
    @Override
    public List<UserTaoLiJinNewbies> query(int page, int count, String key, Integer order) {
        return userTaoLiJinNewbiesMapper.query((page - 1) * count, count, key, order);
    }
}