From ea8fec4b56d4a5cce828c15d72b08219f5844126 Mon Sep 17 00:00:00 2001 From: xiaohanzi Date: Sat, 13 Jun 2020 21:23:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8B=BC=E5=9B=A2=E3=80=81?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E3=80=81=E9=80=80=E6=AC=BE=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=97=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../schedule/OrderExpiringSchedule.java | 127 ++++++++++++++---- .../iformall/service/WxPayOrderService.java | 2 + .../service/impl/WxOrderGroupServiceImpl.java | 28 ++-- .../service/impl/WxPayOrderServiceImpl.java | 1 + .../impl/WxRefundOrderServiceImpl.java | 52 ++++--- 5 files changed, 156 insertions(+), 54 deletions(-) diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java index 156c2c39e..fa5411138 100644 --- a/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java @@ -1,33 +1,45 @@ package com.iformall.schedule; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.iformall.common.ErrorCode; import com.iformall.domain.po.WxAppinfo; +import com.iformall.domain.po.WxCUser; import com.iformall.domain.po.WxOrder; +import com.iformall.domain.po.WxPayAccount; +import com.iformall.domain.po.WxPayOrder; import com.iformall.enums.EnumAppType; import com.iformall.enums.EnumOrderStatus; import com.iformall.enums.EnumOrderType; +import com.iformall.enums.EnumPayStatus; import com.iformall.enums.EnumRefundStatus; import com.iformall.exception.MallinkException; import com.iformall.mapper.WxAppinfoMapper; +import com.iformall.mapper.WxCUserMapper; import com.iformall.mapper.WxCouponMapper; import com.iformall.mapper.WxOrderGroupMapper; import com.iformall.mapper.WxOrderMapper; +import com.iformall.mapper.WxPayAccountMapper; +import com.iformall.mapper.WxPayOrderMapper; +import com.iformall.service.WxAppinfoService; import com.iformall.service.WxOrderService; +import com.iformall.service.WxPayOrderService; import com.iformall.service.WxRefundOrderService; +import com.iformall.service.helper.WxPayOrderServiceHelper; import com.iformall.utils.DateUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; @Component public class OrderExpiringSchedule { @@ -53,7 +65,22 @@ public class OrderExpiringSchedule { @Autowired WxCouponMapper wxCouponMapper; - + + @Autowired + WxPayOrderMapper wxPayOrderMapper; + + @Autowired + WxCUserMapper wxCUserMapper; + + @Autowired + WxAppinfoService wxAppinfoService; + + @Autowired + WxPayAccountMapper wxPayAccountMapper; + + @Autowired + WxPayOrderService wxPayOrderService; + @Scheduled(cron = "0 */5 * * * *?") // 每5分钟检查一次 //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 public void orderExpireSchedule() { @@ -62,13 +89,16 @@ public class OrderExpiringSchedule { Date curDate = new Date(); Date expireDate = new Date(curDate.getTime() - NORMAL_TIME_OUT ); + //直接调用不会触发事务,spring事务基于AOP代理 + OrderExpiringSchedule proxy = (OrderExpiringSchedule) AopContext.currentProxy(); + // 券相关订单, 15分钟未支付, 订单过期 dateMap.put("type", EnumOrderType.COUPON.getCode()); dateMap.put("endDate", expireDate); List orderCoupons = wxOrderMapper.findListOfUnpaidOrderByDate(dateMap); orderCoupons.stream().forEach( o -> { try { - orderExpired(o); + proxy.orderExpired(o); } catch (Exception e) { logger.error("券过期失败" + e.getMessage()); } @@ -82,7 +112,7 @@ public class OrderExpiringSchedule { List orderPresss = wxOrderMapper.findListOfCompleteUnPaidPressOrderByDate(dateMap); orderPresss.stream().forEach( o -> { try { - orderPressExpired(o, true); + proxy.orderPressExpired(o, true); } catch (Exception e) { logger.error("砍价券支付过期失败" + e.getMessage()); } @@ -93,7 +123,7 @@ public class OrderExpiringSchedule { orderPresss = wxOrderMapper.findListOfUnpaidPressOrderByDate(dateMap); orderPresss.stream().forEach( o -> { try { - orderPressExpired(o, false); + proxy.orderPressExpired(o, false); } catch (Exception e) { logger.error("砍价券过期失败" +e.getMessage()); } @@ -105,7 +135,7 @@ public class OrderExpiringSchedule { order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { try { - orderGroupExpired((WxOrder) o); + proxy.orderGroupExpired((WxOrder) o); } catch (Exception e) { logger.error("拼团取消失败" + e.getMessage()); } @@ -117,7 +147,7 @@ public class OrderExpiringSchedule { order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_OVERTIME.getCode()); wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { try { - returnMoney((WxOrder) o); + proxy.returnMoney((WxOrder) o); } catch (Exception e) { logger.error("拼团过期退款失败" + e.getMessage()); } @@ -128,7 +158,7 @@ public class OrderExpiringSchedule { order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_CANCEL.getCode()); wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { try { - returnMoney((WxOrder) o); + proxy.returnMoney((WxOrder) o); } catch (Exception e) { logger.error("拼团券下架退款失败" + e.getMessage()); } @@ -138,7 +168,7 @@ public class OrderExpiringSchedule { order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); wxOrderMapper.selectList(new QueryWrapper(order)).stream().forEach(o -> { try { - returnMoney((WxOrder) o); + proxy.returnMoney((WxOrder) o); } catch (Exception e) { logger.error("参团失败退款失败" + e.getMessage()); } @@ -147,9 +177,49 @@ public class OrderExpiringSchedule { } + + public boolean wxPaySuccess(WxOrder order) { + WxPayOrder payOrderq = new WxPayOrder(); + payOrderq.setOrderId(order.getId()); + List payorderlist = wxPayOrderMapper.findList(payOrderq); + if (null == payorderlist || payorderlist.size() <=0 ) { + return false; + } + WxPayOrder wxpayOrder = payorderlist.get(0); + if (null == wxpayOrder) { + return false; + } + WxCUser user = wxCUserMapper.selectById(wxpayOrder.getCUserId()); + //找不到用户,问题单,不能删 + if (null == user) { + return true; + } + WxAppinfo appInfo = wxAppinfoService.getByAppId(user.getAppId()); + //找不到appInfo,问题单,不能删 + if(appInfo == null) { + return true; + } + WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + //找不到appInfo,问题单,不能删 + if (null == payAccount) { + return true; + } + Map retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(wxpayOrder, order, appInfo, payAccount); + int status = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, wxpayOrder.getPayOrderNo()); + //如果是支付成功,则更新信息 + if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() == status) { + wxPayOrderService.handleSuccessOrder(wxpayOrder, order, retMap); + return true; + } + return false; + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public void orderExpired(WxOrder order) { - + if (wxPaySuccess(order)) { + return; + } // 库存退回 wxOrderService.stockBack(order); @@ -168,6 +238,10 @@ public class OrderExpiringSchedule { @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public void orderPressExpired(WxOrder order, boolean payExpired) { + if (wxPaySuccess(order)) { + return; + } + Date curDate = new Date(); WxOrder updateOrder = new WxOrder(); updateOrder.setId(order.getId()); @@ -188,7 +262,11 @@ public class OrderExpiringSchedule { @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public void orderGroupExpired(WxOrder order) { - Date curDate = new Date(); + if (wxPaySuccess(order)) { + return; + } + + Date curDate = new Date(); WxOrder updateOrder = new WxOrder(); updateOrder.setId(order.getId()); updateOrder.updateTenantInfo(order); @@ -205,7 +283,10 @@ public class OrderExpiringSchedule { @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public void returnMoney(WxOrder order) { - + //支付成功的才退款 + if (!wxPaySuccess(order)) { + return; + } //获取APP信息 WxAppinfo appinfo = new WxAppinfo(); appinfo.updateTenantInfo(order); diff --git a/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java index 68909540b..e57ae2645 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java @@ -15,6 +15,8 @@ import com.iformall.enums.EnumPayWay; public interface WxPayOrderService { + public void handleSuccessOrder(WxPayOrder oldRecord,WxOrder order,Map retMap); + public WxPayOrder handleWxOrderQuery(WxPayOrder oldRecord,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount,IdWorker idworker,boolean repeatPay); /** diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java index a01aad3c6..491adc7d6 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java @@ -34,8 +34,6 @@ import java.util.stream.Collectors; public class WxOrderGroupServiceImpl implements WxOrderGroupService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final Long notOrderGroupId = 0L; - private final int endPeople = 0; @Autowired WxOrderGroupMapper wxOrderGroupMapper; @@ -72,22 +70,30 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { public void createOrderGroup(WxOrder order, WxCoupon wxCoupon) { Long orderGroupId = order.getOrderGroupId(); //查看是否首次拼团,orderGroupId不等于0代表不是首次拼团,因为第二个加入的拼团者肯定有团单号 - if (!orderGroupId.equals(notOrderGroupId)) { + if (!orderGroupId.equals(0L)) { // 非首次拼团 // 参与拼团 WxOrderGroup wxOrderGroup = wxOrderGroupMapper.selectById(orderGroupId); - if(wxOrderGroup.getRemainPeople() < endPeople + 1) { - logger.info(">>>>>>>>>>>>参团失败 修改订单状态后定时退款 团单号" + orderGroupId); - throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); + if (null == wxOrderGroup) { + //错误,更新状态,定时任务会发起退款 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); + wxOrderMapper.updateById(order); + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"WxOrderGroup is null."+orderGroupId); + } + if(wxOrderGroup.getRemainPeople()<1) { + //错误,更新状态,定时任务会发起退款 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); + wxOrderMapper.updateById(order); + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团人数已满,将稍后退款。"); } Integer remainPeople = wxOrderGroup.getRemainPeople()-1; - wxOrderGroup.setStatus(remainPeople == endPeople ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); + wxOrderGroup.setStatus(remainPeople == 0 ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); wxOrderGroup.setUpdateDate(new Date()); logger.info("非首次拼团,更新拼团信息, 剩余人数-1"); int row = wxOrderGroupMapper.updateOrderGroup(wxOrderGroup); if (row != 1) { - logger.info(">>>>>>>>>>>>参团失败 修改订单状态后定时退款 团单号" + orderGroupId); - throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); + //TODO 这个时候应该要发起异步退款。 + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团失败,将稍后退款."); } // 更新订单信息 @@ -100,7 +106,7 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { logger.error("更新订单信息失败", e); throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); } - if (remainPeople == endPeople) { + if (remainPeople == 0) { actionAfterOrderGroupSuccess(order, orderGroupId); } } else { @@ -233,7 +239,7 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { if (orderTemp == null) { return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); } - if (orderTemp.getOrderGroupId().equals(notOrderGroupId)) { + if (orderTemp.getOrderGroupId().equals(0L)) { return new ResultData(ErrorCode.ORDER_GROUP_COOPERATING_FAILD); } WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(orderTemp.getCouponChannelId()); diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 5cc16d72a..206ea7065 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -120,6 +120,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { //方法必须为public AopContext.currentProxy() @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + @Override public void handleSuccessOrder(WxPayOrder oldRecord,WxOrder order,Map retMap) { Date curDate = new Date(); if (oldRecord.getPayOrderStatus() != EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java index f196bb745..6f11acde7 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java @@ -19,6 +19,7 @@ import com.iformall.pay.WxRefundOrderP; import com.iformall.pay.WxRefundOrderSP; import com.iformall.service.WxOrderService; import com.iformall.service.WxRefundOrderService; +import com.iformall.service.helper.WxPayOrderServiceHelper; import com.iformall.utils.BeanUtils; import com.iformall.utils.CipherUtil; import com.iformall.utils.Utility; @@ -317,6 +318,36 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { logger.error("已经核销过的券: couponOrder-" + couponOrderId); throw new MallinkException(ErrorCode.COUPON_ORDER_IS_USED); } + + //TODO 查询订单状态是否是支付成功的状态,支付成功的状态才能退款。 + // 查找支付订单 + WxPayOrder payOrderQ = new WxPayOrder(); + payOrderQ.updateTenantInfo(wxCouponOrder); + payOrderQ.setCUserId(wxOrder.getCUserId()); + payOrderQ.setOrderId(wxOrder.getId()); + payOrderQ.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); + + WxPayOrder payOrder = null; + List list = wxPayOrderMapper.findList(payOrderQ); + if (list.size() > 0) { + if (list.size() > 1) { + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(),"异常:该订单找到多条支付信息wxpayorder!"); + } + payOrder = list.get(0); + } + if (payOrder == null) { + logger.error("支付订单不存在(payOrder不存在)"); + return new ResultData(ErrorCode.PAY_ORDER_NOT_FOUND); + } + WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + if (null == payAccount) { + throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); + } + int status = WxPayOrderServiceHelper.wxOrderPayStatus(payOrder, wxOrder, appInfo, payAccount); + if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() != status) { + return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(),"该订单查询微信支付状态为未支付成功,无法退款。"); + } + final IdWorker idWorker = IdWorker.get(); Long refundOrderId = idWorker.nextId(); @@ -377,26 +408,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { } } - // 查找支付订单 - WxPayOrder payOrderQ = new WxPayOrder(); - payOrderQ.updateTenantInfo(wxCouponOrder); - payOrderQ.setCUserId(wxOrder.getCUserId()); - payOrderQ.setOrderId(wxOrder.getId()); - payOrderQ.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); - WxPayOrder payOrder = null; - List list = wxPayOrderMapper.findList(payOrderQ); - if (list.size() > 0) { - if (list.size() > 1) { - logger.error("TODO: payOrder成功记录应该只有一条????!!!"); - } - logger.warn(""); - payOrder = list.get(0); - } - if (payOrder == null) { - logger.error("支付订单不存在(payOrder不存在)"); - return new ResultData(ErrorCode.PAY_ORDER_NOT_FOUND); - } WxRefundOrder record = new WxRefundOrder(); record.setPayOrderNo(String.valueOf(payOrder.getId())); @@ -428,7 +440,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { logger.error("退款订单数据库插入出错: " + record.toString()); throw new MallinkException(ErrorCode.DB_FAIL); } - WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + if (StringUtils.isBlank(payAccount.getApiKey())) { logger.error("支付密钥为空"); throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员");