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