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.
 
 
 

354 lines
11 KiB

<?php
namespace api\logic;
use antgoods\goods\models\ars\Goods;
use antgoods\goods\models\ars\GoodsSku;
use common\models\ars\Address;
use common\models\ars\Cart;
use common\models\ars\Order;
use common\models\ars\OrderGoods;
use common\models\ars\TakingSite;
use yii\base\Component;
use Yii;
use yii\db\ActiveRecord;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* Class CartLogic
* @package api\logic
*/
class OrderLogic extends Component
{
/*创建途径类型*/
const TYPE_ADD_GOODS_PURCHASE = 1;
const TYPE_ADD_GOODS_CART = 2;
/*订单操作类型*/
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;
/**
* @param $data
* @return bool|\Exception|\yii\base\Exception
*/
public function update($data)
{
$type = Yii::$app->request->getQueryParam('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->updateShippingType($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 (\yii\base\Exception $e) {
$tra->rollBack();
return $e;
}
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
private function changeAddress($order, $data)
{
if (!isset($data['address_id'])) {
throw new BadRequestHttpException('参数缺少或无效');
}
if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) {
throw new BadRequestHttpException('配送方式异常');
}
$address = Address::find()
->where(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()])
->one();
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('参数缺少或无效');
}
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 updateShippingType($order, $data)
{
if (!isset($data['shipping_type'])) {
throw new BadRequestHttpException('参数缺少或无效');
}
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
*/
private function confirm($order, $data)
{
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('订单状态异常');
}
if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) {
if (!isset($data['consignee']) || !isset($data['phone'])
|| empty($data['consignee']) || empty($data['phone'])) {
throw new BadRequestHttpException('(联系人)参数无效');
}
$order->consignee = $data['consignee'];
$order->phone = $data['phone'];
}
if (empty($order->consignee)) {
throw new BadRequestHttpException('需先填写收件人信息');
}
if (isset($data['remarks'])) {
$order->remarks = $data['remarks'];
}
$order->status = Order::STATUS_NONPAYMENT;
$this->updateStock($order, self::TYPE_SUB_STOCK);
}
/**
* @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 $originId
* @param $count
* @param $skuId
* @return bool
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* 创建订单并添加商品
*/
public function addGoods($originId, $count, $skuId)
{
$type = Yii::$app->request->getQueryParam('type');
if (empty($type) || ($type == self::TYPE_ADD_GOODS_CART && empty($originId)) ||
($type == self::TYPE_ADD_GOODS_PURCHASE && (empty($count) || empty($originId)))) {
throw new BadRequestHttpException('参数缺少或无效');
}
if ($type == self::TYPE_ADD_GOODS_PURCHASE) {
$goodsId = $originId;
} else {
$cart = Cart::findOne($originId);
if (!$cart) {
throw new NotFoundHttpException('购物车未找到');
}
$goodsId = $cart->goods_id;
$skuId = $cart->sku_id;
$count = $cart->goods_count;
}
/*检查库存*/
Helper::checkStock($goodsId, $count, $skuId);
$tra = Yii::$app->db->beginTransaction();
try {
$order = new Order();
// $order->user_id = Yii::$app->user->getId();
$order->user_id = 1;
$order->type = Order::TYPE_SHOPPING;
if (!$order->save()) {
throw new ServerErrorHttpException('服务器创建订单失败');
}
$this->createOrderGoods($order->id, $goodsId, $skuId, $count);/*创建订单商品*/
$this->saveGoodsInfo($order);/*保存订单商品信息*/
$tra->commit();
return true;
} catch (\Exception $e) {
$tra->rollBack();
throw $e;
}
}
/**
* @param Order $order
* @throws ServerErrorHttpException
*/
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 ServerErrorHttpException('服务器创建订单失败');
}
}
/**
* @param int $id
* @param int $goodsId
* @param int $skuId
* @param int $count
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 创建订单商品
*/
private function createOrderGoods($id, $goodsId, $skuId, $count)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$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::countPrice($goodsId, $skuId);
if (!$orderGoods->save()) {
throw new ServerErrorHttpException('服务器添加订单商品失败');
}
}
/**
* @return array|Order|null
* 获取订单
*/
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[]
*/
private function findOrderGoods($id)
{
return OrderGoods::find()
->where(['order_id' => $id])
->all();
}
}