| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 | 
							- <?php
 
- namespace app\common\Service;
 
- use app\common\model\ParentOrder;
 
- use app\common\model\Order;
 
- use app\common\model\OrderGoods;
 
- use app\common\model\Address;
 
- use app\common\model\UserCoupon;
 
- use app\common\Enum\OrderEnum;
 
- use app\common\exception\BusinessException;
 
- use app\common\Service\Order\OrderActionService;
 
- use app\common\Enum\OrderActionEnum;
 
- use think\Db;
 
- use think\Exception;
 
- /**
 
-  * 父订单服务类
 
-  * 管理父子订单的创建、支付和状态更新
 
-  */
 
- class ParentOrderService
 
- {
 
-     /**
 
-      * 创建父子订单 - 一个商品一个子订单,统一支付父订单
 
-      * @param int $addressId 地址ID
 
-      * @param int $userId 用户ID
 
-      * @param array $goodsList 商品列表
 
-      * @param int $userCouponId 优惠券ID
 
-      * @param string $remark 备注
 
-      * @return ParentOrder 返回父订单对象
 
-      * @throws BusinessException
 
-      */
 
-     public static function createParentChildOrders($addressId, $userId, $goodsList, $userCouponId = 0, $remark = '')
 
-     {
 
-         // 验证地址
 
-         $address = Address::get($addressId);
 
-         if (!$address || $address['user_id'] != $userId) {
 
-             throw new BusinessException("地址未找到");
 
-         }
 
-         if (empty($goodsList)) {
 
-             throw new BusinessException("商品列表不能为空");
 
-         }
 
-         // 验证商品列表格式
 
-         OrderService::validateGoodsList($goodsList);
 
-         $orderTimeout = ShopConfigService::getConfigs('shop.order.order_timeout', false) ?? 3600;
 
-         $platform = request()->header('platform', 'H5');
 
-         $ip = request()->ip();
 
-         
 
-         // 生成父订单号
 
-         $parentOrderSn = 'P' . date("Ymdhis") . sprintf("%08d", $userId) . mt_rand(1000, 9999);
 
-         $parentOrder = null;
 
-         $childOrders = [];
 
-         
 
-         Db::startTrans();
 
-         try {
 
-             // 先创建所有子订单
 
-             $firstOrder = true;
 
-             foreach ($goodsList as $goodsItem) {
 
-                 // 创建子订单
 
-                 $childOrder = self::createSingleChildOrder($goodsItem, $userId, $address, $firstOrder ? $userCouponId : 0, $remark, $orderTimeout, $platform, $ip);
 
-                 $childOrders[] = $childOrder;
 
-                 $firstOrder = false;
 
-             }
 
-             // 计算父订单总金额
 
-             $totalAmountData = self::calculateTotalAmount($childOrders);
 
-             // 创建父订单
 
-             $parentOrderInfo = [
 
-                 'parent_order_sn'      => $parentOrderSn,
 
-                 'user_id'              => $userId,
 
-                 'total_amount'         => $totalAmountData['total_amount'],
 
-                 'total_goods_price'    => $totalAmountData['total_goods_price'],
 
-                 'total_goods_num'      => $totalAmountData['total_goods_num'],
 
-                 'total_express_fee'    => $totalAmountData['total_express_fee'],
 
-                 'total_discount_fee'   => $totalAmountData['total_discount_fee'],
 
-                 'coupon_discount_fee'  => $totalAmountData['coupon_discount_fee'],
 
-                 'promo_discount_fee'   => 0,
 
-                 'total_order_amount'   => $totalAmountData['total_order_amount'],
 
-                 'pay_amount'           => $totalAmountData['pay_amount'],
 
-                 'pay_original_amount'  => $totalAmountData['pay_amount'],
 
-                 'pay_remain_amount'    => $totalAmountData['pay_amount'],
 
-                 'user_coupon_id'       => $userCouponId ?: null,
 
-                 'remark'               => $remark,
 
-                 'expire_time'          => time() + $orderTimeout,
 
-                 'order_status'         => OrderEnum::STATUS_CREATE,
 
-                 'pay_status'           => 0,
 
-                 'platform'             => $platform,
 
-                 'ip'                   => $ip,
 
-                 'status'               => 'normal',
 
-             ];
 
-             $parentOrder = ParentOrder::create($parentOrderInfo, true);
 
-             // 更新子订单的父订单ID
 
-             foreach ($childOrders as $childOrder) {
 
-                 $childOrder->parent_order_id = $parentOrder->id;
 
-                 $childOrder->save();
 
-             }
 
-             // 提交事务
 
-             Db::commit();
 
-             // 记录操作
 
-             OrderActionService::recordUserAction(
 
-                 $parentOrderSn,
 
-                 OrderActionEnum::ACTION_CREATE,
 
-                 $userId,
 
-                 '创建父订单',
 
-                 $userId
 
-             );
 
-         } catch (Exception $e) {
 
-             Db::rollback();
 
-             throw new BusinessException("创建父子订单失败: " . $e->getMessage());
 
-         }
 
-         return $parentOrder;
 
-     }
 
-     /**
 
-      * 创建单个子订单
 
-      * @param array $goodsItem 商品项
 
-      * @param int $userId 用户ID
 
-      * @param object $address 地址对象
 
-      * @param int $userCouponId 优惠券ID
 
-      * @param string $remark 备注
 
-      * @param int $orderTimeout 订单超时时间
 
-      * @param string $platform 平台
 
-      * @param string $ip IP地址
 
-      * @return Order
 
-      */
 
-     protected static function createSingleChildOrder($goodsItem, $userId, $address, $userCouponId, $remark, $orderTimeout, $platform, $ip)
 
-     {
 
-         // 构建单商品列表
 
-         $singleGoodsList = [$goodsItem];
 
-         
 
-         // 生成子订单号
 
-         $orderSn = date("Ymdhis") . sprintf("%08d", $userId) . mt_rand(1000, 9999);
 
-         // 子订单信息
 
-         $orderInfo = [
 
-             'type'                 => 1,
 
-             'order_sn'             => $orderSn,
 
-             'user_id'              => $userId,
 
-             'amount'               => 0,
 
-             'goods_price'          => 0,
 
-             'goods_num'            => 0,
 
-             'discount_fee'         => 0,
 
-             'coupon_discount_fee'  => 0,
 
-             'promo_discount_fee'   => 0,
 
-             'order_amount'         => 0,
 
-             'express_fee'          => 0,
 
-             'expire_time'          => time() + $orderTimeout,
 
-             'order_status'         => OrderEnum::STATUS_CREATE,
 
-             'invoice_status'       => 0,
 
-             'remark'               => $remark,
 
-             'user_coupon_id'       => $userCouponId > 0 ? $userCouponId : null,
 
-             'ip'                   => $ip,
 
-             'status'               => 'normal',
 
-             'platform'             => $platform,
 
-             'parent_order_id'      => null, // 稍后更新
 
-         ];
 
-                  // 使用OrderService创建订单
 
-          return OrderService::createOrder($address->id, $userId, $singleGoodsList, $userCouponId, $remark);
 
-     }
 
-     /**
 
-      * 计算父订单总金额
 
-      * @param array $childOrders 子订单数组
 
-      * @return array
 
-      */
 
-     protected static function calculateTotalAmount($childOrders)
 
-     {
 
-         $totalAmount = 0;
 
-         $totalGoodsPrice = 0;
 
-         $totalGoodsNum = 0;
 
-         $totalExpressFee = 0;
 
-         $totalDiscountFee = 0;
 
-         $couponDiscountFee = 0;
 
-         foreach ($childOrders as $childOrder) {
 
-             $totalAmount = bcadd($totalAmount, $childOrder->amount, 2);
 
-             $totalGoodsPrice = bcadd($totalGoodsPrice, $childOrder->goods_price, 2);
 
-             $totalGoodsNum += $childOrder->goods_num;
 
-             $totalExpressFee = bcadd($totalExpressFee, $childOrder->express_fee, 2);
 
-             $totalDiscountFee = bcadd($totalDiscountFee, $childOrder->discount_fee, 2);
 
-             $couponDiscountFee = bcadd($couponDiscountFee, $childOrder->coupon_discount_fee, 2);
 
-         }
 
-         return [
 
-             'total_amount' => $totalAmount,
 
-             'total_goods_price' => $totalGoodsPrice,
 
-             'total_goods_num' => $totalGoodsNum,
 
-             'total_express_fee' => $totalExpressFee,
 
-             'total_discount_fee' => $totalDiscountFee,
 
-             'coupon_discount_fee' => $couponDiscountFee,
 
-             'total_order_amount' => bcadd($totalGoodsPrice, $totalExpressFee, 2),
 
-             'pay_amount' => $totalAmount
 
-         ];
 
-     }
 
-     /**
 
-      * 获取父订单详情
 
-      * @param int $parentOrderId 父订单ID
 
-      * @param int $userId 用户ID
 
-      * @return ParentOrder|null
 
-      */
 
-     public static function getParentOrderDetail($parentOrderId, $userId = 0)
 
-     {
 
-         $parentOrderModel = new ParentOrder();
 
-         $query = $parentOrderModel->with(['childOrders']);
 
-         
 
-         if ($userId > 0) {
 
-             $query->where('user_id', $userId);
 
-         }
 
-         
 
-         return $query->where('id', $parentOrderId)->find();
 
-     }
 
-     /**
 
-      * 根据父订单号获取详情
 
-      * @param string $parentOrderSn 父订单号
 
-      * @return ParentOrder|null
 
-      */
 
-     public static function getParentOrderByOrderSn($parentOrderSn)
 
-     {
 
-         $parentOrderModel = new ParentOrder();
 
-         return $parentOrderModel->with(['childOrders'])
 
-             ->where('parent_order_sn', $parentOrderSn)
 
-             ->find();
 
-     }
 
-     /**
 
-      * 检查父订单是否可以支付
 
-      * @param ParentOrder $parentOrder 父订单对象
 
-      * @return bool
 
-      */
 
-     public static function canPay($parentOrder)
 
-     {
 
-         return $parentOrder->order_status == OrderEnum::STATUS_CREATE && $parentOrder->pay_status == 0;
 
-     }
 
-     /**
 
-      * 检查父订单是否已支付
 
-      * @param ParentOrder $parentOrder 父订单对象
 
-      * @return bool
 
-      */
 
-     public static function isPaid($parentOrder)
 
-     {
 
-         return $parentOrder->pay_status == 1;
 
-     }
 
-     /**
 
-      * 更新父订单支付状态
 
-      * @param ParentOrder $parentOrder 父订单对象
 
-      * @param int $payStatus 支付状态
 
-      * @param string $payType 支付方式
 
-      * @param string $transactionId 第三方交易号
 
-      * @return bool
 
-      */
 
-     public static function updateParentOrderPayStatus($parentOrder, $payStatus, $payType = '', $transactionId = '')
 
-     {
 
-         $updateData = [
 
-             'pay_status' => $payStatus,
 
-             'pay_type' => $payType,
 
-             'transaction_id' => $transactionId
 
-         ];
 
-         
 
-         if ($payStatus == 1) {
 
-             $updateData['pay_time'] = time();
 
-             $updateData['order_status'] = OrderEnum::STATUS_PAY;
 
-         }
 
-         
 
-         return $parentOrder->save($updateData);
 
-     }
 
-     /**
 
-      * 更新子订单状态
 
-      * @param int $parentOrderId 父订单ID
 
-      * @param int $status 订单状态
 
-      * @return bool
 
-      */
 
-     public static function updateChildOrdersStatus($parentOrderId, $status)
 
-     {
 
-         $orderModel = new Order();
 
-         return $orderModel->where('parent_order_id', $parentOrderId)->update(['order_status' => $status]);
 
-     }
 
-     /**
 
-      * 获取父订单的所有商品
 
-      * @param ParentOrder $parentOrder 父订单对象
 
-      * @return array
 
-      */
 
-     public static function getAllOrderGoods($parentOrder)
 
-     {
 
-         $childOrderIds = [];
 
-         foreach ($parentOrder->childOrders as $childOrder) {
 
-             $childOrderIds[] = $childOrder->id;
 
-         }
 
-         
 
-         if (empty($childOrderIds)) {
 
-             return [];
 
-         }
 
-         
 
-         $orderGoodsModel = new OrderGoods();
 
-         return $orderGoodsModel->where('order_id', 'in', $childOrderIds)->select();
 
-     }
 
-     /**
 
-      * 父订单支付成功后的处理
 
-      * @param string $parentOrderSn 父订单号
 
-      * @param string $payType 支付方式
 
-      * @param string $transactionId 第三方交易号
 
-      * @return bool
 
-      */
 
-     public static function handleParentOrderPaySuccess($parentOrderSn, $payType = '', $transactionId = '')
 
-     {
 
-         $parentOrder = self::getParentOrderByOrderSn($parentOrderSn);
 
-         if (!$parentOrder) {
 
-             throw new BusinessException('父订单不存在');
 
-         }
 
-         if (self::isPaid($parentOrder)) {
 
-             throw new BusinessException('父订单已支付');
 
-         }
 
-         Db::startTrans();
 
-         try {
 
-             // 更新父订单支付状态
 
-             self::updateParentOrderPayStatus($parentOrder, 1, $payType, $transactionId);
 
-             // 更新所有子订单状态为已支付
 
-             self::updateChildOrdersStatus($parentOrder->id, OrderEnum::STATUS_PAY);
 
-             // 记录父订单支付操作
 
-             OrderActionService::recordUserAction(
 
-                 $parentOrderSn,
 
-                 OrderActionEnum::ACTION_PAY,
 
-                 $parentOrder->user_id,
 
-                 '父订单支付成功',
 
-                 $parentOrder->user_id
 
-             );
 
-             // 记录子订单支付操作
 
-             foreach ($parentOrder->childOrders as $childOrder) {
 
-                 OrderActionService::recordUserAction(
 
-                     $childOrder->order_sn,
 
-                     OrderActionEnum::ACTION_PAY,
 
-                     $parentOrder->user_id,
 
-                     '子订单支付成功(通过父订单)',
 
-                     $parentOrder->user_id
 
-                 );
 
-             }
 
-             Db::commit();
 
-             return true;
 
-         } catch (Exception $e) {
 
-             Db::rollback();
 
-             throw new BusinessException('处理父订单支付失败: ' . $e->getMessage());
 
-         }
 
-     }
 
-     /**
 
-      * 取消父订单
 
-      * @param int $parentOrderId 父订单ID
 
-      * @param int $userId 用户ID
 
-      * @return bool
 
-      */
 
-     public static function cancelParentOrder($parentOrderId, $userId)
 
-     {
 
-         $parentOrder = self::getParentOrderDetail($parentOrderId, $userId);
 
-         if (!$parentOrder) {
 
-             throw new BusinessException('父订单不存在');
 
-         }
 
-         if (self::isPaid($parentOrder)) {
 
-             throw new BusinessException('已支付的父订单无法取消');
 
-         }
 
-         Db::startTrans();
 
-         try {
 
-             // 更新父订单状态
 
-             $parentOrder->save(['order_status' => OrderEnum::STATUS_CANCEL]);
 
-             // 更新所有子订单状态
 
-             self::updateChildOrdersStatus($parentOrder->id, OrderEnum::STATUS_CANCEL);
 
-             // 恢复库存
 
-             foreach ($parentOrder->childOrders as $childOrder) {
 
-                 OrderGoods::setGoodsStocksInc($childOrder->order_sn);
 
-             }
 
-             // 恢复优惠券
 
-             if ($parentOrder->user_coupon_id) {
 
-                 $userCouponModel = new UserCoupon();
 
-                 $userCouponModel->where('id', $parentOrder->user_coupon_id)
 
-                     ->update(['is_used' => 1]);
 
-             }
 
-             Db::commit();
 
-             return true;
 
-         } catch (Exception $e) {
 
-             Db::rollback();
 
-             throw new BusinessException('取消父订单失败: ' . $e->getMessage());
 
-         }
 
-     }
 
-     /**
 
-      * 获取父订单列表
 
-      * @param int $userId 用户ID
 
-      * @param array $param 查询参数
 
-      * @param array $status 状态筛选
 
-      * @return \think\Paginator
 
-      */
 
-     public static function getParentOrderList($userId = 0, $param = [], $status = [])
 
-     {
 
-         $pageSize = $param['pageSize'] ?? 10;
 
-         
 
-         $parentOrderModel = new ParentOrder();
 
-         $query = $parentOrderModel->with(['childOrders']);
 
-         
 
-         if (!empty($userId)) {
 
-             $query->where('user_id', $userId);
 
-         }
 
-         
 
-         if (!empty($status)) {
 
-             $query->whereIn('order_status', $status);
 
-         }
 
-         
 
-         if (isset($param['keywords']) && $param['keywords'] != '') {
 
-             $query->where('parent_order_sn', 'like', '%' . $param['keywords'] . '%');
 
-         }
 
-         
 
-         return $query->order('createtime desc')
 
-             ->paginate($pageSize, false, ['query' => request()->get()]);
 
-     }
 
- } 
 
 
  |