You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
394 lines
12 KiB
394 lines
12 KiB
<?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;
|
|
if (!$order->save()) {
|
|
throw new ServerErrorHttpException('服务器创建订单失败');
|
|
}
|
|
if ($goodsId && $count) {
|
|
$this->addGoods($order->id, $goodsId, $skuId, $count);/*添加订单商品*/
|
|
} else {
|
|
$this->addGoodsByCart($cartIds, $order->id);/*通过购物车添加订单商品*/
|
|
}
|
|
Helper::checkStock($goodsId, $count, $skuId); /*检查库存*/
|
|
$this->saveGoodsInfo($order);/*保存订单商品信息*/
|
|
$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;
|
|
}
|
|
if (!$order->save()) {
|
|
throw new ServerErrorHttpException('服务器更新订单失败');
|
|
}
|
|
$tra->commit();
|
|
return true;
|
|
} catch (Exception $e) {
|
|
$tra->rollBack();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------- 华丽的分割线 -----------------------------------------*/
|
|
/**
|
|
* @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('配送方式异常');
|
|
}
|
|
$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('配送方式异常');
|
|
}
|
|
$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'])) {
|
|
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) {
|
|
/*检查库存*/
|
|
Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id);
|
|
if ($orderGoods->sku_id) {
|
|
$goods = GoodsSku::findOne($orderGoods->sku_id);
|
|
} else {
|
|
$goods = Goods::findOne($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
|
|
* @throws Exception
|
|
* 保存商品总价格和总数量信息到
|
|
*/
|
|
private function saveGoodsInfo($order)
|
|
{
|
|
$orderGoods = $this->findOrderGoods($order->id);
|
|
foreach ($orderGoods as $goods) {
|
|
$order->goods_amount += $goods->price;
|
|
$order->goods_count += $goods->goods_count;
|
|
}
|
|
if (!$order->save()) {
|
|
throw new Exception('服务器创建订单失败');
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $id
|
|
* @param int $goodsId
|
|
* @param $skuId
|
|
* @param $count
|
|
* @throws Exception
|
|
* @throws NotFoundHttpException
|
|
* 添加商品到订单
|
|
*/
|
|
private function addGoods($id, $goodsId, $skuId, $count)
|
|
{
|
|
$goods = Goods::findOne($goodsId);
|
|
$orderGoods = new OrderGoods();
|
|
$orderGoods->order_id = $id;
|
|
$orderGoods->goods_id = $goodsId;
|
|
$orderGoods->sku_id = $skuId ?: 0;
|
|
$orderGoods->sku_value = Helper::skuValue($skuId);
|
|
$orderGoods->goods_count = $count;
|
|
$orderGoods->goods_img = $goods->image;
|
|
$orderGoods->goods_name = $goods->name;
|
|
$orderGoods->price = Helper::goodsPrice($goodsId, $skuId);
|
|
if (!$orderGoods->save()) {
|
|
throw new Exception('服务器添加订单商品失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @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();
|
|
}
|
|
|
|
|
|
}
|