|
|
<?php
namespace api\logic;
use backend\modules\goods\models\ars\Goods; use backend\modules\goods\models\ars\GoodsSku; use backend\modules\shop\models\ars\Address; use backend\modules\shop\models\ars\Cart; use backend\modules\shop\models\ars\Order; use backend\modules\shop\models\ars\OrderGoods; use backend\modules\shop\models\ars\TakingSite; use yii\base\Component; use Throwable; use Yii; use yii\db\ActiveRecord; use yii\base\Exception; use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; use yii\web\ServerErrorHttpException;
/** * @author iron * @email weiriron@gmail.com * @package api\logic */ class OrderLogic extends Component { public $viewAction = 'view'; /*订单操作类型*/ const TYPE_CONFIRM = 1; const TYPE_CANCEL = 2; const TYPE_TAKE = 3; const TYPE_CHANGE_SHIPPING_TYPE = 4; const TYPE_CHANGE_ADDRESS = 5; const TYPE_CHANGE_TAKING_SITE = 6; /*仓库类型*/ const TYPE_ADD_STOCK = 1; const TYPE_SUB_STOCK = -1;
/** * @return Order * @throws BadRequestHttpException * @throws Exception * 创建订单 */ public function create() { //立即购物需传参数
$goodsId = Yii::$app->request->getBodyParam('goodsId');/*int 商品id*/ $count = Yii::$app->request->getBodyParam('count');/*int 数量*/ $skuId = Yii::$app->request->getBodyParam('skuId');/*int 商品sku id*/ //购物车提交订单需传参数
$cartIds = Yii::$app->request->getBodyParam('cartIds');/*array 购物车商品id*/
if ((empty($cartIds) && empty($goodsId)) || ($goodsId && empty($count))) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } $tra = Yii::$app->db->beginTransaction(); try { $order = new Order(); $order->user_id = Yii::$app->user->getId(); $order->type = Order::TYPE_SHOPPING; $order->order_sn = Helper::timeRandomNum(3, 'W'); if (!$order->save()) { throw new ServerErrorHttpException('服务器创建订单失败'); } if ($goodsId && $count) { $this->addGoods($order->id, $goodsId, $skuId, $count);/*添加订单商品*/ } else { $this->addGoodsByCart($cartIds, $order->id);/*通过购物车添加订单商品*/ } $this->getShippingType($order); $this->saveGoodsInfo($order);/*保存订单商品信息*/ if (!$order->save()) { throw new Exception('服务器创建订单失败'); } $tra->commit(); Helper::createdResponse($order, $this->viewAction); return $order; } catch (Exception $e) { $tra->rollBack(); throw $e; } }
/** * @return bool * @throws Exception * @throws Throwable * @throws yii\base\InvalidConfigException * 根据操作类型更新订单 */ public function update() { $data = Yii::$app->request->getBodyParams(); $type = Yii::$app->request->getBodyParam('type'); $order = $this->findOrder(); $tra = Yii::$app->db->beginTransaction(); try { switch ($type) { case self::TYPE_CONFIRM : $this->confirm($order, $data); break; case self::TYPE_CANCEL: $this->cancel($order); break; case self::TYPE_TAKE: $this->take($order); break; case self::TYPE_CHANGE_SHIPPING_TYPE: $this->switchShippingType($order, $data); break; case self::TYPE_CHANGE_ADDRESS: $this->changeAddress($order, $data); break; case self::TYPE_CHANGE_TAKING_SITE: $this->changeTakingSite($order, $data); break; default: throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if (!$order->save()) { throw new ServerErrorHttpException('服务器更新订单失败'); } $tra->commit(); return true; } catch (Exception $e) { $tra->rollBack(); throw $e; } }
/*----------------------------------------- 华丽的分割线 -----------------------------------------*/ /** * @param $order * @return int * @throws BadRequestHttpException * @throws NotFoundHttpException */ private function getShippingType($order) { $allOrderGoods = $this->findOrderGoods($order->id); $goods = $this->findGoods($allOrderGoods[0]->goods_id); if ($goods->is_express) { return Order::SHIPPING_TYPE_EXPRESS; } if ($goods->is_taking) { return Order::SHIPPING_TYPE_PICKED_UP; } throw new BadRequestHttpException('配送方式异常'); }
/** * @param Order $order * @param array $data * @throws BadRequestHttpException * @throws NotFoundHttpException * 添加地址到订单 */ private function changeAddress($order, $data) { if (!isset($data['address_id'])) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) { throw new BadRequestHttpException('配送方式异常'); } if ($order->status !== Order::STATUS_UNCONFIRMED) { throw new BadRequestHttpException('该状态下不允许更改配送方式'); } $address = Address::findOne(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()]); if (!$address) { throw new NotFoundHttpException('收货地址未找到'); } $order->consignee = $address->consignee; $order->phone = $address->phone; $order->city = $address->city; $order->area = $address->area; $order->province = $address->province; $order->address = $address->address; }
/** * @param Order $order * @param array $data * @throws BadRequestHttpException * @throws NotFoundHttpException * 修改自提点 */ private function changeTakingSite($order, $data) { if (!isset($data['taking_site_id']) || empty($data['taking_site_id'])) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if ($order->shipping_type !== Order::SHIPPING_TYPE_PICKED_UP) { throw new BadRequestHttpException('配送方式异常'); } if ($order->status !== Order::STATUS_UNCONFIRMED) { throw new BadRequestHttpException('该状态下不允许更改提货地址方式'); } $site = TakingSite::findOne($data['taking_site_id']); if (!$site) { throw new NotFoundHttpException('自提点未找到'); } $order->taking_site = $data['taking_site_id']; }
/** * @param Order $order * @param array $data * @throws BadRequestHttpException * 切换配送方式 */ private function switchShippingType($order, $data) { if (!isset($data['shipping_type']) || !in_array($data['shipping_type'], [Order::SHIPPING_TYPE_PICKED_UP, Order::SHIPPING_TYPE_EXPRESS])) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if ($order->status !== Order::STATUS_UNCONFIRMED) { throw new BadRequestHttpException('该状态下不允许更改配送方式'); }
$order->shipping_type = $data['shipping_type']; }
/** * @param Order $order * @param array $data * @throws BadRequestHttpException * @throws NotFoundHttpException * @throws ServerErrorHttpException * @throws Throwable * @throws yii\db\StaleObjectException * 确定订单 */ private function confirm($order, $data) { if ($order->status !== Order::STATUS_UNCONFIRMED) { throw new BadRequestHttpException('订单状态异常'); } if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) { if ($data['consignee'] ?? false || $data['phone'] ?? false) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } $order->consignee = $data['consignee']; $order->phone = $data['phone']; } if (empty($order->consignee)) { throw new BadRequestHttpException('需先填写收件人信息'); } if (isset($data['remarks'])) { $order->remarks = $data['remarks']; } Helper::delCarts($this->getCartsIds($order)); //删除购物车对应商品
$order->status = Order::STATUS_NONPAYMENT; $this->updateStock($order, self::TYPE_SUB_STOCK); }
/** * @param $order * @return array * 获取订单商品对应购物车商品id */ private function getCartsIds($order) { $allGoods = $this->findOrderGoods($order->id); $ids = []; foreach ($allGoods as $goods) { $cart = Cart::findOne(['goods_id' => $goods->goods_id, 'user_id' => Yii::$app->user->getId()]); if ($cart) { $ids[] = $cart->id; } } return $ids; }
/** * @param Order $order * @throws BadRequestHttpException * @throws NotFoundHttpException * @throws ServerErrorHttpException * 取消订单 */ private function cancel($order) { if ($order->status !== Order::STATUS_NONPAYMENT) { throw new BadRequestHttpException('该状态下无法取消订单'); } $order->status = Order::STATUS_CANCEL; $this->updateStock($order, self::TYPE_ADD_STOCK);/*更新库存*/ }
/** * @param Order $order * @throws BadRequestHttpException * 确认收货 */ private function take($order) { if ($order->status !== Order::STATUS_SHIPMENT_ALL) { throw new BadRequestHttpException('该状态下无法确认收货'); } $order->status = Order::STATUS_FINISH; }
/** * @param $id * @param $type * @throws BadRequestHttpException * @throws NotFoundHttpException * @throws ServerErrorHttpException * 更新库存 */ private function updateStock($id, $type) { $allOrderGoods = $this->findOrderGoods($id); foreach ($allOrderGoods as $orderGoods) { /*检查库存*/ if (Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id)) { return; } if ($orderGoods->sku_id) { $goods = GoodsSku::findOne($orderGoods->sku_id); } else { $goods = $this->findGoods($orderGoods->goods_id); } if ($type) { $count = $orderGoods->goods_count; } else { $count = -$orderGoods->goods_count; } if (!$goods->updateCounters(['stock' => $count])) { throw new ServerErrorHttpException('更新库存失败'); } } }
/** * @param array $cartIds 购物车商品id * @param int $id 订单id * @throws Exception * @throws NotFoundHttpException * 通过购物车添加商品 */ private function addGoodsByCart($cartIds, $id) { foreach ($cartIds as $cartId) { $cart = Cart::findOne($cartId); if (!$cart) { throw new NotFoundHttpException('购物车未找到'); } $this->addGoods($id, $cart->goods_id, $cart->sku_id, $cart->goods_count); } }
/** * @param Order $order * 保存商品总价格和总数量信息到 */ private function saveGoodsInfo($order) { $orderGoods = $this->findOrderGoods($order->id); foreach ($orderGoods as $goods) { $order->goods_amount += $goods->price; $order->goods_count += $goods->goods_count; } }
/** * @param $id * @param int $goodsId * @param $skuId * @param $count * @throws Exception * @throws NotFoundHttpException * 添加商品到订单 */ private function addGoods($id, $goodsId, $skuId, $count) { $goods = $this->findGoods($goodsId); $orderGoods = new OrderGoods(); $orderGoods->order_id = $id; $orderGoods->goods_id = $goodsId; $orderGoods->sku_id = $skuId ?: 0; $orderGoods->sku_value = Helper::skuValue($skuId); $orderGoods->weight = $skuId ? $this->skuWeight($skuId) : $goods->weight; $orderGoods->goods_count = $count; $orderGoods->goods_img = $goods->image; $orderGoods->goods_name = $goods->name; $orderGoods->price = Helper::goodsPrice($goodsId, $skuId); Helper::checkStock($goodsId, $count, $skuId); /*检查库存*/ if (!$orderGoods->save()) { throw new Exception('服务器添加订单商品失败'); } }
/** * @param $skuId * @return int * @throws NotFoundHttpException * 获取sku重量 */ private function skuWeight($skuId) { $sku = GoodsSku::findOne($skuId); if (!$sku) { throw new NotFoundHttpException('sku未找到'); } return $sku->weight; }
/** * @return array|Order|null * 根据id获取订单 */ private function findOrder() { $id = Yii::$app->request->getQueryParam('id'); return Order::find() ->where(['id' => $id]) ->andWhere(['user_id' => Yii::$app->user->getId()]) ->one(); }
/** * @param $id * @return array|ActiveRecord[]|OrderGoods[] * 根据订单 id 获取所有订单商品 */ private function findOrderGoods($id) { return OrderGoods::find() ->where(['order_id' => $id]) ->all(); }
/** * @param $goodsId * @return array|Goods|null * @throws NotFoundHttpException */ private function findGoods($goodsId) { $goods = Goods::find() ->where(['id' => $goodsId]) ->andWhere(['is_delete' => Goods::IS_DELETE_NO]) ->andWhere(['is_sale' => Goods::IS_SALE_YES]) ->one(); if (!$goods) { throw new NotFoundHttpException("商品[{$goodsId}]未找到"); } return $goods; }
}
|