checkUserOrUse($userCouponId, $userId); $orderInfo['user_coupon_id'] = $userCouponId; } // 提取所有商品ID和SKU ID,进行批量查询 $goodsIds = array_column($goodsList, 'goods_id'); $skuIds = []; foreach ($goodsList as $index => $item) { if (isset($item['goods_sku_id']) && $item['goods_sku_id'] > 0) { $skuIds[] = $item['goods_sku_id']; } } // 批量查询商品信息 $goodsData = []; if (!empty($goodsIds)) { $goodsCollection = Goods::with(['brand']) ->where('id', 'in', $goodsIds) ->where('status', GoodsEnum::STATUS_ON_SALE) ->select(); foreach ($goodsCollection as $goods) { $goodsData[$goods->id] = $goods; } } // 批量查询SKU信息 $skuData = []; $multiSpecSkuIds = []; // 用于存储多规格商品的SKU ID if (!empty($skuIds)) { $skuCollection = Sku::where('id', 'in', $skuIds)->select(); foreach ($skuCollection as $sku) { $skuData[$sku->id] = $sku; // 过滤出有规格值的SKU ID(spec_value_ids不为空) if (!empty($sku->spec_value_ids)) { $multiSpecSkuIds[] = $sku->id; } } } // 批量查询规格属性字符串(只查询多规格商品的SKU) $skuAttrData = []; if (!empty($multiSpecSkuIds)) { $skuAttrData = \app\common\Service\SkuSpec::getSkuAttrs($multiSpecSkuIds); } // 验证并构建商品数据 foreach ($goodsList as $item) { $goods_id = $item['goods_id']; $goods_sku_id = $item['goods_sku_id']; // 现在所有商品都应该有SKU ID $nums = $item['nums']; if ($nums <= 0) { throw new BusinessException("商品数量必须大于0"); } // 检查商品是否存在 if (!isset($goodsData[$goods_id])) { throw new ("商品已下架"); } $goods = $goodsData[$goods_id]; // 所有商品都必须有SKU(包括单规格商品的默认SKU) if (empty($skuData) || !isset($skuData[$goods_sku_id])) { throw new Exception("商品规格不存在"); } $sku = $skuData[$goods_sku_id]; // 验证SKU是否属于该商品 if ($sku->goods_id != $goods_id) { throw new Exception("商品规格不匹配"); } // 获取规格属性字符串(单规格商品的sku_attr为空) $sku_attr = $skuAttrData[$goods_sku_id] ?? ''; // 构建商品对象,模拟购物车数据结构 $goodsItem = (object)[ 'goods_id' => $goods_id, 'goods_sku_id' => $goods_sku_id, 'nums' => $nums, 'goods' => $goods, 'sku' => $sku, 'sku_attr' => $sku_attr ]; $processedGoodsList[] = $goodsItem; } // 计算商品价格和运费(统一使用SKU进行计算) foreach ($processedGoodsList as $item) { $goodsItemData = []; if (empty($item->goods) || empty($item->sku)) { throw new Exception("商品已下架"); } // 库存验证(统一使用SKU库存) if ($item->sku->stocks < $item->nums) { throw new Exception("商品库存不足,请重新修改数量"); } // 统一使用SKU数据进行计算 $goodsItemData['image'] = !empty($item->sku->image) ? $item->sku->image : $item->goods->image; $goodsItemData['price'] = $item->sku->price; // $goodsItemData['lineation_price'] = $item->sku->lineation_price; $goodsItemData['sku_sn'] = $item->sku->sku_sn; $amount = bcmul($item->sku->price, $item->nums, 2); $goodsItemData['amount'] = $amount; // 订单应付金额 $orderInfo['amount'] = bcadd($orderInfo['amount'], $amount, 2); // 商品总价 $orderInfo['goods_price'] = bcadd($orderInfo['goods_price'], $amount, 2); // 商品数量累计 $orderInfo['goods_num'] += $item->nums; $freight_id = $item->goods->express_template_id; // 计算邮费【合并运费模板】 if (!isset($shippingTemp[$freight_id])) { $shippingTemp[$freight_id] = [ 'nums' => $item->nums, 'weight' => $item->sku->weight, 'amount' => $amount ]; } else { $shippingTemp[$freight_id] = [ 'nums' => bcadd($shippingTemp[$freight_id]['nums'], $item->nums, 2), 'weight' => bcadd($shippingTemp[$freight_id]['weight'], $item->sku->weight, 2), 'amount' => bcadd($shippingTemp[$freight_id]['amount'], $amount, 2) ]; } // 创建订单商品数据 (基于正确的表结构) $orderItemData = [ 'user_id' => $userId, 'order_sn' => '', // 将在订单创建后补充 'goods_sn' => $item->goods->goods_sn ?: '', // 商品货号 'sku_sn' => $item->sku->sku_sn ?: '', // SKU编号 'goods_type' => $item->goods->type ?: 0, // 商品类型 'goods_id' => $item->goods->id, 'goods_sku_attr' => $item->sku->sku_attr, 'goods_spec_value_ids' => $item->sku->spec_value_ids, 'goods_sku_id' => $item->sku->id, 'goods_title' => $item->goods->title, 'goods_market_price' => $item->sku->market_price ?: 0, // 市场价 'goods_original_price' => $item->sku->price, // 商城售价 'goods_price' => $amount, // 实付金额 'goods_image' => $goodsItemData['image'], 'goods_weight' => $item->sku->weight ?: 0, 'nums' => $item->nums, 'sale_status' => 0, // 销售状态:0=待申请 'comment_status' => 0, // 评论状态:0=未评论 'status' => 1, // 状态 'supplier_id' => $item->goods->supplier_id, ]; $orderItem[] = $orderItemData; } // 按运费模板计算 foreach ($shippingTemp as $key => $item) { $shippingfee = Freight::calculate($key, $areaId, $item['nums'], $item['weight'], $item['amount']); $orderInfo['express_fee'] = bcadd($orderInfo['express_fee'], $shippingfee, 2); } // 订单金额(商品价格+运费) $orderInfo['order_amount'] = bcadd($orderInfo['goods_price'], $orderInfo['express_fee'], 2); // 订单应付金额(暂时等于订单金额,后续会减去优惠) $orderInfo['amount'] = $orderInfo['order_amount']; // if (!empty($userCoupon)) { // // 校验优惠券 // $goods_ids = array_column($orderItem, 'goods_id'); // $category_ids = array_column($orderItem, 'category_id'); // $brand_ids = array_column($orderItem, 'brand_id'); // $couponModel = new Coupon(); // $coupon = $couponModel->getCoupon($userCoupon['coupon_id']) // ->checkCoupon() // ->checkOpen() // ->checkUseTime($userCoupon['createtime']) // ->checkConditionGoods($goods_ids, $userId, $category_ids, $brand_ids); // // 计算折扣金额,判断是使用不含运费,还是含运费的金额 // $amount = !isset($config['shippingfeecoupon']) || $config['shippingfeecoupon'] == 0 ? $orderInfo['goods_price'] : $orderInfo['order_amount']; // list($new_money, $coupon_money) = $coupon->doBuy($amount); // // 判断优惠金额是否超出总价,超出则直接设定优惠金额为总价 // $orderInfo['coupon_discount_fee'] = $coupon_money > $amount ? $amount : $coupon_money; // $orderInfo['discount_fee'] = $orderInfo['coupon_discount_fee']; // } // 计算最终应付金额【订单金额减去折扣】 $orderInfo['amount'] = max(0, bcsub($orderInfo['order_amount'], $orderInfo['discount_fee'], 2)); $orderInfo['pay_amount'] = $orderInfo['amount']; // 实际付款金额等于应付金额 $orderInfo['discount_fee'] = bcadd($orderInfo['discount_fee'], 0, 2); return [ $orderItem, $processedGoodsList, $userCoupon ]; } /** * 统一的创建订单方法 * @param int $address_id 地址ID * @param int $user_id 用户ID * @param array $goods_list 标准化的商品列表 * @param int $user_coupon_id 优惠券ID * @param string $memo 备注 * @param array $cart_ids 购物车ID数组(如果是购物车模式需要清空) * @return Order * @throws BusinessException */ public static function createOrder($addressId, $userId, $goodsList, $userCouponId = 0, $remark = '',$supplierId = 0) { $address = Address::get($addressId); if (!$address || $address['user_id'] != $userId) { throw new BusinessException("地址未找到"); } if (empty($goodsList)) { throw new BusinessException("商品列表不能为空"); } $config = get_addon_config('shop'); $orderSn = date("Ymdhis") . sprintf("%08d", $userId) . mt_rand(1000, 9999); // 订单主表信息 (基于新表结构) $orderInfo = [ 'type' => 1, // 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() + $config['order_timeout'], // 过期时间 'order_status' => OrderEnum::STATUS_CREATE, // 待付款 'invoice_status' => 0, // 发票开具状态 'remark' => $remark, // 用户备注 'user_coupon_id' => $userCouponId ?: null, 'ip' => request()->ip(), // IP地址 'status' => 'normal', ]; $orderInfo['platform'] = request()->header('platform', 'H5'); // 通过商品列表计算订单明细 list($orderItem, $calculatedGoodsList, $userCoupon) = self::computeGoods($orderInfo, $goodsList, $userId, $address->area_id, $userCouponId); $orderInfo['pay_amount'] = bcsub($orderInfo['order_amount'], $orderInfo['discount_fee'], 2); $orderInfo['pay_original_amount'] = $orderInfo['pay_amount']; $orderInfo['pay_remain_amount'] = $orderInfo['pay_amount']; // 创建订单 $order = self::createOrderWithTransaction($orderInfo, $orderItem, $calculatedGoodsList, $userCoupon, $address); return $order; } /** * 在事务中创建订单 * @param array $orderInfo 订单信息 * @param array $orderItem 订单商品列表 * @param array $goodsList 商品列表 * @param object $userCoupon 优惠券 * @param object $address 地址信息 * @return Order * @throws Exception */ protected static function createOrderWithTransaction($orderInfo, $orderItem, $goodsList, $userCoupon, $address) { $order = null; Db::startTrans(); try { // 创建订单 $order = Order::create($orderInfo, true); // 为每个订单商品添加订单ID和订单号 foreach ($orderItem as &$item) { $item['order_id'] = $order->id; $item['order_sn'] = $order->order_sn; // 移除临时字段 unset($item['category_id'], $item['brand_id']); } unset($item); // 创建订单地址信息 $orderAddressData = [ 'order_id' => $order->id, 'user_id' => $orderInfo['user_id'], 'consignee' => $address->receiver, 'mobile' => $address->mobile, 'province_name' => $address->province->name ?? '', 'city_name' => $address->city->name ?? '', 'district_name' => $address->area->name ?? '', 'address' => $address->address, 'province_id' => $address->province_id, 'city_id' => $address->city_id, 'district_id' => $address->area_id, ]; OrderAddress::create($orderAddressData); // 减库存 foreach ($goodsList as $index => $item) { if ($item->sku) { $item->sku->setDec('stocks', $item->nums); } $item->goods->setDec("stocks", $item->nums); } // 计算单个商品折扣后的价格 (基于新字段名) $saleamount = bcsub($order['amount'], $order['express_fee'], 2); $saleratio = $order['goods_price'] > 0 ? bcdiv($saleamount, $order['goods_price'], 10) : 1; $saleremains = $saleamount; foreach ($orderItem as $index => &$item) { if (!isset($orderItem[$index + 1])) { $saleprice = $saleremains; } else { $saleprice = $order['discount_fee'] == 0 ? bcmul($item['goods_original_price'], $item['nums'], 2) : bcmul(bcmul($item['goods_original_price'], $item['nums'], 2), $saleratio, 2); } $saleremains = bcsub($saleremains, $saleprice, 2); $item['goods_price'] = $saleprice; } unset($item); // 批量创建订单商品数据 if (!empty($orderItem)) { (new OrderGoods())->saveAll($orderItem); } // 修改地址使用次数 if ($address) { $address->setInc('used_nums'); } // 优惠券已使用 if (!empty($userCoupon)) { $userCoupon->save(['is_used' => 2]); } // 提交事务 Db::commit(); } catch (Exception $e) { Db::rollback(); throw new Exception($e->getMessage()); } // 记录操作 OrderActionService::recordUserAction( $orderInfo['order_sn'], OrderActionEnum::ACTION_CREATE, $orderInfo['user_id'], '创建订单', $orderInfo['user_id'] ); // 订单应付金额为0时直接结算 if ($order['amount'] == 0) { // Order::settle($order->order_sn, 0); // $order = Order::get($order->id); return $order; } return $order; } /** * 验证商品规格参数 * @param array $goods_list 商品列表 * @throws Exception */ public static function validateGoodsList($goods_list) { if (empty($goods_list) || !is_array($goods_list)) { throw new Exception("商品列表不能为空"); } foreach ($goods_list as $item) { if (!isset($item['goods_id']) || !is_numeric($item['goods_id']) || $item['goods_id'] <= 0) { throw new Exception("商品ID无效"); } if (!isset($item['nums']) || !is_numeric($item['nums']) || $item['nums'] <= 0) { throw new Exception("商品数量必须大于0"); } if (isset($item['goods_sku_id']) && !is_numeric($item['goods_sku_id'])) { throw new Exception("商品规格ID无效"); } } } /** * 统一的订单计算方法(用于预览订单) * @param array $goods_list 标准化的商品列表 * @param int $user_id 用户ID * @param int $area_id 地区ID * @param int $user_coupon_id 优惠券ID * @return array * @throws Exception */ public static function calculateOrder($goodsList, $userId, $areaId = 0, $userCouponId = 0) { if (empty($goodsList)) { throw new Exception("商品列表不能为空"); } // 验证商品列表格式 self::validateGoodsList($goodsList); // 订单基础信息(用于计算,不包含订单号) $orderInfo = [ '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, // 运费 ]; // 计算商品明细 list($orderItem, $calculatedGoodsList, $userCoupon) = self::computeGoods($orderInfo, $goodsList, $userId, $areaId, $userCouponId); return [ 'orderItem' => $orderItem, 'goodsList' => $calculatedGoodsList, 'orderInfo' => $orderInfo, 'userCoupon' => $userCoupon ]; } /** * 订单列表 * * @param $param * @return \think\Paginator */ public static function getOrderList($userId = 0, $param =[],$status = [],$supplierId = 0) { $pageSize = 10; if (!empty($param['pageSize'])) { $pageSize = $param['pageSize']; } return Order::with(['orderGoods']) ->where(function ($query) use ($param,$userId,$status) { if (!empty($userId)) { $query->where('user_id', $userId); } if (!empty($status)) { $query->whereIn('order_status', $status ); } if (isset($param['keywords']) && $param['keywords'] != '') { $query->where('order_sn', 'in', function ($query) use ($param) { return $query->name('shop_order_goods')->where('order_sn|goods_title', 'like', '%' . $param['q'] . '%')->field('order_sn'); }); } if (!empty($supplierId)) { $query->where('order_sn', 'in', function ($query) use ($supplierId) { return $query->name('shop_order_goods')->where('supplier_id', $supplierId)->field('order_sn'); }); } }) ->order('createtime desc') ->paginate($pageSize, false, ['query' => request()->get()]); } /** * * @ 订单信息 * @param $orderId * @param $userId * @return array|false|\PDOStatement|string|Model */ public static function getDetail($orderId, $userId) { return Order::with(['orderGoods']) ->where('id', $orderId) ->where('user_id', $userId) ->find(); } public static function getDetailByOrderSn($orderSn) { return Order::with(['orderGoods']) ->where('order_sn', $orderSn) ->find(); } // 查询地址信息 public static function getAddressInfo($orderId) { return OrderAddress::where('order_id', $orderId)->find(); } /** * 判断订单是否失效 * @param $order_sn * @return bool */ public static function isExpired($orderSn) { $orderInfo = self::getByOrderSn($orderSn); //订单过期 if (!$orderInfo['orderstate'] && !$orderInfo['paystate'] && time() > $orderInfo['expiretime']) { // 启动事务 Db::startTrans(); try { $orderInfo->save(['orderstate' => 2]); //库存恢复 OrderGoods::setGoodsStocksInc($orderInfo->order_sn); //恢复优惠券 UserCoupon::resetUserCoupon($orderInfo->user_coupon_id, $orderInfo->order_sn); // 提交事务 Db::commit(); } catch (\Exception $e) { // 回滚事务 Db::rollback(); } return true; } return false; } public static function getByOrderSn($orderSn) { return Order::where('order_sn', $orderSn)->find(); } public static function getByOrderId($orderId) { return Order::where('id', $orderId)->find(); } // 获取状态订单统计 public static function getOrderStatusCount($userId = 0) { $info = []; $info['unpay'] = Order::where('user_id', $userId)->where('order_status',OrderEnum::STATUS_CREATE)->count(); $info['unsend'] = Order::where('user_id', $userId)->where('order_status',OrderEnum::STATUS_PAY)->count(); $info['unrec'] = Order::where('user_id', $userId)->where('order_status',OrderEnum::STATUS_SHIP)->count(); $info['uneva'] = Order::where('user_id', $userId)->where('order_status',OrderEnum::STATUS_CONFIRM)->count(); $info['inspect'] = Order::where('user_id', $userId) ->whereIn('order_status',[ OrderEnum::STATUS_INSPECTION, OrderEnum::STATUS_INSPECTION_PASS, OrderEnum::STATUS_INSPECTION_FAIL]) ->count(); return $info; } // 更新订单状态 public static function updateOrderStatus($orderId = 0, $userId = 0, $status = 0) { $order = self::getDetail($orderId, $userId); if (!$order) { throw new BusinessException('订单不存在!'); } // 验证状态 if (!OrderEnum::isValidOrderStatus($status)) { throw new BusinessException('状态不合法!'); } // 要处理每个状态对应的时间字段在枚举类中 $timeField = OrderEnum::STATUS_TIME_MAP[$status]; $updateData = [ 'order_status' => $status, $timeField => time() ]; Order::where('id', $orderId)->update($updateData); return $order; } /** * 获取供应商订单列表 - 关联查询方式 * @param int $supplierId 供应商ID * @param int $userId 用户ID(可选) * @param array $param 查询参数 * @param array $status 订单状态筛选 * @return \think\Paginator */ public static function getSupplierOrderList($supplierId, $userId = 0, $param = [], $status = []) { $pageSize = $param['page_size'] ?? 10; return Order::alias('o') ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner') ->with(['orderGoods' => function($query) use ($supplierId) { $query->where('supplier_id', $supplierId); }]) ->where('og.supplier_id', $supplierId) ->where(function ($query) use ($param, $userId, $status) { if (!empty($userId)) { $query->where('o.user_id', $userId); } if (!empty($status)) { $query->whereIn('o.order_status', $status); } if (isset($param['keywords']) && $param['keywords'] != '') { $query->where(function($subQuery) use ($param) { $subQuery->where('o.order_sn', 'like', '%' . $param['keywords'] . '%') ->whereOr('og.goods_title', 'like', '%' . $param['keywords'] . '%'); }); } }) ->field('o.*') ->group('o.id') ->order('o.createtime desc') ->paginate($pageSize, false, ['query' => request()->get()]); } /** * 获取供应商订单详情 - 只返回该供应商的商品 * @param string $orderSn 订单号 * @param int $supplierId 供应商ID * @return array|null */ public static function getSupplierOrderDetail($orderSn, $supplierId) { $order = Order::where('order_sn', $orderSn)->find(); if (!$order) { return null; } // 获取该供应商在此订单中的商品 $orderGoods = OrderGoods::where('order_sn', $orderSn) ->where('supplier_id', $supplierId) ->select(); $order->orderGoods = $orderGoods; return $order; } /** * 获取供应商订单统计 * @param int $supplierId 供应商ID * @param int $userId 用户ID(可选) * @return array */ public static function getSupplierOrderStatusCount($supplierId, $userId = 0) { $baseQuery = function($status) use ($supplierId, $userId) { $query = Order::alias('o') ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner') ->where('og.supplier_id', $supplierId) ->where('o.order_status', $status); if (!empty($userId)) { $query->where('o.user_id', $userId); } return $query->count('DISTINCT o.id'); }; return [ 'unpay' => $baseQuery(OrderEnum::STATUS_CREATE), // 待付款 'unsend' => $baseQuery(OrderEnum::STATUS_PAY), // 待发货 'unrec' => $baseQuery(OrderEnum::STATUS_SHIP), // 待收货 'uneva' => $baseQuery(OrderEnum::STATUS_CONFIRM), // 待评价 ]; } /** * 验证订单和订单商品是否存在 * @param int $orderId 订单ID * @param int $orderGoodsId 订单商品ID * @return array|false 返回订单和订单商品信息,不存在返回false */ public static function validateOrderAndOrderGoods($orderId, $orderGoodsId) { // 查询订单 $order = Order::where('id', $orderId)->find(); if (!$order) { return false; } // 查询订单商品 $orderGoods = OrderGoods::where('id', $orderGoodsId) ->where('order_id', $orderId) ->find(); if (!$orderGoods) { return false; } return [ 'order' => $order, 'order_goods' => $orderGoods ]; } /** * 更新订单商品的验收状态 * @param int $orderGoodsId 订单商品ID * @param int $inspectStatus 验收状态 0:待验收 1:验收通过 2:验收不通过 * @return bool */ public static function updateOrderGoodsInspectStatus($orderGoodsId, $inspectStatus) { return OrderGoods::where('id', $orderGoodsId)->update([ 'inspect_status' => $inspectStatus, 'inspect_time' => time() ]); } /** * 检查订单中所有商品的验收状态 * @param int $orderId 订单ID * @return array 返回验收状态统计 */ public static function checkOrderInspectStatus($orderId) { $orderGoods = OrderGoods::where('order_id', $orderId)->select(); $statusCount = [ 'total' => count($orderGoods), // 总商品数 'pending' => 0, // 待验收 'passed' => 0, // 验收通过 'failed' => 0 // 验收不通过 ]; foreach ($orderGoods as $goods) { switch ($goods['inspect_status']) { case 0: $statusCount['pending']++; break; case 1: $statusCount['passed']++; break; case 2: $statusCount['failed']++; break; } } return $statusCount; } /** * 根据验收状态决定是否更新订单状态 * @param int $orderId 订单ID * @param int $userId 用户ID * @return bool */ public static function updateOrderStatusByInspectResult($orderId, $userId = 0) { $inspectStatus = self::checkOrderInspectStatus($orderId); // 如果所有商品都验收完成(没有待验收的商品) if ($inspectStatus['pending'] == 0) { // 如果所有商品都验收通过 if ($inspectStatus['failed'] == 0 && $inspectStatus['passed'] > 0) { // 更新订单状态为验收通过 return self::updateOrderStatus($orderId, $userId, OrderEnum::STATUS_INSPECTION_PASS); } // 如果所有商品都验收不通过 elseif ($inspectStatus['failed'] > 0 && $inspectStatus['passed'] == 0) { // 更新订单状态为验收失败 return self::updateOrderStatus($orderId, $userId, OrderEnum::STATUS_INSPECTION_FAIL); } // 如果部分商品验收通过,部分不通过 elseif ($inspectStatus['failed'] > 0 && $inspectStatus['passed'] > 0) { // 混合状态,由业务人员手动处理,不自动更新订单状态 return true; } } return true; } /** * 更新订单商品的发货状态 * @param int $orderGoodsId 订单商品ID * @param string $expressName 快递公司 * @param string $expressNo 快递单号 * @param array $expressImage 快递图片 * @return bool */ public static function updateOrderGoodsDeliveryStatus($orderGoodsId, $expressName, $expressNo, $expressImage = []) { $updateData = [ 'express_name' => $expressName, 'express_no' => $expressNo, 'express_image' => is_array($expressImage) ? json_encode($expressImage) : $expressImage, 'delivery_status' => 1, // 已发货 'updatetime' => time() ]; return OrderGoods::where('id', $orderGoodsId)->update($updateData); } /** * 检查订单中所有商品的发货状态 * @param int $orderId 订单ID * @return array 返回发货状态统计 */ public static function checkOrderDeliveryStatus($orderId) { $orderGoods = OrderGoods::where('order_id', $orderId)->select(); $statusCount = [ 'total' => count($orderGoods), // 总商品数 'pending' => 0, // 待发货 'delivered' => 0, // 已发货 ]; foreach ($orderGoods as $goods) { if ($goods['delivery_status'] == 1) { $statusCount['delivered']++; } else { $statusCount['pending']++; } } return $statusCount; } /** * 根据发货状态决定是否更新订单状态 * @param int $orderId 订单ID * @param int $userId 用户ID * @return bool */ public static function updateOrderStatusByDeliveryResult($orderId, $userId = 0) { $deliveryStatus = self::checkOrderDeliveryStatus($orderId); // 如果所有商品都已发货(没有待发货的商品) if ($deliveryStatus['pending'] == 0 && $deliveryStatus['delivered'] > 0) { // 更新订单状态为已发货 return self::updateOrderStatus($orderId, $userId, OrderEnum::STATUS_SHIP); } return true; } /** * 验证订单商品是否可以发货 * @param int $orderId 订单ID * @param int $orderGoodsId 订单商品ID * @return array|false 返回订单和订单商品信息,验证失败返回false */ public static function validateOrderGoodsForDelivery($orderId, $orderGoodsId) { // 验证订单和订单商品是否存在 $orderData = self::validateOrderAndOrderGoods($orderId, $orderGoodsId); if (!$orderData) { return false; } $order = $orderData['order']; $orderGoods = $orderData['order_goods']; // 检查订单状态是否允许发货(验收通过状态) if ($order['order_status'] != OrderEnum::STATUS_INSPECTION_PASS) { return false; } // 检查该订单商品是否已经发货 if ($orderGoods['delivery_status'] == 1) { return false; } return $orderData; } }