|
|
@@ -1,24 +1,43 @@
|
|
|
package com.cyksj.service.order.impl;
|
|
|
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.alipay.api.internal.util.AlipaySignature;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.cyksj.common.constant.Constant;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
|
import com.cyksj.common.snowflake.Sequence;
|
|
|
-import com.cyksj.mapper.GoodsDonSkuMapper;
|
|
|
-import com.cyksj.mapper.GoodsWholesaleMapper;
|
|
|
-import com.cyksj.mapper.GoodsWholesaleOrderDonMapper;
|
|
|
-import com.cyksj.model.entity.GoodsDonSku;
|
|
|
-import com.cyksj.model.entity.GoodsWholesale;
|
|
|
-import com.cyksj.model.entity.GoodsWholesaleOrderDon;
|
|
|
+import com.cyksj.common.util.Codec;
|
|
|
+import com.cyksj.common.util.Jsons;
|
|
|
+import com.cyksj.common.util.StringUtil;
|
|
|
+import com.cyksj.config.zfb.BaseZfbConfig;
|
|
|
+import com.cyksj.mapper.*;
|
|
|
+import com.cyksj.mapper.channel.ShopConfigMapper;
|
|
|
+import com.cyksj.mapper.sys.SysConfigMapper;
|
|
|
+import com.cyksj.model.dto.AliPayParams;
|
|
|
+import com.cyksj.model.dto.GoodsWholesaleUserDepositDto;
|
|
|
+import com.cyksj.model.entity.*;
|
|
|
+import com.cyksj.model.request.AlipayOrderDonReq;
|
|
|
import com.cyksj.model.request.GoodsWholesaleOrderPayReq;
|
|
|
+import com.cyksj.model.request.OrderAttach;
|
|
|
import com.cyksj.service.order.GoodsWholesalePayService;
|
|
|
+import com.cyksj.service.order.OrderRefundService;
|
|
|
+import com.cyksj.service.pay.AliPayCommonService;
|
|
|
+import com.cyksj.service.user.UserBenefitsService;
|
|
|
import com.cyksj.service.user.UserBindRelationService;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.util.Date;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 项目名: yhlxj
|
|
|
@@ -40,6 +59,20 @@ public class GoodsWholesalePayServiceImpl implements GoodsWholesalePayService {
|
|
|
|
|
|
private static final Sequence SEQUENCE = new Sequence(0);
|
|
|
|
|
|
+ private final AliPayCommonService aliPayCommonService;
|
|
|
+
|
|
|
+ private final ShopConfigMapper shopConfigMapper;
|
|
|
+
|
|
|
+ private final GoodsWholesaleUserReturnRecordMapper goodsWholesaleUserReturnRecordMapper;
|
|
|
+
|
|
|
+ private final SysConfigMapper sysConfigMapper;
|
|
|
+
|
|
|
+ private final GoodsWholesaleUserDepositMapper depositMapper;
|
|
|
+
|
|
|
+ private final OrderRefundService orderRefundService;
|
|
|
+
|
|
|
+ private UserBenefitsService userBenefitsService;
|
|
|
+
|
|
|
@Override
|
|
|
public GoodsWholesaleOrderDon unifiedPay(GoodsWholesaleOrderPayReq payReq) {
|
|
|
Long userId = payReq.getUserId();
|
|
|
@@ -70,17 +103,279 @@ public class GoodsWholesalePayServiceImpl implements GoodsWholesalePayService {
|
|
|
throw BusinessRuntimeException.getInstance("规格已下架");
|
|
|
}
|
|
|
//是否交过押金
|
|
|
- if (false) {
|
|
|
+ GoodsWholesaleUserDeposit deposit = depositMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserDeposit.class)
|
|
|
+ .in(GoodsWholesaleUserDeposit::getUserId, userIdList)
|
|
|
+ .last("limit 1"));
|
|
|
+ //未支付押金 或批发数量未达到且已退款 使用规格单价
|
|
|
+ if (deposit == null || (!deposit.getIsGoal() && deposit.getStatus() == GoodsWholesaleUserDeposit.Status.refund)) {
|
|
|
singlePrice = sku.getPrice();
|
|
|
}
|
|
|
GoodsWholesaleOrderDon orderDon = new GoodsWholesaleOrderDon();
|
|
|
orderDon.setUserId(userId);
|
|
|
orderDon.setGoodsId(goodsWholesale.getGoodsId());
|
|
|
orderDon.setSkuId(goodsWholesale.getSkuId());
|
|
|
+ //批发id
|
|
|
+ orderDon.setPid(id);
|
|
|
orderDon.setMoney(BigDecimal.valueOf(payReq.getNum()).multiply(singlePrice));
|
|
|
String orderNo = SEQUENCE.nextId().toString();
|
|
|
orderDon.setOrderNo(orderNo);
|
|
|
goodsWholesaleOrderDonMapper.insert(orderDon);
|
|
|
return orderDon;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AliPayParams aliPayWholesale(AlipayOrderDonReq re, String productCode, String qrPayMode) throws Exception {
|
|
|
+ if (!re.getIsDeposit()) {
|
|
|
+ return aliPayCommonService.aliPayUnifiedWholesaleDeposit(re, productCode, qrPayMode);
|
|
|
+ }
|
|
|
+ return aliPayCommonService.aliPayUnifiedWholesale(re, productCode, qrPayMode);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AliPayParams zfbWholesaleWebQrCode(AlipayOrderDonReq re, String productCode, String qrPayMode) throws Exception {
|
|
|
+ return aliPayCommonService.aliPayUnifiedWholesale(re, productCode, qrPayMode);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void aliPayWholesaleNotify(Map<String, String> params) throws Exception {
|
|
|
+ //调用SDK验证签名
|
|
|
+ String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
|
|
|
+ OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
|
|
|
+ Long oderId = orderAttach.getO();
|
|
|
+ GoodsWholesaleOrderDon orderDon = goodsWholesaleOrderDonMapper.selectById(oderId);
|
|
|
+ if (null == orderDon) {
|
|
|
+ throw BusinessRuntimeException.getInstance("订单不存在.");
|
|
|
+ }
|
|
|
+ String appId = params.get("app_id");
|
|
|
+ boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
|
|
|
+ if (!signVerified) {
|
|
|
+ log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
|
|
|
+ throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
|
|
|
+ }
|
|
|
+ String transactionId = params.get("trade_no");
|
|
|
+ String payTimeStr = params.get("gmt_payment");
|
|
|
+ //买家支付宝账号
|
|
|
+ String buyerId = Optional.ofNullable(params.get("buyer_id")).orElse(params.get("buyer_open_id"));
|
|
|
+ log.info("批发支付宝回调信息:{}", Jsons.toJson(params));
|
|
|
+ if (!orderDon.getStatus().equals(UpgradeOrderDon.Status.noPayment) && !orderDon.getStatus().equals(UpgradeOrderDon.Status.close)) {
|
|
|
+ log.info("批发支付宝已回调,重复修改状态 id:{}", orderDon.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Date payTime = DateTime.now();
|
|
|
+ if (StringUtils.isNotBlank(payTimeStr)) {
|
|
|
+ payTime = DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss");
|
|
|
+ }
|
|
|
+ // 更改订单状态
|
|
|
+ orderDon.setTransactionId(transactionId);
|
|
|
+ orderDon.setPayTime(payTime);
|
|
|
+ orderDon.setShopId(appId);
|
|
|
+ orderDon.setType(GoodsWholesaleOrderDon.Type.ALI_PAY);
|
|
|
+ orderDon.setBuyerId(buyerId);
|
|
|
+ goodsWholesaleOrderDonMapper.updateById(orderDon);
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null);
|
|
|
+ //退还押金
|
|
|
+ returnDeposit(orderDon, userIdList);
|
|
|
+ //返批发余额差价
|
|
|
+ returnWholesaleBalanceDiffer(orderDon, userIdList);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void returnWholesaleBalanceDiffer(GoodsWholesaleOrderDon orderDon, List<Long> userIdList) throws Exception {
|
|
|
+ //批发补差价
|
|
|
+ Long skuId = orderDon.getSkuId();
|
|
|
+ GoodsWholesale goodsWholesale = goodsWholesaleMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesale.class)
|
|
|
+ .eq(GoodsWholesale::getSkuId, skuId)
|
|
|
+ .eq(GoodsWholesale::getDeleted, 1)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (goodsWholesale != null && goodsWholesale.getIsReturn()) {
|
|
|
+ //目前购买多少个
|
|
|
+ Integer payNum = goodsWholesaleOrderDonMapper.getUserWholesaleNumByUserIds(userIdList);
|
|
|
+ log.info("目前用户userId:{}购买批发数量:{}", orderDon.getUserId(), payNum);
|
|
|
+ List<GoodsWholesale.GoodsWholesaleConfig> configs = Jsons.parseList(goodsWholesale.getConfig(), GoodsWholesale.GoodsWholesaleConfig.class);
|
|
|
+ GoodsWholesale.GoodsWholesaleConfig firstConfig = configs.get(0);
|
|
|
+ GoodsWholesale.GoodsWholesaleConfig endConfig = configs.get(configs.size() - 1);
|
|
|
+ //移除第一档
|
|
|
+ configs.remove(firstConfig);
|
|
|
+ //移除倒数第一档
|
|
|
+ configs.remove(endConfig);
|
|
|
+ //未超过第一档
|
|
|
+ if (payNum <= firstConfig.getEnd()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ GoodsWholesaleUserReturnRecord goodsWholesaleUserReturnRecord = goodsWholesaleUserReturnRecordMapper.selectGoodsWholeReturnBalanceRecordByUserId(userIdList);
|
|
|
+ //直接买到最高
|
|
|
+ Integer priceDifferNum = null;
|
|
|
+ BigDecimal differPrice = null;
|
|
|
+ if (payNum > endConfig.getEnd()) {
|
|
|
+ //将之前的全部返还余额差价
|
|
|
+ priceDifferNum = endConfig.getStart() - 1;
|
|
|
+ if (goodsWholesaleUserReturnRecord != null) {
|
|
|
+ //减去之前返差价的数目
|
|
|
+ priceDifferNum = priceDifferNum - goodsWholesaleUserReturnRecord.getNum();
|
|
|
+ }
|
|
|
+ differPrice = endConfig.getSingle().subtract(firstConfig.getSingle());
|
|
|
+ }
|
|
|
+ if (goodsWholesaleUserReturnRecord != null) {
|
|
|
+ //寻找符合条件的目前挡位的配置
|
|
|
+ Optional<GoodsWholesale.GoodsWholesaleConfig> first = configs.stream().filter(config -> config.getStart() < goodsWholesaleUserReturnRecord.getNum() && config.getEnd() > goodsWholesaleUserReturnRecord.getNum()).collect(Collectors.toList()).stream().findFirst();
|
|
|
+ if (first.isPresent()) {
|
|
|
+ GoodsWholesale.GoodsWholesaleConfig thisLevel = first.get();
|
|
|
+ log.info("目前批发挡位设置是start:{} ======> end:{}", thisLevel.getStart(), thisLevel.getEnd());
|
|
|
+ priceDifferNum = thisLevel.getStart() - 1;
|
|
|
+ if (goodsWholesaleUserReturnRecord != null) {
|
|
|
+ priceDifferNum = priceDifferNum - goodsWholesaleUserReturnRecord.getNum();
|
|
|
+ }
|
|
|
+ differPrice = thisLevel.getSingle().subtract(firstConfig.getSingle());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (priceDifferNum != null && differPrice != null) {
|
|
|
+ BigDecimal returnBalance = differPrice.multiply(BigDecimal.valueOf(priceDifferNum));
|
|
|
+ log.info("返用户userId:{}批发余额:{}分", orderDon.getUserId(), returnBalance);
|
|
|
+ //记录返差价数量
|
|
|
+ GoodsWholesaleUserReturnRecord wholesaleUserReturnRecord = Optional.ofNullable(goodsWholesaleUserReturnRecord).orElseGet(() -> {
|
|
|
+ GoodsWholesaleUserReturnRecord newRecord = new GoodsWholesaleUserReturnRecord();
|
|
|
+ newRecord.setNum(0);
|
|
|
+ newRecord.setGoodsId(orderDon.getGoodsId());
|
|
|
+ newRecord.setSkuId(orderDon.getSkuId());
|
|
|
+ newRecord.setReturnBalance(BigDecimal.ZERO);
|
|
|
+ newRecord.setUserId(orderDon.getUserId());
|
|
|
+ return newRecord;
|
|
|
+ });
|
|
|
+ wholesaleUserReturnRecord.setNum(wholesaleUserReturnRecord.getNum() + priceDifferNum);
|
|
|
+ wholesaleUserReturnRecord.setReturnBalance(wholesaleUserReturnRecord.getReturnBalance().add(returnBalance));
|
|
|
+ if (wholesaleUserReturnRecord.getId() != null) {
|
|
|
+ goodsWholesaleUserReturnRecordMapper.updateById(wholesaleUserReturnRecord);
|
|
|
+ } else {
|
|
|
+ goodsWholesaleUserReturnRecordMapper.insert(wholesaleUserReturnRecord);
|
|
|
+ }
|
|
|
+ //返余额差价
|
|
|
+ userBenefitsService.addUserBalance(orderDon.getUserId(), returnBalance, UserBalanceSourceRecord.Source.wholesale_differ, 0l, orderDon.getId(), UserBalanceSourceRecord.Source.wholesale_differ.getDesc(), true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public GoodsWholesaleUserDeposit submitDeposit(Long userId) throws Exception {
|
|
|
+ //是否已支付押金
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+
|
|
|
+ GoodsWholesaleUserDeposit deposit = depositMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserDeposit.class).in(GoodsWholesaleUserDeposit::getUserId, userIdList));
|
|
|
+ if (deposit != null && deposit.getStatus() == GoodsWholesaleUserDeposit.Status.hasPayment) {
|
|
|
+ throw BusinessRuntimeException.getInstance("您已支付过押金");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (deposit == null) {
|
|
|
+ deposit = new GoodsWholesaleUserDeposit();
|
|
|
+ deposit.setUserId(userId);
|
|
|
+ String orderNo = SEQUENCE.nextId().toString();
|
|
|
+ deposit.setOrderNo(orderNo);
|
|
|
+ deposit.setType(GoodsWholesaleUserDeposit.Type.ALI_PAY);
|
|
|
+ }
|
|
|
+ deposit.setStatus(GoodsWholesaleUserDeposit.Status.noPayment);
|
|
|
+ SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
|
|
|
+ .eq(SysConfig::getSysKey, Constant.WHOLESALE_DEPOSIT_KEY)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
|
|
|
+ throw BusinessRuntimeException.getInstance("未配置押金,请联系客服");
|
|
|
+ }
|
|
|
+ GoodsWholesaleUserDepositDto goodsWholesaleUserDepositDto = Jsons.parseObject(sysConfig.getSysValue(), GoodsWholesaleUserDepositDto.class);
|
|
|
+ deposit.setMoney(goodsWholesaleUserDepositDto.getDeposit());
|
|
|
+
|
|
|
+ if (deposit.getId() == null) {
|
|
|
+ depositMapper.insert(deposit);
|
|
|
+ }
|
|
|
+ return deposit;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void aliPayWholesaleDepositNotify(Map<String, String> params) throws Exception {
|
|
|
+ //调用SDK验证签名
|
|
|
+ String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
|
|
|
+ OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
|
|
|
+ Long oderId = orderAttach.getO();
|
|
|
+ GoodsWholesaleUserDeposit orderDon = depositMapper.selectById(oderId);
|
|
|
+ if (null == orderDon) {
|
|
|
+ throw BusinessRuntimeException.getInstance("订单不存在.");
|
|
|
+ }
|
|
|
+ String appId = params.get("app_id");
|
|
|
+ boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
|
|
|
+ if (!signVerified) {
|
|
|
+ log.error("押金支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
|
|
|
+ throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
|
|
|
+ }
|
|
|
+ String transactionId = params.get("trade_no");
|
|
|
+ String payTimeStr = params.get("gmt_payment");
|
|
|
+ //买家支付宝账号
|
|
|
+ String buyerId = Optional.ofNullable(params.get("buyer_id")).orElse(params.get("buyer_open_id"));
|
|
|
+ log.info("押金支付宝回调信息:{}", Jsons.toJson(params));
|
|
|
+ if (!orderDon.getStatus().equals(UpgradeOrderDon.Status.noPayment) && !orderDon.getStatus().equals(UpgradeOrderDon.Status.close)) {
|
|
|
+ log.info("押金支付宝已回调,重复修改状态 id:{}", orderDon.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Date payTime = DateTime.now();
|
|
|
+ if (StringUtils.isNotBlank(payTimeStr)) {
|
|
|
+ payTime = DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss");
|
|
|
+ }
|
|
|
+ // 更改订单状态
|
|
|
+ orderDon.setTransactionId(transactionId);
|
|
|
+ orderDon.setPayTime(payTime);
|
|
|
+ orderDon.setShopId(appId);
|
|
|
+ orderDon.setType(GoodsWholesaleUserDeposit.Type.ALI_PAY);
|
|
|
+ orderDon.setBuyerId(buyerId);
|
|
|
+ depositMapper.updateById(orderDon);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void closeWholesaleOrder(Long orderId, long userId) {
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ GoodsWholesaleOrderDon orderDon = goodsWholesaleOrderDonMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleOrderDon.class)
|
|
|
+ .eq(GoodsWholesaleOrderDon::getId, orderId)
|
|
|
+ .in(GoodsWholesaleOrderDon::getUserId, userIdList)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (orderDon == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (orderDon.getStatus() != GoodsWholesaleOrderDon.Status.noPayment) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ orderDon.setStatus(GoodsWholesaleOrderDon.Status.close);
|
|
|
+ goodsWholesaleOrderDonMapper.updateById(orderDon);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退还押金
|
|
|
+ */
|
|
|
+ public void returnDeposit(GoodsWholesaleOrderDon orderDon, List<Long> userIdList) throws Exception {
|
|
|
+ GoodsWholesaleUserDeposit goodsWholesaleUserDeposit = depositMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserDeposit.class)
|
|
|
+ .in(GoodsWholesaleUserDeposit::getUserId, userIdList)
|
|
|
+ .eq(GoodsWholesaleUserDeposit::getStatus, GoodsWholesaleUserDeposit.Status.hasPayment)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (goodsWholesaleUserDeposit != null) {
|
|
|
+ //是否已满足 批发足够账号
|
|
|
+ SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
|
|
|
+ .eq(SysConfig::getSysKey, Constant.WHOLESALE_DEPOSIT_KEY)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
|
|
|
+ log.error("押金配置已失效");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ GoodsWholesaleUserDepositDto goodsWholesaleUserDepositDto = Jsons.parseObject(sysConfig.getSysValue(), GoodsWholesaleUserDepositDto.class);
|
|
|
+ Integer num = goodsWholesaleUserDepositDto.getNum();
|
|
|
+ Integer payNum = goodsWholesaleOrderDonMapper.getUserWholesaleNumByUserIds(userIdList);
|
|
|
+ if (payNum >= num) {
|
|
|
+ //腿还押金
|
|
|
+ try {
|
|
|
+ String outNo = orderRefundService.refundWholesaleUserDeposit(goodsWholesaleUserDeposit);
|
|
|
+ goodsWholesaleUserDeposit.setRefundOutNo(outNo);
|
|
|
+ goodsWholesaleUserDeposit.setStatus(GoodsWholesaleUserDeposit.Status.refund);
|
|
|
+ //批发数量已达
|
|
|
+ goodsWholesaleUserDeposit.setIsGoal(true);
|
|
|
+ depositMapper.updateById(goodsWholesaleUserDeposit);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("押金退款错误:{}", StringUtil.getErrorText(e));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|