admin
2022-10-28 0e9b6603d4ae9d11c1fbc90257ce816c5807b8ff
app/src/main/java/com/yeshi/makemoney/app/service/impl/money/ExtractServiceImpl.java
@@ -18,12 +18,15 @@
import com.yeshi.makemoney.app.exception.money.UserMoneyBalanceException;
import com.yeshi.makemoney.app.service.inter.config.SystemConfigService;
import com.yeshi.makemoney.app.service.inter.money.ExtractService;
import com.yeshi.makemoney.app.service.inter.money.UserExtractMoneyLimitService;
import com.yeshi.makemoney.app.service.inter.money.UserMoneyRecordService;
import com.yeshi.makemoney.app.service.inter.money.UserMoneyService;
import com.yeshi.makemoney.app.service.inter.msg.UserMsgNotifyService;
import com.yeshi.makemoney.app.service.inter.user.UserInfoService;
import com.yeshi.makemoney.app.service.query.money.ExtractQuery;
import com.yeshi.makemoney.app.utils.Constant;
import com.yeshi.makemoney.app.utils.factory.UserMoneyRecordFactory;
import com.yeshi.makemoney.app.utils.factory.msg.UserMsgFactory;
import com.yeshi.makemoney.app.utils.mq.CMQManager;
import com.yeshi.makemoney.app.utils.pay.AlipayUtil;
import org.slf4j.Logger;
@@ -39,6 +42,7 @@
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -63,14 +67,20 @@
    @Resource
    private UserMoneyRecordService userMoneyRecordService;
    @Resource
    private UserExtractMoneyLimitService userExtractMoneyLimitService;
    @Resource
    private UserMsgNotifyService userMsgNotifyService;
    @Override
    public List<Extract> list(ExtractQuery extractQuery, int page, int pageSize) {
        DaoQuery daoQuery = new DaoQuery();
        try {
            BeanUtil.copyProperties(extractQuery, daoQuery);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        daoQuery.uid = extractQuery.getUid();
        daoQuery.state = extractQuery.getState();
        daoQuery.minCreateTime = extractQuery.toStartTime();
        daoQuery.maxCreateTime = extractQuery.toEndTime();
        daoQuery.sortList = Arrays.asList(new String[]{"create_time desc"});
        daoQuery.start = (page - 1) * pageSize;
        daoQuery.count = pageSize;
        return extractMapper.list(daoQuery);
@@ -79,11 +89,10 @@
    @Override
    public long count(ExtractQuery extractQuery) {
        DaoQuery daoQuery = new DaoQuery();
        try {
            BeanUtil.copyProperties(extractQuery, daoQuery);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        daoQuery.uid = extractQuery.getUid();
        daoQuery.state = extractQuery.getState();
        daoQuery.minCreateTime = extractQuery.toStartTime();
        daoQuery.maxCreateTime = extractQuery.toEndTime();
        return extractMapper.count(daoQuery);
    }
@@ -99,12 +108,34 @@
        return extractMapper.count(daoQuery) < 1L;
    }
    private ExtractConfig getExtractConfig(SystemEnum system) {
    @Override
    public ExtractConfig getExtractConfig(SystemEnum system) {
        String value = systemConfigService.getValueCache(system, SystemConfigKey.extractConfig);
        if (StringUtil.isNullOrEmpty(value)) {
            return null;
        }
        return new Gson().fromJson(value, ExtractConfig.class);
    }
    @Override
    public List<Extract> listNeedPassRecord(BigDecimal maxMoney, Date minCreateTime, int page, int pageSize) {
        DaoQuery daoQuery = new DaoQuery();
        daoQuery.state = Extract.STATE_NOT_PROCESS;
        daoQuery.minCreateTime = minCreateTime;
        daoQuery.maxMoney = maxMoney;
        daoQuery.sortList = Arrays.asList(new String[]{"create_time asc"});
        daoQuery.start = (page - 1) * pageSize;
        daoQuery.count = pageSize;
        return extractMapper.list(daoQuery);
    }
    @Override
    public long countNeedPassRecord(BigDecimal maxMoney, Date minCreateTime) {
        DaoQuery daoQuery = new DaoQuery();
        daoQuery.state = Extract.STATE_NOT_PROCESS;
        daoQuery.minCreateTime = minCreateTime;
        daoQuery.maxMoney = maxMoney;
        return extractMapper.count(daoQuery);
    }
    private void validateExtract(BigDecimal money, UserInfo user) throws ExtractException {
@@ -113,15 +144,11 @@
            throw new ExtractException(ExtractException.CODE_EXTRACT_CONFIG_ERROR, "提现配置错误");
        }
        if (isFirst(user.getId())) {
            if (money.compareTo(config.getFirstMinMoney()) < 0) {
                throw new ExtractException(ExtractException.CODE_MONEY_LIMIT, String.format("首次提现最低金额为%s元", config.getFirstMinMoney().toString()));
            }
        } else {
            if (money.compareTo(config.getMinMoney()) < 0) {
                throw new ExtractException(ExtractException.CODE_MONEY_LIMIT, String.format("最低提现金额为%s元", config.getMinMoney().toString()));
            }
        if (money.compareTo(config.getMinMoney()) < 0) {
            throw new ExtractException(ExtractException.CODE_MONEY_LIMIT, String.format("最低提现金额为%s元", config.getMinMoney().toString()));
        }
        if (money.compareTo(config.getMaxMoney()) > 0) {
            throw new ExtractException(ExtractException.CODE_MONEY_LIMIT, String.format("最高提现金额为%s元", config.getMaxMoney().toString()));
@@ -147,6 +174,44 @@
            throw new ExtractException(ExtractException.CODE_MONEY_LIMIT, String.format("单日累计最高提现次数为%s次", config.getMaxNumPerDay().toString()));
        }
        //小金额提现限制
        if (money.compareTo(Constant.EXTRACT_LITTLE_MONEY_LIMIT) < 0) {
            //是否已经用完新用户额度
            if (!canExtractLittleMoney(user.getId(), config.getNewerLittleMoneyNum(), new Date(currentTime))) {
                throw new ExtractException(ExtractException.CODE_LITTLE_MONEY_LIMIT, "今日小于1元提现次数已用尽");
            }
        }
    }
    @Override
    public boolean canExtractLittleMoney(Long uid, int maxNewerCount, Date date) {
        //判断新人
        long count = countByMaxMoney(uid, Constant.EXTRACT_LITTLE_MONEY_LIMIT, Arrays.asList(new Integer[]{Extract.STATE_NOT_PROCESS, Extract.STATE_PROCESSING, Extract.STATE_PASS}), null);
        if (maxNewerCount > count) {
            return true;
        }
        //判断激励分配
        int limit = userExtractMoneyLimitService.getLittleMoneyLimit(uid, date);
        if (limit <= 0) {
            return false;
        }
        count = countByMaxMoney(uid, Constant.EXTRACT_LITTLE_MONEY_LIMIT, Arrays.asList(new Integer[]{Extract.STATE_NOT_PROCESS, Extract.STATE_PROCESSING, Extract.STATE_PASS}), new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(date.getTime(), "yyyyMMdd"), "yyyyMMdd")));
        if (count < limit) {
            return true;
        }
        return false;
    }
    @Override
    public BigDecimal getExtractingMoney(Long uid) {
        DaoQuery daoQuery = new DaoQuery();
        daoQuery.uid = uid;
        daoQuery.state = Extract.STATE_NOT_PROCESS;
        BigDecimal money = extractMapper.sumMoney(daoQuery);
        return money == null ? new BigDecimal(0) : money;
    }
@@ -193,7 +258,7 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void passExtract(Long id, Long adminId) throws ExtractException {
    public void passExtract(Long id, String adminId) throws ExtractException {
        Extract extract = extractMapper.selectByPrimaryKeyForUpdate(id);
        if (extract == null) {
            throw new ExtractException(ExtractException.CODE_NOT_EXIST, "提现记录不存在");
@@ -217,15 +282,26 @@
        if (extract.getType() == ExtractPayType.alipay) {
            transferByAlipay(extract, adminId);
        } else {
            transferByWX(extract, adminId, systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.wxAppId));
          String result =  transferByWX(extract, adminId, systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.wxAppId));
            Map<String, String> resultMap = WXUtil.parseXML(result);
            if ("SUCCESS".equalsIgnoreCase(resultMap.get("return_code")) && "SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) {
                ;
            } else {
                String errCode = resultMap.get("err_code");
                String errMsg = resultMap.get("err_code_des");
                boolean noMoney = "NOTENOUGH".equalsIgnoreCase(errCode);
                if(noMoney) {
                    throw new ExtractException(ExtractException.CODE_WX_PAY_ACCOUNT_NO_MONEY,"微信支付账户余额不足");
                }
            }
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rejectExtract(Long id, Long adminId, String reason) throws ExtractException, UserMoneyBalanceException, ParamsException {
    public void rejectExtract(Long id, String adminId, String reason) throws ExtractException, UserMoneyBalanceException, ParamsException {
        Extract extract = extractMapper.selectByPrimaryKeyForUpdate(id);
        if (extract == null) {
            throw new ExtractException(ExtractException.CODE_NOT_EXIST, "提现记录不存在");
@@ -244,7 +320,12 @@
        updateExtract.setState(Extract.STATE_REJECT);
        updateExtract.setReason(reason);
        extractMapper.updateByPrimaryKeySelective(updateExtract);
        //TODO 消息
        //添加消息通知
        try {
            userMsgNotifyService.notify(UserMsgFactory.createExtractFail(extract.getUser().getId(), extract.getMoney(), reason));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
@@ -283,13 +364,23 @@
        }
    }
    @Override
    public long countByMaxMoney(Long uid, BigDecimal money, List<Integer> stateList, Date minCreateTime) {
        DaoQuery daoQuery = new DaoQuery();
        daoQuery.uid = uid;
        daoQuery.maxMoney = money;
        daoQuery.stateList = stateList;
        daoQuery.minCreateTime = minCreateTime;
        return extractMapper.count(daoQuery);
    }
    /**
     * 提现到支付宝
     *
     * @param extract
     * @param adminId
     */
    private void transferByAlipay(Extract extract, Long adminId) {
    private void transferByAlipay(Extract extract, String adminId) {
        //获取用户的系统
        UserInfo user = userInfoService.get(extract.getUser().getId());
        String appName = user.getSystem().getName();
@@ -313,18 +404,20 @@
        }
    }
    private void transferByWX(Extract extract, Long adminId, String wxAPPId) {
    private String transferByWX(Extract extract, String adminId, String wxAPPId) {
        //获取用户的系统
        UserInfo user = userInfoService.get(extract.getUser().getId());
        String appName = user.getSystem().getName();
        //理由
        String result = WXPayUtil.payToOpenId(wxAPPId, extract.getAccount(), Constant.wxTransferConfig.getMchId(), Constant.wxTransferConfig.getKey(), Constant.wxTransferConfig.getCertPwd(), this.getClass().getClassLoader().getResourceAsStream(Constant.wxTransferConfig.getCertPath()), "makemoney" + extract.getId(), extract.getMoney(), "提现", extract.getIp());
        String result = WXPayUtil.payToOpenId(wxAPPId, extract.getAccount(), Constant.wxTransferConfig.getMchId(), Constant.wxTransferConfig.getKey(), Constant.wxTransferConfig.getCertPwd(), this.getClass().getClassLoader().getResourceAsStream(Constant.wxTransferConfig.getCertPath()), "makemoney" + extract.getId(), extract.getMoney(), String.format("来自%s的提现",appName), extract.getIp());
        try {
            CMQManager.getInstance().addExtractResultMsg(new ExtractTransferResultMQMsg(extract.getId(), result, adminId));
            logger.info("提现:添加处理队列成功-" + extract.getId());
        } catch (Exception e) {
            logger.error("提现:微信提现CMQ异常:{}", result + ",提现信息" + GsonUtil.toJson(extract));
        }
        return result;
    }
@@ -360,7 +453,12 @@
                userMoneyRecordService.update(update);
            }
        }
        // TODO 通知转账成功
        //添加消息通知
        try {
            userMsgNotifyService.notify(UserMsgFactory.createExtractSuccess(extract.getUser().getId(), extract.getMoney()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
@@ -370,7 +468,7 @@
        if (noMoney) {
            Extract updateExtract = new Extract();
            updateExtract.setId(extract.getId());
            updateExtract.setState(Extract.STATE_PROCESSING);
            updateExtract.setState(Extract.STATE_NOT_PROCESS);
            updateExtract.setReason(msg);
            extractMapper.updateByPrimaryKeySelective(updateExtract);
        } else {
@@ -388,8 +486,12 @@
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 新版提现
            //TODO 通知转账被拒绝
            //添加消息通知
            try {
                userMsgNotifyService.notify(UserMsgFactory.createExtractFail(extract.getUser().getId(), extract.getMoney(), null));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }