package com.cyksj.service.pay.impl; import cn.hutool.core.date.DateTime; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import com.alipay.api.AlipayClient; import com.alipay.api.AlipayRequest; import com.alipay.api.AlipayResponse; import com.alipay.api.domain.AlipayFundTransUniTransferModel; import com.alipay.api.domain.Participant; import com.alipay.api.request.AlipayFundTransUniTransferRequest; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.EnvCommonService; import com.cyksj.common.constant.Constant; import com.cyksj.common.constant.TransferConstant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.snowflake.Sequence; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.SmsUtil; import com.cyksj.config.zfb.AliPayClientFactory; import com.cyksj.config.zfb.ZfbProductCode; import com.cyksj.dto.Result; import com.cyksj.enums.GatewayResponse; import com.cyksj.mapper.TransferAccountsRecordMapper; import com.cyksj.mapper.UserMapper; import com.cyksj.mapper.manage.distribute.DistributeMoneyApplyMapper; import com.cyksj.mapper.manage.distribute.DistributePointsExchangeMoneyMapper; import com.cyksj.mapper.manage.distribute.UserDistributeMapper; import com.cyksj.mapper.shop.YhShopDistributeMoneyApplyMapper; import com.cyksj.mapper.shop.YhShopMapper; import com.cyksj.model.entity.*; import com.cyksj.model.request.ApplyMoneyReq; import com.cyksj.model.request.TransferAccountsReq; import com.cyksj.model.request.YhShopApplyMoneyReq; import com.cyksj.service.pay.TransferFuncService; import com.cyksj.service.user.UserBenefitsService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Optional; /* *项目名: yhlxj *文件名: TransferFuncServiceImpl *创建者: JavaZou *创建时间:2023/9/20 18:55 */ @Service @RequiredArgsConstructor @Slf4j public class TransferFuncServiceImpl implements TransferFuncService { private static final Sequence SEQUENCE = new Sequence(0); private final TransferAccountsRecordMapper transferAccountsRecordMapper; private final YhShopMapper yhShopMapper; private final UserMapper userMapper; private final UserBenefitsService userBenefitsService; private final YhShopDistributeMoneyApplyMapper yhShopDistributeMoneyApplyMapper; private final EnvCommonService envCommonService; private final UserDistributeMapper userDistributeMapper; private final DistributePointsExchangeMoneyMapper distributePointsExchangeMoneyMapper; private final DistributeMoneyApplyMapper distributeMoneyApplyMapper; @Override public Result distributeApply(ApplyMoneyReq applyMoneyReq) throws Exception { applyMoneyReq.setMType(DistributeMoneyApply.MType.ds); return commonApplyMoney(applyMoneyReq); } @Override public Result yhShopDistributeApply(YhShopApplyMoneyReq applyMoneyReq) throws Exception { Long userId = applyMoneyReq.getUserId(); User user = userMapper.selectById(userId); if (user == null) { throw BusinessRuntimeException.getInstance("请先授权登录"); } Boolean isTakeAll = applyMoneyReq.getIsTakeAll(); YhShopDistributeMoneyApply.Type type = applyMoneyReq.getType(); if (type == null) type = YhShopDistributeMoneyApply.Type.zfb; if (type == YhShopDistributeMoneyApply.Type.zfb) { if (ObjectUtil.hasEmpty(applyMoneyReq.getAccount(), applyMoneyReq.getRealName())) { throw BusinessRuntimeException.getInstance("必填项不能为空"); } if (applyMoneyReq.getAccount().length() > 255 || applyMoneyReq.getRealName().length() > 32) { throw BusinessRuntimeException.getInstance("请输入正确的账户信息"); } } if (type == YhShopDistributeMoneyApply.Type.usdt) { if (StrUtil.isEmpty(applyMoneyReq.getWalletAddr())) { throw BusinessRuntimeException.getInstance("USDT提现钱包地址不能为空"); } if (applyMoneyReq.getWalletAddr().length() > 1000) { throw BusinessRuntimeException.getInstance("请输入正确的钱包地址"); } if (StrUtil.isNotBlank(applyMoneyReq.getRemark()) && applyMoneyReq.getRemark().length() > 512) { throw BusinessRuntimeException.getInstance("备注过多"); } isTakeAll = true; } YhShopDistributeMoneyApply distributeMoneyApply = null; if (type == YhShopDistributeMoneyApply.Type.pwdRed) { distributeMoneyApply = yhShopMapper.selectRelationBusiness(userId); isTakeAll = true; } BigDecimal needApplyMoney = user.getYhsMoney(); BigDecimal fourHundred = BigDecimal.valueOf(4 * 10000); if (isTakeAll == null || !isTakeAll) { if (needApplyMoney.compareTo(fourHundred) > 0) { needApplyMoney = fourHundred; } } Integer update = userMapper.subYhsMoney(user.getId(), needApplyMoney); if (update == 1) { distributeMoneyApply = Optional.ofNullable(distributeMoneyApply).orElse(new YhShopDistributeMoneyApply()); distributeMoneyApply.setUserId(userId); distributeMoneyApply.setMoney(needApplyMoney); distributeMoneyApply.setAccount(applyMoneyReq.getAccount()); distributeMoneyApply.setRealName(applyMoneyReq.getRealName()); distributeMoneyApply.setWalletAddr(applyMoneyReq.getWalletAddr()); distributeMoneyApply.setRemark(applyMoneyReq.getRemark()); distributeMoneyApply.setType(applyMoneyReq.getType()); if (isTakeAll != null && isTakeAll) { distributeMoneyApply.setVerifyStatus(YhShopDistributeMoneyApply.Status.verifying); } else { TransferAccountsReq req = new TransferAccountsReq(); req.setMoney(needApplyMoney); req.setAccount(applyMoneyReq.getAccount()); req.setName(applyMoneyReq.getRealName()); req.setChannelType(2); req.setUserId(userId); req.setRemark("小店提现"); AlipayResponse alipayResponse = transferAccounts(req); if (alipayResponse.isSuccess()) { distributeMoneyApply.setVerifyStatus(YhShopDistributeMoneyApply.Status.success); } else { distributeMoneyApply.setVerifyStatus(YhShopDistributeMoneyApply.Status.fail); distributeMoneyApply.setReason(alipayResponse.getSubMsg()); userBenefitsService.addYhsMoney(userId, distributeMoneyApply.getMoney()); if (StrUtil.equals(alipayResponse.getSubCode(), "SECURITY_CHECK_FAILED")) { return GatewayResponse.FAIL.newBuilder().setMsg("当前支付宝提现人数较多,请稍后再试").toResult(); } return GatewayResponse.FAIL.newBuilder().setMsg("目前财务清账中,48小时后可提现").toResult(); } } try { yhShopDistributeMoneyApplyMapper.insert(distributeMoneyApply); //大额提现 超过400 if (envCommonService.isPrdEnv() && distributeMoneyApply.getVerifyStatus() == YhShopDistributeMoneyApply.Status.verifying && distributeMoneyApply.getMoney().compareTo(fourHundred) > 0) { SmsUtil.sendLuoKey2Msg(Constant.ZK_MOBILE, "小店店铺有大额提现申请【银河录像局】"); } } catch (Exception e) { userBenefitsService.addYhsMoney(userId, distributeMoneyApply.getMoney()); return GatewayResponse.FAIL.newBuilder().setMsg("网络错误,请重试").toResult(); } return GatewayResponse.SUCCESS.newBuilder().toResult(distributeMoneyApply); } throw BusinessRuntimeException.getInstance("系统异常,请重新提交提现申请"); } @Override public AlipayResponse transferAccounts(TransferAccountsReq transferAccountsReq) throws Exception { Long userId = transferAccountsReq.getUserId(); String account = transferAccountsReq.getAccount(); String name = transferAccountsReq.getName(); BigDecimal money = transferAccountsReq.getMoney(); String type = transferAccountsReq.getType(); BigDecimal points = transferAccountsReq.getPoints(); Integer channelType = transferAccountsReq.getChannelType(); String remark = transferAccountsReq.getRemark(); /* 生成商户转账订单号 */ String donNo = SEQUENCE.nextId().toString(); if (StrUtil.isEmpty(type)) { type = TransferConstant.ALIPAY; } if (!envCommonService.isPrdEnv()) { name += "xx"; } Integer scope = transferAccountsReq.getScope(); AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(ShopConfig.DISTRIBUTE_ZFB_DEFAULT_APP_ID); AlipayRequest alipayRequest = aliPayTransferAccountsRequest(donNo, account, name, money, remark); AlipayResponse response = alipayClient.certificateExecute(alipayRequest); if (response.isSuccess()) { log.info("支付宝转账金额:{}至用户:{}成功", money.divide(BigDecimal.valueOf(100)), userId); saveTransferRecord(userId, donNo, account, name, money, points, type, scope, response.getBody(), null, channelType); return response; } log.info("支付宝转账金额:{}至用户:{}失败", money.divide(BigDecimal.valueOf(100)), userId); saveTransferRecord(userId, donNo, account, name, money, points, type, scope, response.getBody(), response.getSubMsg(), channelType); return response; } @Override public Result subApplyMoney(ApplyMoneyReq applyMoneyReq) throws Exception { applyMoneyReq.setMType(DistributeMoneyApply.MType.sub); return commonApplyMoney(applyMoneyReq); } private AlipayRequest aliPayTransferAccountsRequest(String donNo, String account, String name, BigDecimal money, String remark) { //支付宝转账 AlipayFundTransUniTransferRequest transUniTransferRequest = new AlipayFundTransUniTransferRequest(); //转账参数 AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel(); model.setOutBizNo(donNo); //单位元 model.setTransAmount(money.divide(BigDecimal.valueOf(100)).toString()); model.setProductCode(ZfbProductCode.STD_RED_PACKET.getProductCode()); model.setBizScene(TransferConstant.DIRECT_TRANSFER); model.setOrderTitle(remark); //红包业务必传,取值REDPACKET JSONObject businessParams = new JSONObject(); businessParams.putOpt(TransferConstant.SUB_BIZ_SCENE, TransferConstant.RED_PACKET); model.setBusinessParams(businessParams.toString()); Participant payeeInfo = new Participant(); payeeInfo.setIdentity(account); payeeInfo.setIdentityType(TransferConstant.ALIPAY_LOGON_ID); payeeInfo.setName(name); model.setPayeeInfo(payeeInfo); model.setRemark("分销提现转账"); transUniTransferRequest.setBizModel(model); return transUniTransferRequest; } public void saveTransferRecord(Long userId, String donNo, String account, String name, BigDecimal money, BigDecimal points, String type, Integer scope, String body, String error, Integer channelType) throws Exception { TransferAccountsRecord record = new TransferAccountsRecord(); JSONObject re = Jsons.parseObject(body, JSONObject.class); JSONObject response = Jsons.parseObject(re.get("alipay_fund_trans_uni_transfer_response"), JSONObject.class); String transactionId = response.getStr("order_id"); String transDate = response.getStr("trans_date"); record.setUserId(userId); record.setAccount(account); record.setName(name); record.setMoney(money); record.setType(type); record.setScope(scope); Optional.ofNullable(error).ifPresent(msg -> { record.setErrorMsg(msg); record.setStatus(0); }); record.setPoints(points); record.setTransferOutNo(donNo); record.setTransactionId(transactionId); Optional.ofNullable(transDate).ifPresent(transferTime -> record.setTransferTime(DateTime.of(transferTime, "yyyy-MM-dd HH:mm:ss"))); transferAccountsRecordMapper.insert(record); } public Result commonApplyMoney(ApplyMoneyReq applyMoneyReq) throws Exception { Long userId = applyMoneyReq.getUserId(); User user = userMapper.selectById(userId); if (user == null) { throw BusinessRuntimeException.getInstance("请先授权登录"); } if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常,请稍后再试"); Boolean isTakeAll = applyMoneyReq.getIsTakeAll(); DistributeMoneyApply.Type type = applyMoneyReq.getType(); if (type == null) type = DistributeMoneyApply.Type.zfb; if (type == DistributeMoneyApply.Type.zfb) { if (ObjectUtil.hasEmpty(applyMoneyReq.getAccount(), applyMoneyReq.getRealName())) { throw BusinessRuntimeException.getInstance("必填项不能为空"); } if (applyMoneyReq.getAccount().length() > 255 || applyMoneyReq.getRealName().length() > 32) { throw BusinessRuntimeException.getInstance("请输入正确的账户信息"); } } if (type == DistributeMoneyApply.Type.usdt) { if (StrUtil.isEmpty(applyMoneyReq.getWalletAddr())) { throw BusinessRuntimeException.getInstance("USDT提现钱包地址不能为空"); } if (applyMoneyReq.getWalletAddr().length() > 1000) { throw BusinessRuntimeException.getInstance("请输入正确的钱包地址"); } if (StrUtil.isNotBlank(applyMoneyReq.getRemark()) && applyMoneyReq.getRemark().length() > 512) { throw BusinessRuntimeException.getInstance("备注过多"); } isTakeAll = true; } DistributeMoneyApply.MType mType = applyMoneyReq.getMType(); Assert.notNull(mType, "系统异常.."); DistributeMoneyApply distributeMoneyApply = null; if (type == DistributeMoneyApply.Type.pwdRed) { distributeMoneyApply = userDistributeMapper.selectRelationBusiness(userId); isTakeAll = true; } // //今日是否已提现 // DistributeMoneyApply apply = distributeMoneyApplyMapper.selectOne(Wrappers.lambdaQuery(DistributeMoneyApply.class).eq(DistributeMoneyApply::getUserId, userId).between(DistributeMoneyApply::getCreatedTime, DateUtil.beginOfDay(DateTime.now()), DateUtil.endOfDay(DateTime.now())).last("limit 1")); // if (apply != null) { // throw BusinessRuntimeException.getInstance("今日已提现,请明日再进行操作"); // } BigDecimal userPoints = null; BigDecimal needSubPoints = null; BigDecimal needApplyMoney = null; BigDecimal fourHundred = null; if (mType == DistributeMoneyApply.MType.ds) { userPoints = user.getPoints(); DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1")); BigDecimal minPoints = BigDecimal.valueOf(distributePointsExchangeMoney.getMinPoints()); BigDecimal ratePoints = BigDecimal.valueOf(distributePointsExchangeMoney.getPoints()); BigDecimal minMoney = distributePointsExchangeMoney.getMoney(); if (userPoints.compareTo(minPoints) < 0) { throw BusinessRuntimeException.getInstance("您当前积分未达到积分门槛,无法提现"); } BigDecimal num = userPoints.divide(ratePoints, 0, RoundingMode.DOWN); needApplyMoney = num.multiply(minMoney); needSubPoints = num.multiply(ratePoints); fourHundred = BigDecimal.valueOf(4 * 100 * 100); if (isTakeAll == null || !isTakeAll) { if (needApplyMoney.compareTo(fourHundred) > 0) { needApplyMoney = fourHundred; needSubPoints = fourHundred.divide(minMoney).multiply(ratePoints); } } } if (mType == DistributeMoneyApply.MType.sub) { needApplyMoney = user.getSubApplyMoney(); if (needApplyMoney.compareTo(BigDecimal.ZERO) <= 0) { throw BusinessRuntimeException.getInstance("您暂无可提现金额.."); } } Integer update = 0; String zfbRemark = StrUtil.EMPTY; if (mType == DistributeMoneyApply.MType.ds) { update = userMapper.subPoints(user.getId(), needSubPoints); zfbRemark = Constant.APPLY_MONEY_DS; } if (mType == DistributeMoneyApply.MType.sub) { update = userMapper.suUserSubApplyMoney(user.getId(), needApplyMoney); zfbRemark = Constant.APPLY_MONEY_SUB; } if (update == 1) { distributeMoneyApply = Optional.ofNullable(distributeMoneyApply).orElse(new DistributeMoneyApply()); distributeMoneyApply.setUserId(userId); distributeMoneyApply.setPoints(needSubPoints); distributeMoneyApply.setMoney(needApplyMoney); distributeMoneyApply.setAccount(applyMoneyReq.getAccount()); distributeMoneyApply.setRealName(applyMoneyReq.getRealName()); distributeMoneyApply.setWalletAddr(applyMoneyReq.getWalletAddr()); distributeMoneyApply.setRemark(applyMoneyReq.getRemark()); distributeMoneyApply.setType(applyMoneyReq.getType()); distributeMoneyApply.setMType(applyMoneyReq.getMType()); if (isTakeAll != null && isTakeAll) { distributeMoneyApply.setVerifyStatus(DistributeMoneyApply.Status.verifying); } else { TransferAccountsReq req = new TransferAccountsReq(); req.setMoney(needApplyMoney); req.setAccount(applyMoneyReq.getAccount()); req.setName(applyMoneyReq.getRealName()); req.setPoints(needSubPoints); req.setUserId(userId); req.setChannelType(1); req.setRemark(zfbRemark); AlipayResponse alipayResponse = transferAccounts(req); if (alipayResponse.isSuccess()) { distributeMoneyApply.setVerifyStatus(DistributeMoneyApply.Status.success); } else { distributeMoneyApply.setVerifyStatus(DistributeMoneyApply.Status.fail); distributeMoneyApply.setReason(alipayResponse.getSubMsg()); if (mType == DistributeMoneyApply.MType.ds){ userBenefitsService.addDistributePoints(userId, distributeMoneyApply.getPoints()); } if (mType == DistributeMoneyApply.MType.sub) { userBenefitsService.addDistributeSubMoney(userId, needApplyMoney); } if (StrUtil.equals(alipayResponse.getSubCode(), "SECURITY_CHECK_FAILED")) { return GatewayResponse.FAIL.newBuilder().setMsg("当前支付宝提现人数较多,请稍后再试").toResult(); } return GatewayResponse.FAIL.newBuilder().setMsg("目前财务清账中,48小时后可提现").toResult(); } } try { distributeMoneyApplyMapper.insert(distributeMoneyApply); //大额提现 超过400 if (envCommonService.isPrdEnv() && distributeMoneyApply.getVerifyStatus() == DistributeMoneyApply.Status.verifying && distributeMoneyApply.getMoney().compareTo(fourHundred) > 0) { SmsUtil.sendLuoKey2Msg(Constant.ZK_MOBILE, "推广有大额提现申请【银河录像局】"); } } catch (Exception e) { userBenefitsService.addDistributePoints(userId, distributeMoneyApply.getPoints()); return GatewayResponse.FAIL.newBuilder().setMsg("网络错误,请重试").toResult(); } return GatewayResponse.SUCCESS.newBuilder().toResult(distributeMoneyApply); } throw BusinessRuntimeException.getInstance("系统异常,请重新提交提现申请"); } }