admin
2021-06-23 b47f8a03db79bb1f6356479cd8a5cf190d7d9694
service-lijin/src/main/java/com/ks/lijin/service/remote/LijinCreateServiceImpl.java
@@ -3,9 +3,11 @@
import com.ks.lijin.exception.*;
import com.ks.lijin.mapper.LiJinExpendRecordMapper;
import com.ks.lijin.pojo.DO.LiJinExpendRecord;
import com.ks.lijin.pojo.DO.LiJinProviderAccount;
import com.ks.lijin.pojo.DO.LiJinProviderTaoKeAccount;
import com.ks.lijin.pojo.DO.LiJinProviderNotice;
import com.ks.lijin.pojo.DTO.LiJinCreateParam;
import com.ks.lijin.pojo.DTO.MoneyInfo;
import com.ks.lijin.pojo.DTO.TaoLijinCreateResultDTO;
import com.ks.lijin.pojo.DTO.taobao.TaoKeAppInfo;
import com.ks.lijin.pojo.DTO.taobao.TaoLiJinDTO;
import com.ks.lijin.pojo.Enums.NoticeTypeEnum;
@@ -13,6 +15,10 @@
import com.ks.lijin.service.LiJinProviderAccountService;
import com.ks.lijin.service.LiJinProviderNoticeService;
import com.ks.lijin.service.LijinCreateService;
import com.ks.lijin.service.manager.LiJinProviderTaoKeAccountManager;
import com.ks.lijin.service.manager.LijinConfigManager;
import com.ks.lijin.service.manager.LijinDangerGoodsManager;
import com.ks.lijin.service.manager.LijinGoodsManager;
import com.ks.lijin.util.Constant;
import com.ks.lijin.utils.taobao.TaoBaoUtil;
import com.ks.lijin.utils.taobao.TaoKeApiUtil;
@@ -20,18 +26,24 @@
import com.ks.vip.pojo.Enums.VIPEnum;
import com.ks.vip.service.VipCenterService;
import com.ks.vip.service.VipGradePotenceService;
import com.ks.vip.service.VipGradeService;
import com.yeshi.goods.facade.entity.taobao.TaoBaoGoodsBrief;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.MoneyBigDecimalUtil;
import org.yeshi.utils.StringUtil;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service(version = "1.0")
@@ -49,18 +61,75 @@
    @Resource
    private LiJinProviderAccountService liJinProviderAccountService;
    @Resource
    @Reference(version = "1.0", check = false)
    private VipCenterService vipCenterService;
    @Resource
    @Reference(version = "1.0", check = false)
    private VipGradePotenceService vipGradePotenceService;
    @Reference(version = "1.0", check = false)
    private VipGradeService vipGradeService;
    @Resource
    private LiJinExpendRecordService liJinExpendRecordService;
    @Resource
    private LiJinProviderTaoKeAccountManager liJinProviderTaoKeAccountManager;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private LijinGoodsManager lijinGoodsManager;
    @Resource
    private LijinDangerGoodsManager lijinDangerGoodsManager;
    @Resource
    private LijinConfigManager lijinConfigManager;
    @Override
    public List<MoneyInfo> getMoneyInfo(String uid, List<TaoBaoGoodsBrief> goodsBriefList) {
        VIPEnum vipRank = null;
        if (!StringUtil.isNullOrEmpty(uid)) {
            vipRank = vipCenterService.getVIPEnumByUid(uid);
        }
        if (vipRank == null) {
            vipRank = vipGradeService.getDefaultGrade().getIdentity();
        }
        VipGradePotence potence = vipGradePotenceService.getPotenceByVipEnum(vipRank);
        List<MoneyInfo> list = new ArrayList<>();
        for (TaoBaoGoodsBrief goods : goodsBriefList) {
            MoneyInfo moneyInfo = new MoneyInfo();
            moneyInfo.setGoodsId(goods.getAuctionId() + "");
            moneyInfo.setGoodsType(1);
            try {
                moneyInfo.setLijinAmount(getTBLijinAmount(goods, vipRank));
            } catch (LiJinGoodsException e) {
                e.printStackTrace();
            } catch (LiJinAmountException e) {
                e.printStackTrace();
            }
            //计算返利比例
            BigDecimal rebateRate = potence.getRebatePercent();
            BigDecimal fanliMoney = TaoBaoUtil.getGoodsHongBaoMoney(goods, rebateRate, false);
            moneyInfo.setFanliAmount(fanliMoney);
            moneyInfo.setFirstOrderAmount(null);
            list.add(moneyInfo);
        }
        //获取
        return list;
    }
    @Override
    public BigDecimal getTBLijinAmount(Long actionId, String uid) throws LiJinGoodsException, LiJinUserException, LiJinAmountException {
        if (!lijinGoodsManager.todayCanCreate(actionId)) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_CREATED_FULL, "今日礼金创建次数已达上限");
        }
        // 获取用户等级
        VIPEnum vipRank = vipCenterService.getVIPEnumByUid(uid);
        if (vipRank == null) {
@@ -69,6 +138,10 @@
        // 1、判断商品 并计算金额
        BigDecimal money = getTBLijinAmount(actionId, vipRank);
        if (!lijinGoodsManager.isLijinMoneyAvaiable(money)) {
            throw new LiJinAmountException(LiJinAmountException.CODE_LIJIN_AMOUNT_OUTOFRANGE, "礼金未在规定范围内");
        }
        // 2、判断用户
        boolean result = userCanCreateTBLijin(uid, money);
@@ -81,6 +154,10 @@
    @Override
    public BigDecimal getTBLijinAmount(Long actionId, VIPEnum vipRank) throws LiJinGoodsException, LiJinAmountException {
        if (!lijinGoodsManager.todayCanCreate(actionId)) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_CREATED_FULL, "今日礼金创建次数已达上限");
        }
        //获取商品可创建的淘礼金面额,若不能创建需要抛出相关的异常(1.商品不支持礼金创建)
        BigDecimal money = null;
        // 1、判断商品
@@ -97,23 +174,24 @@
            //券后价 * 商品佣金比例 * 返利比例
            VipGradePotence potence = vipGradePotenceService.getPotenceByVipEnum(vipRank);
            if (potence != null && potence.getRebatePercent() != null) {
                money = TaoBaoUtil.getGoodsHongBaoMoney(goods, potence.getRebatePercent(), false);
            if (potence != null && potence.getTaolijinPercent() != null) {
                money = TaoBaoUtil.getGoodsHongBaoMoney(goods, potence.getTaolijinPercent(), false);
            }
        } catch (TaoBaoGoodsDownException e) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_OFFLINE, "商品下线");
        }
        // 金额为空 或者小于零 则抛出异常
        if (money == null || money.compareTo(BigDecimal.valueOf(0)) <= 0) {
            throw new LiJinAmountException(LiJinAmountException.CODE_LIJIN_AMOUNT_OUTOFRANGE, "礼金创建的金额超出规定范围");
        if (!lijinGoodsManager.isLijinMoneyAvaiable(money)) {
            throw new LiJinAmountException(LiJinAmountException.CODE_LIJIN_AMOUNT_OUTOFRANGE, "礼金未在规定范围内");
        }
        return money;
    }
    @Override
    public boolean userCanCreateTBLijin(String uid) throws LiJinUserException {
    public boolean userCanCreateTBLijin(String uid, Date registerDate) throws LiJinUserException {
        VipGradePotence potence = vipCenterService.getVipPotence(uid);
        if (potence == null) {
            return false;
@@ -133,7 +211,19 @@
        // 使用次数已经超过最大次数
        int numExpend = liJinExpendRecordService.countTodayNumByExpend(uid);
        if (numMax.intValue() < numExpend) {
        if (registerDate != null) {
            //判断新用户
            String newerHour = lijinConfigManager.getConfigValue("newer-hour");
            String dayPlusCount = lijinConfigManager.getConfigValue("newer-everyday-plus-lijin-count");
            if (!StringUtil.isNullOrEmpty(newerHour) && !StringUtil.isNullOrEmpty(dayPlusCount)) {
                //新用户每日附加次数
                if (System.currentTimeMillis() - registerDate.getTime() < 1000 * 60 * 60L * Integer.parseInt(dayPlusCount)) {
                    numExpend += Integer.parseInt(dayPlusCount);
                }
            }
        }
        if (numMax.intValue() <= numExpend) {
            throw new LiJinUserException(LiJinUserException.CODE_USER_CREATE_NUM_LIMIT, "用户创建淘礼金的次数超限");
        }
@@ -194,8 +284,27 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LiJinExpendRecord createTBLijin(String uid, Long goodsId) throws LiJinException, LiJinGoodsException, LiJinUserException, LiJinAmountException {
        return createTBLijin(uid, null, goodsId);
    }
    @Override
    public LiJinExpendRecord createTBLijin(String uid, Date registerDate, Long auctionId) throws LiJinException, LiJinGoodsException, LiJinUserException, LiJinAmountException {
        //用户是否有创建权限
        userCanCreateTBLijin(uid, registerDate);
        //商品是否在危险商品中
        boolean dangerous = lijinDangerGoodsManager.isDangerous(auctionId + "", 1);
        if (dangerous) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_NOT_SUPPORT, "该商品暂无法创建礼金");
        }
        // 获取用户等级
        VIPEnum vipRank = vipCenterService.getVIPEnumByUid(uid);
        if (vipRank == null) {
            vipRank = vipGradeService.getDefaultGrade().getIdentity();
        }
        if (vipRank == null) {
            throw new LiJinUserException(LiJinUserException.CODE_USER_CREATE_NUM_LIMIT, "用户创建淘礼金的次数超限");
        }
@@ -203,7 +312,7 @@
        //淘礼金创建
        TaoBaoGoodsBrief goods = null;
        try {
            goods = TaoKeApiUtil.searchGoodsDetail(goodsId);
            goods = TaoKeApiUtil.searchGoodsDetail(auctionId);
        } catch (TaoBaoGoodsDownException e) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_OFFLINE, "商品下线");
        }
@@ -215,32 +324,66 @@
        BigDecimal lijinAmount = getTBLijinAmount(goods, vipRank);
        // 执行创建淘礼金
        LiJinCreateParam params = getLiJinCreateParam();
        LiJinCreateParam params = getLiJinCreateBaseParam();
        TaoLiJinDTO taoLiJinDTO = executeTaoLiJinAPI(uid, goodsId, lijinAmount, params);
        if (taoLiJinDTO == null) {
            throw new LiJinException(1, "淘宝API推广红包创建失败");
        //用户创建淘礼金为单线程操作
        String key = "createtblijin-" + uid;
        if (redisTemplate.opsForValue().setIfAbsent(key, "1", 120, TimeUnit.SECONDS)) {
            Date now = new Date();
            try {
                TaoLijinCreateResultDTO taoLiJinDTO = executeTaoLiJin(auctionId, lijinAmount, params);
                if (taoLiJinDTO == null) {
                    throw new LiJinException(1, "淘宝API推广红包创建失败");
                }
                //添加账号的
                return addCreateSuccessRecord(uid, auctionId, lijinAmount, params.getTitle(), params.getNum(), taoLiJinDTO);
            } catch (LiJinGoodsException e) {
                if (e.getCode() == LiJinGoodsException.CODE_GOODS_CREATED_FULL) {
                    lijinGoodsManager.createdFullToday(auctionId, now);
                }
                throw e;
            } finally {
                redisTemplate.delete(key);
            }
        } else {
            throw new LiJinException(LiJinException.CODE_SERVER_BUSY, "服务器繁忙,请稍后再试");
        }
    }
    /**
     * 添加创建记录
     *
     * @param uid
     * @param goodsId
     * @param lijinAmount
     * @param title
     * @param num
     * @param taoLiJinDTO
     */
    private LiJinExpendRecord addCreateSuccessRecord(String uid, Long goodsId, BigDecimal lijinAmount, String title, int num, TaoLijinCreateResultDTO taoLiJinDTO) {
        Date now = new Date();
        // 保存记录
        LiJinExpendRecord record = new LiJinExpendRecord();
        record.setUid(uid);
        record.setGoodsId(goodsId + "");
        record.setTitle(params.getTitle());
        record.setNum(params.getNum());
        record.setTitle(title);
        record.setNum(num);
        record.setMoney(lijinAmount);
        record.setRightsId(taoLiJinDTO.getRightsId());
        record.setSendUrl(taoLiJinDTO.getSendUrl());
        record.setAccountId(taoLiJinDTO.getAccount().getId());
        record.setRightsId(taoLiJinDTO.getTaoLiJin().getRightsId());
        record.setSendUrl(taoLiJinDTO.getTaoLiJin().getSendUrl());
        record.setCreateTime(new Date());
        liJinExpendRecordMapper.insertSelective(record);
        //添加
        liJinProviderTaoKeAccountManager.createLijinSuccess(taoLiJinDTO.getAccount().getId(), goodsId, lijinAmount.multiply(new BigDecimal(num)), now);
        return record;
    }
    /**
     * 调用账号以及淘宝API
     * @param uid
     *
     * @param goodsId
     * @param lijinAmount
     * @param params
@@ -248,24 +391,39 @@
     * @throws LiJinGoodsException
     * @throws LiJinException
     */
    private TaoLiJinDTO executeTaoLiJinAPI(String uid, Long goodsId, BigDecimal lijinAmount, LiJinCreateParam params) throws LiJinGoodsException, LiJinException {
    private TaoLijinCreateResultDTO executeTaoLiJin(Long goodsId, BigDecimal lijinAmount, LiJinCreateParam params) throws LiJinGoodsException, LiJinException, LiJinAmountException {
        // 查询供应商账号信息
        List<LiJinProviderAccount> listAccount = liJinProviderAccountService.listByProviderId(Constant.PROVIDER_DEFAULT_ID);
        List<LiJinProviderTaoKeAccount> listAccount = liJinProviderAccountService.listValidByProviderId(Constant.PROVIDER_DEFAULT_ID, LiJinProviderTaoKeAccount.ERROR_CODE_NORMAL);
        if (listAccount == null || listAccount.size() == 0) {
            throw new LiJinException(1, "供应商账号不存在");
            throw new LiJinException(1, "没有可用的供应商账号");
        }
        TaoLiJinDTO taoLiJinDTO = null;
        // 遍历账号 用可使用账号
        for (LiJinProviderAccount account : listAccount) {
        for (LiJinProviderTaoKeAccount account : listAccount) {
            params.setAppkey(account.getAppKey());
            params.setAppsecret(account.getAppSecret());
            params.setPid(account.getPid());
            try {
                taoLiJinDTO = executeTaoLiJinAPI(uid, goodsId, lijinAmount, params);
                if (taoLiJinDTO != null) {
                    break;
                //创建礼金
                return new TaoLijinCreateResultDTO(account, executeTaoLiJinAPI(goodsId, lijinAmount, params));
            } catch (LiJinAccountException e) {// 账号问题
                //更新账号的错误信息
                LiJinProviderTaoKeAccount update = new LiJinProviderTaoKeAccount();
                update.setId(account.getId());
                if (e.getCode() == LiJinAccountException.CODE_TLJ_NO_MONEY) {
                    //资金不足
                    update.setErrorCode(LiJinProviderTaoKeAccount.ERROR_CODE_MONEY_NOT_ENOUGH);
                } else if (e.getCode() == LiJinAccountException.CODE_TLJ_NO_GOODS) {
                    //商品数量不足
                    update.setErrorCode(LiJinProviderTaoKeAccount.ERROR_CODE_GOODS_NOT_ENOUGH);
                } else {
                    //账号异常
                    update.setErrorCode(LiJinProviderTaoKeAccount.ERROR_CODE_OTHER);
                }
            } catch (LiJinException e) {
                update.setErrorMsg(e.getMsg());
                update.setUpdateTime(new Date());
                liJinProviderAccountService.updateByPrimaryKeySelective(update);
                // 通知相应供应商  TODO
                executor.execute(new Runnable() {
                    @Override
@@ -273,36 +431,44 @@
                        LiJinProviderNotice notice = new LiJinProviderNotice();
                        notice.setRead(false);
                        notice.setProviderId(account.getProviderId());
                       if (e.getCode() == LiJinException.CODE_TLJ_NO_MONEY) {
                        if (e.getCode() == LiJinAccountException.CODE_TLJ_NO_MONEY) {
                            // 官方玩法钱包余额不足
                            notice.setTitle("玩法钱包余额不足");
                            notice.setContent("账号:" + account.getAccountName() + "官方玩法钱包余额不足");
                            notice.setType(NoticeTypeEnum.noMoney.name());
                            liJinProviderNoticeService.save(notice);
                        } else if (e.getCode() == LiJinException.CODE_TLJ_UN_PAID) {
                        } else if (e.getCode() == LiJinAccountException.CODE_TLJ_UN_PAID) {
                            // 未创建账户
                        }
                    }
                });
            }
        }
        throw new LiJinException(1, "没有可用的供应商账号");
    }
        // 创建淘礼金红包
    private TaoLiJinDTO executeTaoLiJinAPI(Long goodsId, BigDecimal lijinAmount, LiJinCreateParam params) throws LiJinException, LiJinGoodsException, LiJinAccountException, LiJinAmountException {
        return TaoKeApiUtil.createTaoLiJin(goodsId, params.getTitle(), lijinAmount,
                params.getNum(), params.getSendStartTime(), params.getSendEndTime(),
                params.getUseStartTime(), params.getUseEndTime(), new TaoKeAppInfo(params.getAppkey(), params.getAppsecret(), params.getPid()));
    }
    /**
     * 获取商品可创建的礼金金额
     * @param goods 商品
     * @param vipRank  会员等级
     *
     * @param goods   商品
     * @param vipRank 会员等级
     * @return
     * @throws LiJinGoodsException
     * @throws LiJinAmountException
     */
    private BigDecimal getTBLijinAmount(TaoBaoGoodsBrief goods, VIPEnum vipRank) throws
            LiJinGoodsException, LiJinAmountException {
        if (!lijinGoodsManager.todayCanCreate(goods.getAuctionId())) {
            throw new LiJinGoodsException(LiJinGoodsException.CODE_GOODS_CREATED_FULL, "今日礼金创建次数已达上限");
        }
        //获取商品可创建的淘礼金面额,若不能创建需要抛出相关的异常(1.商品不支持礼金创建)
        BigDecimal money = null;
@@ -313,14 +479,14 @@
        //券后价 * 商品佣金比例 * 返利比例
        VipGradePotence potence = vipGradePotenceService.getPotenceByVipEnum(vipRank);
        if (potence != null && potence.getRebatePercent() != null) {
            money = TaoBaoUtil.getGoodsHongBaoMoney(goods, potence.getRebatePercent(), false);
        if (potence != null && potence.getTaolijinPercent() != null) {
            money = TaoBaoUtil.getGoodsHongBaoMoney(goods, potence.getTaolijinPercent(), false);
        }
        // 金额为空 或者小于零 则抛出异常
        if (money == null || money.compareTo(BigDecimal.valueOf(0)) <= 0) {
            throw new LiJinAmountException(LiJinAmountException.CODE_LIJIN_AMOUNT_OUTOFRANGE, "礼金创建的金额超出规定范围");
        if (!lijinGoodsManager.isLijinMoneyAvaiable(money)) {
            throw new LiJinAmountException(LiJinAmountException.CODE_LIJIN_AMOUNT_OUTOFRANGE, "礼金未在规定范围内");
        }
        return money;
    }
@@ -329,7 +495,7 @@
     *
     * @return
     */
    private LiJinCreateParam getLiJinCreateParam() {
    private LiJinCreateParam getLiJinCreateBaseParam() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");