| | |
| | | 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; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | @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); |
| | |
| | | @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); |
| | | } |
| | | |
| | |
| | | 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 { |
| | |
| | | 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())); |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | @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, "提现记录不存在"); |
| | |
| | | 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, "提现记录不存在"); |
| | |
| | | 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 |
| | |
| | | } |
| | | } |
| | | |
| | | @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(); |
| | |
| | | } |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | |
| | |
| | | userMoneyRecordService.update(update); |
| | | } |
| | | } |
| | | // TODO 通知转账成功 |
| | | //添加消息通知 |
| | | try { |
| | | userMsgNotifyService.notify(UserMsgFactory.createExtractSuccess(extract.getUser().getId(), extract.getMoney())); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | 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 { |
| | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | // 新版提现 |
| | | //TODO 通知转账被拒绝 |
| | | //添加消息通知 |
| | | try { |
| | | userMsgNotifyService.notify(UserMsgFactory.createExtractFail(extract.getUser().getId(), extract.getMoney(), null)); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |