|
@@ -18,15 +18,23 @@ import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentReq;
|
|
|
import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
|
|
|
import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
|
|
|
import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
|
|
|
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
|
|
|
import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
|
|
|
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
|
|
|
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
|
|
|
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
|
|
|
import com.yonge.cooleshow.biz.dal.service.*;
|
|
|
import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
|
|
|
+import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
|
|
|
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
|
|
|
import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
|
|
|
import com.yonge.cooleshow.common.enums.SysUserType;
|
|
|
-import com.yonge.cooleshow.common.enums.payment.EGoodsType;
|
|
|
import com.yonge.cooleshow.common.enums.payment.EPaymentChannel;
|
|
|
import com.yonge.cooleshow.common.enums.payment.EPaymentStatus;
|
|
|
import com.yonge.cooleshow.common.enums.payment.EPaymentType;
|
|
|
+import com.yonge.cooleshow.common.service.IdGeneratorService;
|
|
|
+import com.yonge.toolset.payment.core.props.PaymentProperties;
|
|
|
+import com.yonge.toolset.payment.core.service.PaymentClient;
|
|
|
import com.yonge.toolset.payment.util.DistributedLock;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
@@ -78,32 +86,87 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
@Autowired
|
|
|
private UserOrderDetailService userOrderDetailService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private UserOrderService userOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MemberPriceSettingsService memberPriceSettingsService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CourseGroupService courseGroupService;
|
|
|
+ @Autowired
|
|
|
+ private CourseScheduleService scheduleService;
|
|
|
+ @Autowired
|
|
|
+ private VideoLessonPurchaseRecordService recordService;
|
|
|
+ @Autowired
|
|
|
+ private MusicSheetService musicSheetService;
|
|
|
+ @Autowired
|
|
|
+ private PianoRoomBuyRecordService pianoRoomBuyRecordService;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ActivityPlanService activityPlanService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CouponInfoService couponInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TenantAlbumService tenantAlbumService;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
// 订单商品参数校验,获取订单支付金额
|
|
|
- private static final Map<EGoodsType, Consumer<UserOrderDetail>> orderGoodsCreate = Maps.newHashMap();
|
|
|
- // 支付订单类型参数校验
|
|
|
- private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderCreate = Maps.newHashMap();
|
|
|
+ private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderGoodsCreate = Maps.newHashMap();
|
|
|
+
|
|
|
+
|
|
|
// 支付创建前,数据库存
|
|
|
private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderSuccessBefore = Maps.newHashMap();
|
|
|
- // 支付创建前,数据库存
|
|
|
-// private static final Map<EPaymentType, Consumer<UserPaymentOrder>> executeSuccessBefore = Maps.newHashMap();
|
|
|
- // 订单完成后执行
|
|
|
- private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
|
|
|
|
|
|
- @PostConstruct
|
|
|
- private void init() {
|
|
|
+ // 订单支付后
|
|
|
+ private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderSuccessAfter = Maps.newHashMap();
|
|
|
|
|
|
- /*订单参数校验*/
|
|
|
|
|
|
- /*支付订单类型参数校验*/
|
|
|
+ // 订单完成后执行
|
|
|
+ private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
|
|
|
+
|
|
|
|
|
|
- /*订单创建前处理流程*/
|
|
|
|
|
|
- /*订单支付完成后执行*/
|
|
|
+ @PostConstruct
|
|
|
+ private void init() {
|
|
|
|
|
|
- /*退款订单类型参数校验*/
|
|
|
+ /**********订单生成前 商品校验******************/
|
|
|
+ //vip开通缴费
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
|
|
|
+ //直播课程购买
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
|
|
|
+ //陪练课购买
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourse);
|
|
|
+ //视频课购买
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourse);
|
|
|
+ //曲目购买
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.MUSIC, musicSheetService::buyMusicSheetCheck);
|
|
|
+ // 专辑购买
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.ALBUM, musicSheetService::buyMusicSheetCheck);
|
|
|
+ //琴房时长
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.PIANO_ROOM, pianoRoomBuyRecordService::orderCreate);
|
|
|
+ //活动报名
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.ACTI_REGIST, activityPlanService::orderCreate);
|
|
|
+
|
|
|
+ // 机构专辑
|
|
|
+ orderGoodsCreate.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderCreate);
|
|
|
+
|
|
|
+ /**********订单生成后 数据处理******************/
|
|
|
+ //曲目购买
|
|
|
+ orderSuccessAfter.put(GoodTypeEnum.MUSIC, musicSheetService::orderAfterSheet);
|
|
|
+ // 专辑购买
|
|
|
+ orderSuccessAfter.put(GoodTypeEnum.ALBUM, musicSheetService::orderAfterSheet);
|
|
|
+
|
|
|
+ /**********订单完成后 数据处理******************/
|
|
|
+ // 沿用以前的流程
|
|
|
+
|
|
|
+ /**********订单取消后******************/
|
|
|
+ // 沿用以前的流程
|
|
|
|
|
|
- /*退款支付完成执行*/
|
|
|
|
|
|
log.info("---> orderCreate.Keys={}", orderGoodsCreate.keySet());
|
|
|
log.info("---> paymentSuccess.Keys={}", paymentSuccess.keySet());
|
|
@@ -221,9 +284,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
userPaymentOrderService.updateById(order);
|
|
|
|
|
|
// 不同订单类型支付成功,后续数据同步流程
|
|
|
- if (paymentSuccess.containsKey(paymentOrder.getOrderType())) {
|
|
|
- paymentSuccess.get(paymentOrder.getOrderType()).accept(paymentOrder);
|
|
|
- }
|
|
|
+ userOrderService.paySuccess(userOrderService.detail(order.getId()));
|
|
|
|
|
|
// 生成协议
|
|
|
try {
|
|
@@ -270,46 +331,47 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
|
|
|
.builder()
|
|
|
.id(paymentOrder.getId())
|
|
|
- //.status(EPaymentStatus.CLOSED)
|
|
|
- //.errorMsg(errorMessage)
|
|
|
+ .status(EPaymentStatus.CLOSED)
|
|
|
+// .errorMsg(errorMessage)
|
|
|
.updateTime(DateTime.now().toDate())
|
|
|
.build();
|
|
|
|
|
|
- if (StringUtils.isBlank(paymentResp.getMsg())) {
|
|
|
|
|
|
- String errorMessage = null;
|
|
|
- try {
|
|
|
- // 关闭三方支付订单状态
|
|
|
- PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
|
|
|
- .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
|
|
|
+ String errorMessage = null;
|
|
|
+ try {
|
|
|
+ // 关闭三方支付订单状态
|
|
|
+ PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
|
|
|
+ .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
|
|
|
|
|
|
- if (Objects.nonNull(paymentClose)) {
|
|
|
- errorMessage = paymentClose.getMsg();
|
|
|
+ if (Objects.nonNull(paymentClose)) {
|
|
|
+ errorMessage = paymentClose.getMsg();
|
|
|
|
|
|
- // 订单取消,三方返回异常信息
|
|
|
- if (StringUtils.isNotEmpty(errorMessage)) {
|
|
|
- log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
|
|
|
- // 记录异常消息
|
|
|
- ThreadPool.getExecutor().submit(() -> {
|
|
|
- order.setErrorMsg(paymentClose.getMsg());
|
|
|
+ // 订单取消,三方返回异常信息
|
|
|
+ if (StringUtils.isNotEmpty(errorMessage)) {
|
|
|
+ log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
|
|
|
+ // 记录异常消息
|
|
|
+ ThreadPool.getExecutor().submit(() -> {
|
|
|
+ order.setErrorMsg(paymentClose.getMsg());
|
|
|
|
|
|
- // 更新订单退款异常信息
|
|
|
- userPaymentOrderService.updateById(order);
|
|
|
- });
|
|
|
- throw new BizException("查询交易中,请耐心等待!");
|
|
|
- }
|
|
|
+ // 更新订单退款异常信息
|
|
|
+ userPaymentOrderService.updateById(order);
|
|
|
+ });
|
|
|
+ throw new BizException("查询交易中,请耐心等待!");
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
|
|
|
- throw new BizException("查询交易中,请耐心等待!");
|
|
|
}
|
|
|
-
|
|
|
- order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
|
|
|
+ throw new BizException("查询交易中,请耐心等待!");
|
|
|
}
|
|
|
|
|
|
+ order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
|
|
|
+
|
|
|
// 更新订单关闭状态
|
|
|
userPaymentOrderService.updateById(order);
|
|
|
|
|
|
+ // 订单关闭后的数据处理流程
|
|
|
+ userOrderService.payCancel(userOrderService.detail(order.getId()));
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}, 10L, TimeUnit.SECONDS);
|
|
@@ -321,17 +383,17 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
* @param orderReq UserPaymentOrderWrapper.UserPaymentOrder
|
|
|
*/
|
|
|
@Override
|
|
|
+ @Transactional
|
|
|
public UserPaymentOrderWrapper.PaymentConfig executeOrderCreate(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 商品校验 orderCreate
|
|
|
|
|
|
-
|
|
|
// 用户下单请求锁
|
|
|
- String lockName = redisCacheService.getExecuteOrderCacheKey(orderReq.getUserId().toString());
|
|
|
// 生成用户支付订单
|
|
|
- return DistributedLock.of(redissonClient).runIfLockToFunction(lockName, this::executeOrder, orderReq, 10L);
|
|
|
+ return DistributedLock.of(redissonClient).runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(orderReq.getUserId()),
|
|
|
+ this::executeOrder, orderReq, 10L);
|
|
|
|
|
|
} catch (BizException e) {
|
|
|
log.error("executeOrder BizException, orderReq={}", orderReq.jsonString(), e);
|
|
@@ -361,35 +423,74 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
.status(EPaymentStatus.WAIT_PAY)
|
|
|
.originalPrice(BigDecimal.ZERO);
|
|
|
|
|
|
+ List<UserOrderDetail> orderDetails = new ArrayList<>();
|
|
|
+ // 订单优惠券信息
|
|
|
+ CouponOrderWrapper couponOrderWrapper = CouponOrderWrapper.builder()
|
|
|
+ .discountedPrices(0D)
|
|
|
+ .couponInfos(Lists.newArrayList())
|
|
|
+ .build();
|
|
|
// 购买商品信息
|
|
|
- for (UserOrderDetail item : orderReq.getGoodsInfos()) {
|
|
|
+ for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
|
|
|
|
|
|
+ // 数据赋值
|
|
|
item.setOrderNo(orderReq.getOrderNo());
|
|
|
item.setSubOrderNo(IdWorker.getIdStr());
|
|
|
+ item.setActivityId(orderReq.getActivityId());
|
|
|
+ item.setUserId(orderReq.getUserId());
|
|
|
+ item.setPaymentClient(orderReq.getPaymentClient());
|
|
|
|
|
|
+
|
|
|
+ BigDecimal couponAmount = BigDecimal.ZERO;
|
|
|
// 商品基本信息
|
|
|
if (orderGoodsCreate.containsKey(item.getGoodType())) {
|
|
|
// 填充商品基础信息,校验参数合法以性
|
|
|
orderGoodsCreate.get(item.getGoodType()).accept(item);
|
|
|
+ UserOrderDetail userOrderDetail = item.getUserOrderDetail();
|
|
|
+ orderDetails.add(userOrderDetail);
|
|
|
+ // 根据优惠券计算实际优惠金额
|
|
|
+ // 计算优惠券金额
|
|
|
+ {
|
|
|
+ if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
|
|
|
+
|
|
|
+ couponOrderWrapper = couponInfoService.queryUserOrderCouponInfo(orderReq.getUserId(),
|
|
|
+ CouponInfoQuery.CouponOrderQuery.builder()
|
|
|
+ .clientType(orderReq.getPaymentClient())
|
|
|
+ .couponTypes(CouponCategoryEnum.getCategory(orderReq.getOrderType().getCode()))
|
|
|
+ .useState(CouponUseStateEnum.USABLE)
|
|
|
+ .timestamp(DateTime.now().getMillis())
|
|
|
+ .amount(userOrderDetail.getExpectPrice().doubleValue())
|
|
|
+ .build()
|
|
|
+ .issueIds(orderReq.getCouponIds()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 优惠券优惠金额,暂时为0
|
|
|
+ couponAmount = couponAmount.add(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
|
|
|
+
|
|
|
+ if (couponAmount.compareTo(userOrderDetail.getExpectPrice()) > 0) {
|
|
|
+ couponAmount = userOrderDetail.getExpectPrice();
|
|
|
+ }
|
|
|
+ userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount).setScale(2, RoundingMode.HALF_UP));
|
|
|
+ userOrderDetail.setCouponAmount(couponAmount);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// 计算原始价格
|
|
|
- BigDecimal originalPrice = orderReq.getGoodsInfos().stream()
|
|
|
+ BigDecimal originalPrice = orderDetails.stream()
|
|
|
.map(UserOrderDetail::getOriginalPrice)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
|
// 支付金额
|
|
|
- BigDecimal currentPrice = orderReq.getGoodsInfos().stream()
|
|
|
+ BigDecimal currentPrice = orderDetails.stream()
|
|
|
.map(UserOrderDetail::getExpectPrice)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
|
// 实际支付金额
|
|
|
- BigDecimal cashAmount = orderReq.getGoodsInfos().stream()
|
|
|
+ BigDecimal cashAmount = orderDetails.stream()
|
|
|
.map(UserOrderDetail::getActualPrice)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
|
|
|
- // 根据优惠券计算实际优惠金额
|
|
|
|
|
|
orderReq.originalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP))
|
|
|
.currentPrice(currentPrice.setScale(2, RoundingMode.HALF_UP))
|
|
@@ -418,11 +519,23 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
|
|
|
}
|
|
|
userPaymentOrderService.save(orderReq);
|
|
|
|
|
|
- userOrderDetailService.saveBatch(orderReq.getGoodsInfos());
|
|
|
+ userOrderDetailService.saveBatch(orderDetails);
|
|
|
+
|
|
|
+ // 入库后处理流程
|
|
|
+ for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
|
|
|
+ if (orderSuccessAfter.containsKey(item.getGoodType())) {
|
|
|
+ orderSuccessAfter.get(item.getGoodType()).accept(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 更新用户订单优惠券使用状态
|
|
|
+ if (CollectionUtils.isNotEmpty(couponOrderWrapper.getCouponInfos())) {
|
|
|
+
|
|
|
+ couponOrderWrapper.useType(CouponCategoryEnum.goodTypeTo(orderReq.getOrderType().getCode()));
|
|
|
+ couponInfoService.updateUserOrderCouponInfo(couponOrderWrapper.orderNo(orderReq.getOrderNo()));
|
|
|
+ }
|
|
|
|
|
|
- String subject = orderReq.getGoodsInfos().stream()
|
|
|
+ String subject = orderDetails.stream()
|
|
|
.map(UserOrderDetail::getGoodName).collect(Collectors.joining(","));
|
|
|
// 返回订单支付配置参数
|
|
|
UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig
|