From cf98926793932b132000e237a487ba4343084410 Mon Sep 17 00:00:00 2001 From: mitao <2763622819@qq.com> Date: 星期一, 09 九月 2024 19:50:47 +0800 Subject: [PATCH] 下单接口 --- xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 230 insertions(+), 3 deletions(-) diff --git a/xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java b/xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java index 2877c44..0fa0063 100644 --- a/xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java +++ b/xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java @@ -1,10 +1,37 @@ package com.xinquan.order.service.impl; -import com.xinquan.order.domain.Order; -import com.xinquan.order.mapper.OrderMapper; -import com.xinquan.order.service.OrderService; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xinquan.common.core.constant.Constants; +import com.xinquan.common.core.constant.SecurityConstants; +import com.xinquan.common.core.enums.ChargeTypeEnum; +import com.xinquan.common.core.enums.DisabledEnum; +import com.xinquan.common.core.enums.PaymentStatusEnum; +import com.xinquan.common.core.enums.PaymentTypeEnum; +import com.xinquan.common.core.exception.ServiceException; +import com.xinquan.common.core.utils.ip.IpUtils; +import com.xinquan.common.security.utils.SecurityUtils; +import com.xinquan.course.api.domain.Course; +import com.xinquan.course.api.feign.RemoteCourseService; +import com.xinquan.meditation.api.domain.Meditation; +import com.xinquan.meditation.api.feign.RemoteMeditationService; +import com.xinquan.order.api.domain.Order; +import com.xinquan.order.domain.OrderPaymentRecord; +import com.xinquan.order.domain.vo.ClientPlaceOrderVO; +import com.xinquan.order.mapper.OrderMapper; +import com.xinquan.order.service.OrderPaymentRecordService; +import com.xinquan.order.service.OrderService; +import com.xinquan.order.utils.JuHeFuUtil; +import com.xinquan.order.utils.OrderUtil; +import com.xinquan.user.api.domain.AppUser; +import com.xinquan.user.api.domain.dto.AppUserDTO; +import com.xinquan.user.api.feign.RemoteAppUserService; +import java.math.BigDecimal; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * <p> @@ -15,6 +42,206 @@ * @since 2024-08-21 */ @Service +@RequiredArgsConstructor public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { + private final RemoteMeditationService remoteMeditationService; + private final RemoteCourseService remoteCourseService; + private final RemoteAppUserService remoteAppUserService; + private final OrderPaymentRecordService orderPaymentRecordService; + + /** + * 创建待支付订单 + * + * @param targetId 目标id + * @param orderFrom 订单来源 1=冥想音频 2=课程 + * @param receiverId 被赠送课程APP用户id + * @param balanceFlag 是否使用余额抵扣 1=是 2=否 + * @param payType 支付方式 1=微信 2=支付宝 + * @return 下单返回数据视图对象 + * @see com.xinquan.order.domain.vo.ClientPlaceOrderVO + */ + @Override + @Transactional(rollbackFor = Exception.class) + public ClientPlaceOrderVO placeOrder(Long targetId, Integer orderFrom, Long receiverId, + Integer balanceFlag, Integer payType) throws Exception { + // 获取当前登录用户id + Long userId = SecurityUtils.getUserId(); + // 获取用户信息 + AppUser appUser = getAppUserById(userId); + ClientPlaceOrderVO clientPlaceOrderVO = new ClientPlaceOrderVO(); + Order order = new Order(); + // 购买冥想音频 + if (orderFrom == 1) { + Meditation meditation = remoteMeditationService.getMeditationById(targetId, + SecurityConstants.INNER).getData(); + String meditationTitle = meditation.getMeditationTitle(); + String detailDescription = meditation.getDetailDescription(); + String wxOpenId = appUser.getWxOpenId(); + // 创建订单 + String orderNo = OrderUtil.getOrderNoForPrefix("MX"); + order.setOrderFrom(orderFrom); + order.setBizOrderNo(orderNo); + order.setBusinessId(meditation.getId()); + order.setAppUserId(userId); + order.setTotalAmount(meditation.getGeneralPrice()); + this.save(order); + Long orderId = order.getId(); + clientPlaceOrderVO.setOrderNo(orderNo); + clientPlaceOrderVO.setId(orderId); + // 如果冥想音频价格设定为单独收费,且需要使用余额抵扣 + if (balanceFlag.equals(1) && meditation.getChargeType() + .equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) { + BigDecimal needPayAmount = handleBalancePayment(appUser, + meditation.getGeneralPrice(), + orderId); + + if (needPayAmount.compareTo(BigDecimal.ZERO) <= 0) { + clientPlaceOrderVO.setZeroFlag(DisabledEnum.YES.getCode()); + return clientPlaceOrderVO; + } + // 创建支付订单 + createPayment(payType, orderNo, needPayAmount, meditationTitle, detailDescription, + wxOpenId, orderId, clientPlaceOrderVO); + } else { + // 创建支付订单 + createPayment(payType, orderNo, meditation.getGeneralPrice(), meditationTitle, + detailDescription, wxOpenId, orderId, clientPlaceOrderVO); + } + } else { + // 购买课程 + Course course = remoteCourseService.getCourseById(targetId, + SecurityConstants.INNER).getData(); + String courseTitle = course.getCourseTitle(); + String wxOpenId = appUser.getWxOpenId(); + String description = course.getDescription(); + + // 创建订单 + String orderNo = OrderUtil.getOrderNoForPrefix("KC"); + order.setOrderFrom(orderFrom); + order.setBizOrderNo(orderNo); + order.setBusinessId(course.getId()); + order.setAppUserId(userId); + order.setTotalAmount(course.getGeneralPrice()); + this.save(order); + Long orderId = order.getId(); + clientPlaceOrderVO.setOrderNo(orderNo); + clientPlaceOrderVO.setId(orderId); + + if (balanceFlag.equals(1) && course.getChargeType() + .equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) { + BigDecimal needPayAmount = handleBalancePayment(appUser, course.getGeneralPrice(), + orderId); + + if (needPayAmount.compareTo(BigDecimal.ZERO) <= 0) { + clientPlaceOrderVO.setZeroFlag(DisabledEnum.YES.getCode()); + return clientPlaceOrderVO; + } + // 创建支付订单 + createPayment(payType, orderNo, needPayAmount, courseTitle, description, + wxOpenId, orderId, clientPlaceOrderVO); + } else { + // 创建支付订单 + createPayment(payType, orderNo, course.getGeneralPrice(), courseTitle, + description, wxOpenId, orderId, clientPlaceOrderVO); + } + } + return clientPlaceOrderVO; + } + + /** + * 处理余额抵扣 + * + * @param appUser app用户 + * @param generalPrice 通用价格 + * @param orderId 订单号 + * @return 需要支付的金额 + */ + @NotNull + private BigDecimal handleBalancePayment(AppUser appUser, BigDecimal generalPrice, + Long orderId) { + if (appUser.getBalance().compareTo(BigDecimal.ZERO) < 0) { + throw new ServiceException("用户可用余额不足,请重新选择支付方案"); + } + // 更新用户余额 + remoteAppUserService.updateAppUser( + AppUserDTO.builder().balance( + appUser.getBalance().subtract(generalPrice)) + .build(), SecurityConstants.INNER); + + OrderPaymentRecord balancePaymentRecord = new OrderPaymentRecord(); + balancePaymentRecord.setOrderId(orderId); + balancePaymentRecord.setPaymentType(PaymentTypeEnum.BALANCE_PAY.getCode()); + balancePaymentRecord.setPaymentStatus(PaymentStatusEnum.COMPLETED.getCode()); + orderPaymentRecordService.save(balancePaymentRecord); + + // 计算除去余额还需支付的金额 + return generalPrice + .subtract(appUser.getBalance()); + } + + /** + * 获取登录用户信息 + * + * @param userId APP用户id + * @return AppUser + */ + private AppUser getAppUserById(Long userId) { + return remoteAppUserService.getUserByCondition( + AppUserDTO.builder().id(userId).build(), + SecurityConstants.INNER).getData(); + } + + /** + * 创建支付订单 + * + * @param payType 支付方式 1=微信 2=支付宝 + * @param orderNo 订单编号 + * @param needPayAmount 支付金额 + * @param goodsTitle 商品标题 + * @param goodsDesc 商品描述 + * @param wxOpenId 微信openId + * @param orderId 订单id + * @param clientPlaceOrderVO 下单返回数据视图对象 + * @throws Exception + */ + private void createPayment(Integer payType, String orderNo, BigDecimal needPayAmount, + String goodsTitle, String goodsDesc, String wxOpenId, Long orderId, + ClientPlaceOrderVO clientPlaceOrderVO) throws Exception { + // 截取前42个字符 商品描述信息,微信小程序和微信公众号该字段,最大长度 42 个字符 + goodsDesc = goodsDesc.substring(0, 42); + // 调用第三方支付获取支付信息 + JSONObject payInfo = JuHeFuUtil.createPayment(orderNo, payType, + needPayAmount.toString(), goodsTitle, goodsDesc, + IpUtils.getIpAddr(), wxOpenId, Constants.PAYMENT_NOTIFY_URL); + // 第三方支付记录 + OrderPaymentRecord paymentRecord = new OrderPaymentRecord(); + paymentRecord.setOrderId(orderId); + + if (payType == 1) { + clientPlaceOrderVO.setPayInfo(payInfo.getString("pay_info")); + paymentRecord.setPaymentType(PaymentTypeEnum.WECHAT_PAY.getCode()); + } else { + clientPlaceOrderVO.setQrcodeUrl(payInfo.getString("qrcode_url")); + paymentRecord.setPaymentType(PaymentTypeEnum.ALI_PAY.getCode()); + } + + paymentRecord.setPaymentStatus(PaymentStatusEnum.TO_BE_PAID.getCode()); + orderPaymentRecordService.save(paymentRecord); + // 设置订单是否需要支付标识 + clientPlaceOrderVO.setZeroFlag(DisabledEnum.NO.getCode()); + } + + /** + * 根据类型获取已完成的订单列表 + * + * @param userId 用户id + * @param orderFrom 订单来源 + * @return + */ + @Override + public List<Order> getOrderListByType(Long userId, Integer orderFrom) { + return this.lambdaQuery().eq(Order::getAppUserId, userId).eq(Order::getOrderFrom, orderFrom) + .eq(Order::getPaymentStatus, PaymentStatusEnum.COMPLETED.getCode()).list(); + } } -- Gitblit v1.7.1